diff --git a/.vscode/settings.json b/.vscode/settings.json
index 480d3d9..99a8cc7 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -21,6 +21,7 @@
"initialising",
"inplace",
"ipynb",
+ "langcodes",
"lemmatize",
"levelname",
"levelno",
@@ -68,12 +69,11 @@
},
"notebook.output.textLineLimit": 400,
"python.defaultInterpreterPath": ".env/bin/python",
- "python.testing.pytestArgs": [
- "tests"
- ],
+ "python.testing.pytestArgs": ["tests"],
+ "editor.rulers": [88],
"python.linting.flake8Enabled": false,
"python.linting.pylintEnabled": false,
"python.linting.mypyEnabled": true,
"python.testing.unittestEnabled": false,
- "python.testing.pytestEnabled": true,
+ "python.testing.pytestEnabled": true
}
diff --git a/README.md b/README.md
index 6f4a8b0..e273b6e 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,10 @@
> GreatAI helps you easily transform your prototype AI code into production-ready software.
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
[](https://github.com/schmelczer/great-ai/actions/workflows/test.yml)
-[](https://sonar.schmelczer.com/dashboard?id=great-ai)
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
[](https://pepy.tech/project/great-ai)
diff --git a/docs/how-to-guides/index.md b/docs/how-to-guides/call-remote.md
similarity index 100%
rename from docs/how-to-guides/index.md
rename to docs/how-to-guides/call-remote.md
diff --git a/docs/how-to-guides/create-service.md b/docs/how-to-guides/create-service.md
new file mode 100644
index 0000000..104975d
--- /dev/null
+++ b/docs/how-to-guides/create-service.md
@@ -0,0 +1,118 @@
+# How to instantiate a GreatAI service
+
+The core value of the `great-ai` library lies in its [great_ai.deploy.GreatAI][] class. In order to take advantage of it, you need to create an instance wrapping your code.
+
+Let's say that you have the following greeter function:
+
+```python title="greeter.py"
+def my_greeter_function(your_name):
+ return f'Hi {your_name}!'
+```
+
+You can simply decorate (wrap) this function with the `GreatAI.create` factory.
+
+```python title="greeter.py"
+from great_ai import GreatAI
+
+@GreatAI.create
+def greeter(your_name):
+ return f'Hi {your_name}!'
+```
+
+??? info "Why not simply use `@GreatAI?`"
+ The purpose of the `GreatAI.create` is simply to provide you with type-checking through MyPy, Pylance, and similar libraries. However, the overloading support for `__new__` is lacking in MyPy, thus, a static factory method is used instead.
+
+## With types
+
+[Type annotating your codebase](https://realpython.com/python-type-checking/){ target=_blank } can save you from lots of trivial mistakes, that's why it's highly advised. Simply add the expected types to your function's signature.
+
+```python title="type_safe_greeter.py"
+from great_ai import GreatAI
+
+@GreatAI.create
+def type_safe_greeter(your_name: str) -> str:
+ return f'Hi {your_name}!'
+```
+
+This not only allows you to statically typecheck your code, but by default, GreatAI will check it during runtime as well using [typeguard](https://github.com/agronholm/typeguard){ target=_blank }.
+
+## With async
+
+Asynchronous code can result in immense performance gains in certain cases. For example, you might rely on a third-party service, do database access, or [call a remote GreatAI instance](/how-to-guides/call-remote). In these cases, you can simply make your function `async` without any other changes.
+
+```python title="async_greeter.py"
+from great_ai import GreatAI
+from asyncio import sleep
+
+@GreatAI.create
+async def async_greeter(your_name: str) -> str:
+ await sleep(2) # simulate IO-heavy operation
+ return f'Hi {your_name}!'
+```
+
+## With decorators
+
+GreatAI can decorate already decorated functions. The only restriction is that `@GreatAI.create` always have to come last. There are two built-in decorators that you can use to customise your function.
+
+### Using `use_model`
+
+If you have previously saved a model with `save_model`, you can inject it into your function by calling `use_model`.
+
+```python title="greeter_with_model.py"
+from great_ai import GreatAI, use_model
+
+@GreatAI.create
+@use_model('name_of_my_model', version='latest') #(1)
+def type_safe_greeter(your_name: str, model) -> str:
+ return f'Hi {your_name}!'
+
+assert type_safe_greeter('Andras').output == 'Hi Andras'
+```
+
+1. By default, the parameter named `model` will be replaced by the loaded model. This behaviour can be customised by setting the `model_kwarg_name`. This way, even multiple models can be injected into a single function.
+
+!!! important
+ You must call `@use_model` before `GreatAI.create`. Feel free to use `@use_model` in other places of the code base, it works equally well outside of GreatAI services.
+
+
+### Using `parameter`
+
+If you wish to turn of logging or specify custom validation for your parameters, you can use the `@parameter` decorator.
+
+!!! note
+ By default, all parameters that are not affected by an explicit `@parameter` or `@use_model` decorator, are automatically decorated with `@parameter` when `GreatAI.create` is called.
+
+```python "greeter_with_validation.py"
+from great_ai import GreatAI, use_model
+
+@GreatAI.create
+@use_model('name_of_my_model', version='latest')
+def type_safe_greeter(your_name: str, model) -> str:
+ return f'Hi {your_name}!'
+
+assert type_safe_greeter('Andras').output == 'Hi Andras'
+```
+
+!!! important
+ You must call `@parameter` before `GreatAI.create`. Feel free to use `@parameter` in other places of the code base, it works equally well outside of GreatAI services.
+
+
+## Complex example
+
+Refer to the following example summarising the options you have when instantiating a GreatAI service.
+
+```python title="complex.py"
+from great_ai import save_model, GreatAI, parameter, use_model
+
+save_model(4, 'secret-number') #(2)
+
+@GreatAI.create
+@parameter('positive_number', validator=lambda n: n > 0)
+@use_model('secret-number', version='latest', model_kwarg_name='secret')
+def add_number(positive_number: int, secret: int) -> int:
+ return positive_number + secret
+
+assert add_number(1).output == 5
+```
+
+2. Refer to [storing models](/how-to-guides/store-models) for specifying where to store your models.
diff --git a/docs/how-to-guides/store-models.md b/docs/how-to-guides/store-models.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/how-to-guides/using-service.md b/docs/how-to-guides/using-service.md
new file mode 100644
index 0000000..6ed65bb
--- /dev/null
+++ b/docs/how-to-guides/using-service.md
@@ -0,0 +1,14 @@
+# How to use a GreatAI service
+
+After [creating a GreatAI service](/how-to-guides/cerate-service) by wrapping your prediction function, it's time to do some prediction.
+
+Let's use the following example:
+
+```python "type_safe_greeter.py"
+from great_ai import GreatAI
+
+@GreatAI.create
+def type_safe_greeter(your_name: str) -> str:
+ return f'Hi {your_name}'
+```
+
diff --git a/docs/index.md b/docs/index.md
index d24e689..9db1204 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -3,13 +3,15 @@
-[](https://github.com/schmelczer/great-ai/actions/workflows/check.yml)
-[](https://sonar.schmelczer.com/dashboard?id=great-ai)
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
+[](https://sonar.scoutinscience.com/dashboard?id=great-ai)
+[](https://github.com/schmelczer/great-ai/actions/workflows/test.yml)
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
[](https://pepy.tech/project/great-ai)
-Applying AI is becoming increasingly easier but many case studies have shown that these applications are often deployed poorly. This may lead to suboptimal performance and to introducing [unintended biases](https://en.wikipedia.org/wiki/Weapons_of_Math_Destruction){ target=_blank }. To extend the list of available solutions, ==GreatAI helps you easily transform your prototype AI code into production-ready software.==
+Applying AI is becoming increasingly easier but many case studies have shown that these applications are often deployed poorly. This may lead to suboptimal performance and to introducing [unintended biases](https://en.wikipedia.org/wiki/Weapons_of_Math_Destruction){ target=_blank }. GreatAI helps fixing this by allowing you to ==easily transform your prototype AI code into production-ready software==.
??? quote "Case studies"
"There is a need to consider and adapt well established SE practices which have been ignored or had a very narrow focus in ML literature."
@@ -36,9 +38,10 @@ Applying AI is becoming increasingly easier but many case studies have shown tha
- [x] A simple, unified configuration interface
- [x] Fully-typed API for [Pylance](https://github.com/microsoft/pylance-release){ target=_blank } and [MyPy](http://mypy-lang.org){ target=_blank } support
- [x] Auto-reload for development
-- [x] Deployable Jupyter Notebooks
- [x] Docker support for deployment
-- [x] Dashboard for high-level overview and searching traces
+- [x] Deployable Jupyter Notebooks
+- [x] Dashboard for high-level overview and analysing traces
+- [ ] Support for direct file input
## Hello world
@@ -59,7 +62,7 @@ def hello_world(name: str) -> str: #(2)
2. it gets a `process_batch` method for supporting parallel execution,
3. and it can be deployed using the `great-ai` command-line tool.
-2. [Typing functions](https://docs.python.org/3/library/typing.html){ target=_blank } is recommended in general, however, not necessary for GreatAI to work.
+2. [Typing functions](https://docs.python.org/3/library/typing.html){ target=_blank } is recommended in general, however, not required for GreatAI to work.
??? note
In practice, `hello_world` could be an inference function of some AI/ML application. But it could also just wrap a black-box solution of some SaaS. Either ways, it is imperative to have continuos oversight of the services you provide and data you process.
@@ -94,7 +97,7 @@ GreatAI fits between the prototype and deployment phase of your (or your organis
There are other, existing solutions aiming to facilitate this phase. [Amazon SageMaker](https://aws.amazon.com/sagemaker){ target=_blank } and [Seldon Core](https://www.seldon.io/solutions/open-source-projects/core){ target=_blank } provide the most comprehensive suite of features. If you have the opportunity use those, do that because they're great.
-However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many [best-practices](https://se-ml.github.io){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort.
+However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many of the [SE4ML best-practices](https://se-ml.github.io){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort.