Skip to main content

Logo

saronia

A lightweight, spec-driven builder for API clients and controllers.

python version saronia version basedpyright strict

Features

  • Declarative API controller syntax
  • Type-safe request/response handling
  • Support for multiple HTTP clients (wreq, aiohttp, or custom)
  • Comprehensive error handling
  • Support for path parameters, query parameters, headers, body, JSON, form data, and file uploads
  • Built on top of msgspex for fast serialization and kungfu for functional types (optional)

Getting started

# Base installation
pip install saronia

# With wreq client
pip install saronia[wreq]

# With aiohttp client
pip install saronia[aiohttp]
import asyncio
from dataclasses import dataclass
from uuid import UUID
from http import HTTPStatus

from kungfu import Error, Ok
from msgspex import Model
from saronia import API, APIError, APIResult, HTTPBearer, ModelStatusError, get, post

from wreq import Client
from saronia import WreqClient

Token = HTTPBearer


@dataclass
class Auth:
    token: Token


cool_api = API.endpoint("/coolapi/v1").bind_auth(Auth)


class ValidationError(Model, ModelStatusError[HTTPStatus.INTERNAL_SERVER_ERROR]):
    message: str


class NotFoundError(Model, ModelStatusError[HTTPStatus.NOT_FOUND]):
    message: str


class Book(Model):
    id: UUID
    name: str


class CreateBookDTO(Model, kw_only=True):
    book_id: UUID
    name: str


@cool_api("/books", auth=Token)
class BooksController:
    @get("/{book_id}", ValidationError, NotFoundError)
    async def get_book_by_id(self, book_id: UUID) -> Book: ...

    @post("/create", form=CreateBookDTO)  # or as a Result
    async def create_book(self) -> APIResult[Book, ValidationError | NotFoundError]: ...


books = BooksController()


async def main() -> None:
    client = Client()

    cool_api.build(WreqClient(client, base_url="https://api.example.com", request_timeout=45.0))
    cool_api.auth(token=Token("abc123..."))

    try:
        book = await books.get_book_by_id(book_id=UUID("12345678-1234-5678-1234-567812345678"))
        print("Book:", book)
    except APIError as error:
        print("API error:", error)
        return

    match await books.create_book(book_id=UUID("87654321-4321-8765-4321-876543218765"), name="New Book"):
        case Ok(new_book):
            print("New book:", new_book)
        case Error(error):
            print("API error:", error)


asyncio.run(main())

License

saronia is MIT licensed

Download files

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

Source Distribution

saronia-1.7.2.tar.gz (71.1 kB view details)

Uploaded Source

Built Distribution

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

saronia-1.7.2-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file saronia-1.7.2.tar.gz.

File metadata

  • Download URL: saronia-1.7.2.tar.gz
  • Upload date:
  • Size: 71.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for saronia-1.7.2.tar.gz
Algorithm Hash digest
SHA256 87f132c3b21b4c6e43d86df0e82dcea8732e074f0af1671d5b07867077216987
MD5 e829043f35eed1c11fcd6eb19720d47d
BLAKE2b-256 9ee25a78b416815452f07063ed596231d1630ba185f2ac3d262a1e2146817a3b

See more details on using hashes here.

File details

Details for the file saronia-1.7.2-py3-none-any.whl.

File metadata

  • Download URL: saronia-1.7.2-py3-none-any.whl
  • Upload date:
  • Size: 27.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for saronia-1.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 893005cddaf1dc06dafd028b9f571ad395045458dcc3a7538ff41a0b81fb3512
MD5 e0a34d52cc47871dbd3f18ef901d04bb
BLAKE2b-256 948bbca28689da16638368ae7397c3ae23b29abb37b569226ffee3c280973368

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page