Global Functions
Functions in this page can be directly used in your code after
from cfdraw import *
is added.
register_plugin
This method is used to register a plugin.
register_plugin = PluginFactory.register
class PluginFactory:
@classmethod
def register(cls, identifier: str) -> Callable[[TPlugin], TPlugin]:
...
identifier
[ str, required ]
The identifier of the plugin.
- It should be unique across all registered plugins.
- It is recommended to keep it self-explanatory.
Returns
[ Callable[[TPlugin], TPlugin] ]
The decorator function to register the plugin.
However, to make your code more decoupled and extensible, it is preferred to use a 'chained' way to register the plugin, see Example below.
Example
from cfdraw import *
class GrayScalePlugin(IFieldsPlugin):
...
from cfdraw import *
from plugins import GrayScalePlugin
register_plugin("gray_scale")(GrayScalePlugin)
app = App()
cache_resource
This function is a decorator which helps you achieve the Singleton pattern. It is commonly used to decorate the initialization of resources that should be initialized only once, such as:
- AI models.
- Database connections.
- SDK / API / HTTP clients.
- ...
def cache_resource(fn: callable) -> callable:
...
fn
[ callable, required ]
The function to be cached.
Returns
[ callable ]
The decorated function, which can cache the result of fn
and return it directly if fn
is called again (with the same input arguments).
Examples
For AI models
- Initialization
from cfdraw import *
@cache_resource
def get_model():
import torch
from diffusers import StableDiffusionPipeline
from diffusers import StableDiffusionImg2ImgPipeline
tag = "runwayml/stable-diffusion-v1-5"
m = StableDiffusionPipeline.from_pretrained(tag, torch_dtype=torch.float16)
m.to("cuda")
return m
- Usage
class TextToImagePlugin(IFieldsPlugin):
@property
def settings(self) -> IPluginSettings:
...
async def process(self, data: ISocketRequest):
model = get_model()
# use model to generate images below
...
For HTTP client
- Initialization
from cfdraw import *
@cache_resource
def get_client():
SECRET_ID = os.getenv("SECRET_ID")
SECRET_KEY = os.getenv("SECRET_KEY")
client = YourHttpClient(SECRET_ID, SECRET_KEY)
return client
- Usage
class Plugin(IFieldsPlugin):
@property
def settings(self) -> IPluginSettings:
...
async def process(self, data: ISocketRequest):
client = get_client()
# use client to send requests below
...
Source Codes
It may help you to understand cache_resource
better by reading its source codes.
from typing import Any
from typing import Dict
from typing import Generic
from typing import TypeVar
from typing import Protocol
TResource = TypeVar("TResource", bound="Any", covariant=True)
class IResourceFn(Generic[TResource], Protocol):
def __call__(self, *args: Any, **kwargs: Any) -> TResource:
pass
def cache_resource(fn: IResourceFn[TResource]) -> IResourceFn[TResource]:
class Cache:
def __init__(self) -> None:
self._cache: Dict[Any, Any] = {}
def __call__(self, *args: Any, **kwargs: Any) -> TResource:
key = (args, tuple(kwargs.items()))
cached = self._cache.get(key)
if cached is None:
cached = self._cache[key] = fn(*args, **kwargs)
return self._cache[key]
return Cache()