great-ai/docs/how-to-guides/create-service.md
2022-07-10 19:43:39 +02:00

4.5 KiB

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:

def my_greeter_function(your_name):
    return f'Hi {your_name}!'

You can simply decorate (wrap) this function with the GreatAI.create factory.

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{ 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.

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{ 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. 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-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.

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.

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.

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
  1. Refer to storing models for specifying where to store your models.