Model Serving Server - FastAPI REST API for serving trained models.
Provides HTTP endpoints for loading models, making predictions, and managing the model serving lifecycle.
Usage: # Serve a single model from tuiml.serving import serve serve("model.pkl", port=8000)
# Or create a custom app from tuiml.serving import ModelServer server = ModelServer() server.load_model("my_model", "model.pkl") app = server.create_app() # Run with uvicorn: uvicorn app:app
Classes
REST API server for serving trained TuiML models.
Wraps FastAPI to provide endpoints for model management and prediction serving.
Loading a model deserialises a pickle, which executes whatever the file says. The endpoints are therefore authenticated by default and POST /models -- the one that takes a path from the caller -- is disabled unless models_dir bounds where it may read from.
__init__( self, max_models: int = 10, title: str = 'TuiML Model Server', version: str = '1.0.0', auth_token: Union[str, bool] = True, models_dir: Optional[Union[str, Path]] = None, allow_origins: Optional[List[str]] = None, )
Parameters
max_models
title
version
auth_token
/ and /health. True generates one; a string uses it as given; False disables authentication entirely, which is only appropriate behind a proxy that provides its own.
models_dir
POST /models may load from. Paths are resolved and must stay inside it. When unset that endpoint is refused, because without a bound it will unpickle any file the caller names.
allow_origins
Attributes
auth_token
>>> from tuiml.serving import ModelServer
>>> server = ModelServer()
>>> server.load_model("clf", "classifier.pkl")
>>> app = server.create_app()
>>> # Run with: uvicorn app:app --port 8000
>>> # Then: curl -H "Authorization: Bearer $TOKEN" localhost:8000/models
Methods
load_model
(self, model_id: str, path: Union[str, Path], metadata: Optional[Dict]=None) -> Dict[str, Any]
load_model
(self, model_id: str, path: Union[str, Path], metadata: Optional[Dict]=None) -> Dict[str, Any]
Load a model into the server.
Parameters
model_id
path
metadata
Returns
dict
Functions
Create a FastAPI application for model serving.
Parameters
model_path
model_id
max_models
auth_token
True generates one, which is readable afterwards as app.state.auth_token; False disables authentication.
models_dir
POST /models may load from. Unset disables that endpoint.
allow_origins
Returns
FastAPI
>>> from tuiml.serving import create_app
>>> app = create_app("classifier.pkl")
>>> token = app.state.auth_token # send as: Authorization: Bearer <token>
>>> # Run with: uvicorn module:app --port 8000
Serve a trained model via REST API.
Workflow, or a model object and starts a uvicorn server exposing prediction endpoints.Parameters
model_or_path
The model to serve:
- •
str: Path to a saved model file - •
Workflow: a fitted pipeline fromtrain()orWorkflow.fit() - •model object, Any object with a
predict()method
host
port
model_id
background
reload
background=False.
workers
background=False.
Returns
dict or None
background=True, returns a dict with server_id, url, and endpoints. If background=False, blocks and returns None.
Serve the pipeline that train() returned:
>>> import tuiml
>>> model = tuiml.train({
... "model": {"name": "NaiveBayesClassifier"},
... "data": {"source": "iris"},
... }) # doctest: +SKIP
>>> info = tuiml.serve(model, port=8000) # doctest: +SKIP
>>> info["url"] # doctest: +SKIP
'http://127.0.0.1:8000'
Serve any fitted model. Every algorithm works, with or without a
pipeline around it (models also carry their own .serve() method):
>>> from tuiml.algorithms.trees import RandomForestClassifier
>>> clf = RandomForestClassifier(n_estimators=100) # doctest: +SKIP
>>> clf = clf.fit(X_train, y_train) # doctest: +SKIP
>>> info = tuiml.serve(clf, port=8001) # doctest: +SKIP
Serve a fitted pipeline built from objects; the fitted preprocessing
travels with it, so the API accepts raw rows:
>>> from tuiml import Workflow
>>> from tuiml.preprocessing import StandardScaler # doctest: +SKIP
>>> wf = Workflow([StandardScaler(), RandomForestClassifier()])
... # doctest: +SKIP
>>> wf = wf.fit(X_train, y_train) # doctest: +SKIP
>>> info = tuiml.serve(wf, port=8002) # doctest: +SKIP
Serve a model saved earlier with model.save(path):
>>> info = tuiml.serve("model.pkl", port=8003) # doctest: +SKIP
Then manage the running servers:
$ tuiml.server_status() # doctest: +SKIP
$ tuiml.stop_server("127.0.0.1:8001") # doctest: +SKIP
$ tuiml.stop_server() # doctest: +SKIP
Stop running model server(s).
Parameters
server_id
"host:port") to stop. If None, stops all running servers.
Stop a specific server:
>>> import tuiml
>>> tuiml.stop_server("127.0.0.1:9999")
Stop all servers:
$ tuiml.stop_server()
Get status of running model servers.
Returns
list of dict
server_id, host, port, model_id, and url.
>>> import tuiml
>>> tuiml.server_status()
[{'server_id': '127.0.0.1:9999', 'url': 'http://127.0.0.1:9999', ...}]