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

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"))

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.

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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiserver-0.1.1.tar.gz (23.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aiserver-0.1.1-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file aiserver-0.1.1.tar.gz.

File metadata

  • Download URL: aiserver-0.1.1.tar.gz
  • Upload date:
  • Size: 23.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for aiserver-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cb915d4a9b48a995753eb7f7683216895f2c3bca153440f840e5b4c8b8613991
MD5 8b9ab93ea8664d1a031406600c918b17
BLAKE2b-256 cf858175f94a65c020b1db47d2f7d240d24b726d8d5c00bbad11d7bc048660b3

See more details on using hashes here.

File details

Details for the file aiserver-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: aiserver-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for aiserver-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1a4521e11bacd0e3cf24648687ea6d140a9a6669a1cf5345ad23381b097d5702
MD5 fa35c6f5b82c63b8ba2c6d1cbf6a3a6d
BLAKE2b-256 b041b11023f7c6d26c9a5918bef809debc565de7b57bda2390ba97f273f1d181

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

0.0.9

1 file

0.0.8

1 file

0.0.6

1 file

0.0.3

1 file

0.0.1

1 file

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