Skip to main content

AIserver

PyPI Python CI License

中文说明

AIserver is a lightweight, local-first Python server for exposing AI inference functions as secure, typed, and concurrency-controlled HTTP APIs.

It is intentionally smaller than a model runtime or distributed serving platform. Bring any Python model or pipeline you already use; AIserver handles request validation, task execution, job status, progress, lifecycle hooks, and conservative network defaults.

Features

  • Turn typed Python functions into documented HTTP endpoints.
  • Accept multipart file uploads for image, audio, and document inference tasks.
  • Accept base64 JSON file inputs when multipart is inconvenient.
  • Return generated files as base64-encoded FileResult payloads.
  • Run tasks directly or submit in-memory asynchronous jobs.
  • List, delete, and inspect asynchronous jobs through HTTP.
  • Download FileResult job outputs as files.
  • Optionally persist job status and results in SQLite.
  • Limit concurrency per task to protect CPU, GPU, and model memory.
  • Report progress from synchronous or asynchronous inference code.
  • Apply per-task timeouts and bounded job history.
  • Load and release models with startup and shutdown hooks.
  • Protect private endpoints with AISERVER_TOKEN.
  • Reject oversized request bodies and bind to localhost by default.
  • Generate OpenAPI documentation automatically at /docs.
  • No telemetry, model downloads, protocol proxy, or request-body logging.

Requirements

  • Python 3.11 or newer
  • Windows, Linux, or macOS

Install

pip install AIserver

Quick start

Create app.py:

from aiserver import AIServer, TaskContext

server = AIServer("demo")


@server.task(concurrency=2, timeout=30)
def classify(text: str, context: TaskContext) -> dict[str, str]:
    context.report(0.5, "running inference")
    return {"label": text.upper()}

Run it:

aiserver run app:server

Open http://127.0.0.1:8000/docs, or call it directly:

curl -X POST http://127.0.0.1:8000/v1/tasks/classify/run \
  -H "Content-Type: application/json" \
  -d '{"text":"hello"}'

Submit the same task as a job:

curl -X POST http://127.0.0.1:8000/v1/tasks/classify/jobs \
  -H "Content-Type: application/json" \
  -d '{"text":"hello"}'

Poll the returned status_url to read progress and the final result.

File uploads and file results

Use file_task when the model expects an uploaded image, audio clip, or document:

from aiserver import AIServer, FileResult, InputFile, TaskContext

server = AIServer("vision")


@server.file_task(concurrency=1, timeout=60, max_file_bytes=8 * 1024 * 1024)
def detect(
    image: InputFile,
    context: TaskContext,
) -> FileResult:
    context.report(0.5, "running detector")
    return FileResult.from_bytes(
        b"generated report",
        filename="report.txt",
        content_type="text/plain",
    )

Call it with multipart form data:

curl -X POST http://127.0.0.1:8000/v1/tasks/detect/run \
  -F "file=@sample.png"

When multipart upload is inconvenient, use the generated base64 JSON endpoints:

POST /v1/tasks/detect/run-base64
POST /v1/tasks/detect/jobs-base64

If an asynchronous job returns FileResult, download it directly:

curl -L http://127.0.0.1:8000/v1/jobs/JOB_ID/result-file -o report.txt

SQLite job history

Jobs are kept in memory by default. For small LAN services that need status and results to survive process restarts, pass a SQLite store:

from aiserver import AIServer, SQLiteJobStore

server = AIServer("demo", job_store=SQLiteJobStore("jobs.sqlite3"))

Or enable it from the CLI without changing application code:

aiserver run app:server --jobs-db jobs.sqlite3

Queued or running jobs found after a restart are marked as interrupted. AIserver does not replay unfinished model work.

Lifecycle hooks

Keep large model objects in your application module and initialize them once:

model = None


@server.on_startup
def load_model():
    global model
    model = load_your_model()


@server.on_shutdown
def release_model():
    global model
    model = None

AIserver is deliberately single-process so tasks can share an in-memory model. Without a job_store, asynchronous job records stay in memory and are lost when the process restarts.

See examples for OCR, image classification, YOLO detection, speech-to-text, local embeddings, custom pipelines, and a LAN drone detector pattern.

List bundled examples from the CLI:

aiserver examples
aiserver version

LAN access

The CLI refuses unauthenticated non-loopback binding by default. Set the token in the environment, then start the server:

$env:AISERVER_TOKEN = "use-a-long-random-value"
aiserver run app:server --host 0.0.0.0

Clients can use either header:

Authorization: Bearer <token>
X-API-Key: <token>

Do not pass tokens on the command line or commit them to source control. Use a reverse proxy with TLS before exposing AIserver outside a trusted private network.

Scope

AIserver is not an LLM inference engine, OpenAI/Anthropic protocol gateway, model downloader, distributed scheduler, or hosted control plane. Projects that need those capabilities should use specialized runtimes and platforms.

Historical package notice

Version 0.1.0 and newer are a clean rewrite. They do not preserve the unrelated remote-chat and robot demo APIs from the historical 0.0.x releases. Those releases should not be used.

Development

python -m venv .venv
.venv/Scripts/pip install -e ".[dev]"
ruff check .
pytest
python -m build
python -m twine check dist/*

License

MIT

Metadata

Release files for AIserver 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for AIserver 0.1.2
File Size Uploaded Provenance
aiserver-0.1.2.tar.gz 26.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for AIserver 0.1.2
File Interpreter ABI Platform
aiserver-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 44.5 kB

Release files / aiserver-0.1.2.tar.gz

Download URL aiserver-0.1.2.tar.gz
Size 26.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e0fd6032ede7b5fb01e7f839e4b2a1143d1dbd847086006e46a46459af9fe543
BLAKE2b-256 checksum
How to use checksums
be55cd2d9cc7a04ecffc551cf69b1531e8499a8aa6e8ee733bd6154f1077a765
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / aiserver-0.1.2-py3-none-any.whl

Download URL aiserver-0.1.2-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
26b557f62c928ebef0e8503fae78d2bc5fa2550bed9e3c6fafc49d1eb3cc7a0a
BLAKE2b-256 checksum
How to use checksums
f27051b4800560609b510e9f6fcbfc9693207bd5380ae642f3084e0ee1d62636
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Security for AIserver 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page