fschwar4/saia_python

Python Wrapper Layer around GWDG's AI Services.

2

stars

43

commits

Python

primary language

Jul 19, 2026

updated

fschwar4.github.io/saia_python/
ai

README

saia-python

PyPI Python versions License: AGPL-3.0-only Tests Docs DOI

A Python wrapper for the GWDG SAIA (Scalable AI Accelerator) platform REST API.

SAIA provides self-hosted, OpenAI-compatible AI services at GWDG, including chat completions, voice transcription/translation, document conversion, and RAG (ARCANA). This library wraps the REST API so you can use it from Python — both as an object-oriented client and as standalone functions.

Installation

pip install saia-python

Or from source:

git clone https://github.com/fschwar4/saia_python.git
cd saia_python
pip install -e .

Quick Start

from saia_python import SAIAClient

# API key auto-discovered from SAIA_API_KEY env var, .saia_api, or .env file
client = SAIAClient()

# List available models
print(client.models.list_ids())

# Chat completion
response = client.chat.completions(
    model="meta-llama-3.1-8b-instruct",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response["choices"][0]["message"]["content"])

# Check your rate limits
print(client.get_rate_limits())

All services are also available as standalone functions:

from saia_python import list_model_ids, chat_completion

list_model_ids()
chat_completion(model="meta-llama-3.1-8b-instruct", messages=[...])

Async

For concurrent workloads (e.g. an ASGI service), install the [async] extra and use AsyncSAIAClient — the httpx.AsyncClient twin of the data plane, carrying the same RetryPolicy and rate-limit handling as the sync client (not the openai_async shim, which bypasses them):

pip install saia-python[async]
import asyncio
from saia_python.aio import AsyncSAIAClient


async def main():
    async with AsyncSAIAClient() as client:
        # Non-streaming RAG chat
        answer = await client.arcana.chat(
            model="openai-gpt-oss-120b",
            messages=[{"role": "user", "content": "Summarise the DLBCL first line."}],
            arcana_id="owner/kb",
        )
        print(answer["choices"][0]["message"]["content"])

        # Streaming plain chat — retry=False fails fast with an informative 429
        stream = await client.chat.completions(
            model="meta-llama-3.1-8b-instruct",
            messages=[{"role": "user", "content": "Hello!"}],
            stream=True,
            retry=False,
        )
        async for chunk in stream:
            ...


asyncio.run(main())

Async covers the data plane (chat, ARCANA RAG chat, streaming) plus the read-only control-plane calls (models, arcana version/heartbeat/list/ get, health_check). File upload/index/sync, voice, and document conversion remain synchronous on SAIAClient — see ADR-0007.

Supported Services

ServiceDescriptionGWDG Docs
Chat AIChat completions with streaming and tool callingChat AI
Voice AIAudio transcription and translation (Whisper)Voice AI
ARCANARAG — knowledge base management and retrieval-augmented chatARCANA
DocumentsPDF/document conversion via DoclingSAIA API
ModelsList available models, probe tool-calling supportSAIA API
TokenizersDownload model tokenizers; count chat-template tokens, special-token overhead, and subword fertility (opt-in [tokenizer] extra)Chat AI Models
Rate LimitsInspect current quota and usageSAIA API

Repository Structure

saia-python/
├── saia_python/                  # Main package
│   ├── __init__.py               # Public API, version, functional wrappers
│   ├── client.py                 # SAIAClient — composes all services
│   ├── chat.py                   # ChatService — completions + streaming
│   ├── voice.py                  # VoiceService — transcribe + translate
│   ├── arcana.py                 # ArcanaService — RAG / knowledge bases
│   ├── models.py                 # ModelsService — list available models
│   ├── tokenizer.py              # Tokenizers — download, chat-template token counting
│   ├── documents.py              # DocumentService — Docling conversion
│   ├── openai_compat.py          # OpenAI SDK compatibility layer
│   ├── auth.py                   # Credential and config discovery
│   ├── rate_limits.py            # RateLimitInfo dataclass + parser
│   ├── exceptions.py             # SAIAError hierarchy + raise_for_status
│   ├── _streaming.py             # Shared SSE iterator
│   └── py.typed                  # PEP 561 typing marker
├── docs/                         # Sphinx documentation (PyData theme)
│   ├── conf.py
│   ├── index.rst
│   ├── quickstart.rst
│   ├── explanations.rst
│   ├── architecture.rst
│   ├── implementation.rst
│   ├── configuration.rst
│   ├── api/                      # API reference (one page per module)
│   ├── development.rst
│   ├── dev_notes.rst
│   ├── testing.rst
│   ├── roadmap.rst
│   └── CHANGELOG.md
├── tests/                        # Unit tests
├── examples/
│   ├── saia_python_demo.ipynb         # Interactive demo
│   ├── openai_compatible_proxy.ipynb  # OpenAI-compatible proxy example
│   ├── config.toml.example            # Template for structured config
│   └── .env.example                   # Template for secrets (.env)
├── .github/workflows/            # CI/CD (tests, docs, PyPI publish)
├── pyproject.toml                # Package metadata + dependencies
├── CITATION.cff                  # Citation metadata (CFF 1.2.0)
├── .gitignore
└── README.md

Documentation

Online documentation: https://fschwar4.github.io/saia_python/

Build the docs locally:

pip install -e ".[docs]"
sphinx-build -b html -w warnings_sphinx_build.txt docs docs/_build/html
python3 -m http.server 8000 --directory docs/_build/html

Citation

If you use saia-python in your work, please cite it. Citation metadata lives in CITATION.cff; GitHub's "Cite this repository" button renders it as APA or BibTeX. A Zenodo DOI will be added here once the first release is archived.

License

AGPL-3.0-only

Contributors

fschwar4

43 commits

fschwar4/saia_python

Python Wrapper Layer around GWDG's AI Services.

2

stars

43

commits

Python

primary language

Jul 19, 2026

updated

fschwar4.github.io/saia_python/
ai

README

saia-python

PyPI Python versions License: AGPL-3.0-only Tests Docs DOI

A Python wrapper for the GWDG SAIA (Scalable AI Accelerator) platform REST API.

SAIA provides self-hosted, OpenAI-compatible AI services at GWDG, including chat completions, voice transcription/translation, document conversion, and RAG (ARCANA). This library wraps the REST API so you can use it from Python — both as an object-oriented client and as standalone functions.

Installation

pip install saia-python

Or from source:

git clone https://github.com/fschwar4/saia_python.git
cd saia_python
pip install -e .

Quick Start

from saia_python import SAIAClient

# API key auto-discovered from SAIA_API_KEY env var, .saia_api, or .env file
client = SAIAClient()

# List available models
print(client.models.list_ids())

# Chat completion
response = client.chat.completions(
    model="meta-llama-3.1-8b-instruct",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response["choices"][0]["message"]["content"])

# Check your rate limits
print(client.get_rate_limits())

All services are also available as standalone functions:

from saia_python import list_model_ids, chat_completion

list_model_ids()
chat_completion(model="meta-llama-3.1-8b-instruct", messages=[...])

Async

For concurrent workloads (e.g. an ASGI service), install the [async] extra and use AsyncSAIAClient — the httpx.AsyncClient twin of the data plane, carrying the same RetryPolicy and rate-limit handling as the sync client (not the openai_async shim, which bypasses them):

pip install saia-python[async]
import asyncio
from saia_python.aio import AsyncSAIAClient


async def main():
    async with AsyncSAIAClient() as client:
        # Non-streaming RAG chat
        answer = await client.arcana.chat(
            model="openai-gpt-oss-120b",
            messages=[{"role": "user", "content": "Summarise the DLBCL first line."}],
            arcana_id="owner/kb",
        )
        print(answer["choices"][0]["message"]["content"])

        # Streaming plain chat — retry=False fails fast with an informative 429
        stream = await client.chat.completions(
            model="meta-llama-3.1-8b-instruct",
            messages=[{"role": "user", "content": "Hello!"}],
            stream=True,
            retry=False,
        )
        async for chunk in stream:
            ...


asyncio.run(main())

Async covers the data plane (chat, ARCANA RAG chat, streaming) plus the read-only control-plane calls (models, arcana version/heartbeat/list/ get, health_check). File upload/index/sync, voice, and document conversion remain synchronous on SAIAClient — see ADR-0007.

Supported Services

ServiceDescriptionGWDG Docs
Chat AIChat completions with streaming and tool callingChat AI
Voice AIAudio transcription and translation (Whisper)Voice AI
ARCANARAG — knowledge base management and retrieval-augmented chatARCANA
DocumentsPDF/document conversion via DoclingSAIA API
ModelsList available models, probe tool-calling supportSAIA API
TokenizersDownload model tokenizers; count chat-template tokens, special-token overhead, and subword fertility (opt-in [tokenizer] extra)Chat AI Models
Rate LimitsInspect current quota and usageSAIA API

Repository Structure

saia-python/
├── saia_python/                  # Main package
│   ├── __init__.py               # Public API, version, functional wrappers
│   ├── client.py                 # SAIAClient — composes all services
│   ├── chat.py                   # ChatService — completions + streaming
│   ├── voice.py                  # VoiceService — transcribe + translate
│   ├── arcana.py                 # ArcanaService — RAG / knowledge bases
│   ├── models.py                 # ModelsService — list available models
│   ├── tokenizer.py              # Tokenizers — download, chat-template token counting
│   ├── documents.py              # DocumentService — Docling conversion
│   ├── openai_compat.py          # OpenAI SDK compatibility layer
│   ├── auth.py                   # Credential and config discovery
│   ├── rate_limits.py            # RateLimitInfo dataclass + parser
│   ├── exceptions.py             # SAIAError hierarchy + raise_for_status
│   ├── _streaming.py             # Shared SSE iterator
│   └── py.typed                  # PEP 561 typing marker
├── docs/                         # Sphinx documentation (PyData theme)
│   ├── conf.py
│   ├── index.rst
│   ├── quickstart.rst
│   ├── explanations.rst
│   ├── architecture.rst
│   ├── implementation.rst
│   ├── configuration.rst
│   ├── api/                      # API reference (one page per module)
│   ├── development.rst
│   ├── dev_notes.rst
│   ├── testing.rst
│   ├── roadmap.rst
│   └── CHANGELOG.md
├── tests/                        # Unit tests
├── examples/
│   ├── saia_python_demo.ipynb         # Interactive demo
│   ├── openai_compatible_proxy.ipynb  # OpenAI-compatible proxy example
│   ├── config.toml.example            # Template for structured config
│   └── .env.example                   # Template for secrets (.env)
├── .github/workflows/            # CI/CD (tests, docs, PyPI publish)
├── pyproject.toml                # Package metadata + dependencies
├── CITATION.cff                  # Citation metadata (CFF 1.2.0)
├── .gitignore
└── README.md

Documentation

Online documentation: https://fschwar4.github.io/saia_python/

Build the docs locally:

pip install -e ".[docs]"
sphinx-build -b html -w warnings_sphinx_build.txt docs docs/_build/html
python3 -m http.server 8000 --directory docs/_build/html

Citation

If you use saia-python in your work, please cite it. Citation metadata lives in CITATION.cff; GitHub's "Cite this repository" button renders it as APA or BibTeX. A Zenodo DOI will be added here once the first release is archived.

License

AGPL-3.0-only

Contributors

fschwar4

43 commits

Languages

Python

100.0%