How to create a GreatAI service#
The core value of great-ai lies in its 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:
You can simply decorate (wrap) this function using the @GreatAI.create factory.
from great_ai import GreatAI
@GreatAI.create
def greeter(your_name):
return f'Hi {your_name}!'
Why not simply use @GreatAI?
The purpose of @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#
Even though it's not required by GreatAI, type annotating your codebase 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.
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.
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. In these cases, you can simply make your function async without any other changes.
from great_ai import GreatAI
from asyncio import sleep
@GreatAI.create
async def async_greeter(your_name: str) -> str:
await sleep(2) # simulate IO-bound operation
return f'Hi {your_name}!'
With decorators#
GreatAI can decorate already decorated functions. The only restriction is that @GreatAI.create must come last. There are two built-in decorators that you can use to customise your function but you can you use any third-party decorator as well.
Using @use_model#
If you have previously saved a model with save_model, you can inject it into your function by calling @use_model.
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'
- By default, the parameter named
modelwill be replaced by the loaded model. This behaviour can be customised by setting themodel_kwarg_name. This way, even multiple models can be injected into a single function.
Important
You must call @use_model before @GreatAI.create. Note, that decorators are applied starting from the bottom-most one. Feel free to use @use_model in other places of the codebase, it works equally well outside of GreatAI services.
Using @parameter#
If you wish to turn off 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 are automatically decorated with @parameter when @GreatAI.create is called.
from great_ai import GreatAI, use_model
@GreatAI.create
@parameter('your_name', disable_logging=True)
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. Note, that decorators are applied starting from the bottom-most one. Feel free to use @parameter in other places of the codebase, 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.
from great_ai import save_model, GreatAI, parameter, use_model, log_metric
save_model(4, 'secret-number') #(1)
@GreatAI.create
@parameter('positive_number', validate=lambda n: n > 0, disable_logging=True)
@use_model('secret-number', version='latest', model_kwarg_name='secret')
def add_number(positive_number: int, secret: int) -> int:
log_metric(
'log directly into the returned Trace',
positive_number * 2
)
return positive_number + secret
assert add_number(1).output == 5
- Refer to the configuration page for specifying where to store your models.