Skip to main content

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

Project description

saronia

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

  • Declarative API controller syntax
  • Type-safe request/response handling with APIResult
  • Support for multiple HTTP clients (rnet, aiohttp, or custom)
  • Comprehensive error handling with StatusError mixin
  • 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

Getting Started

# Base installation
pip install saronia

# With rnet client
pip install saronia[rnet]

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

from kungfu import Error
from msgspex import Model
from saronia import API, APIResult, HTTPBearer, StatusError, get, post

from rnet import Client
from saronia import RnetClient


class Auth(Model):
    bearer: HTTPBearer


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


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


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


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


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


@cool_api("/books")
class BooksController:
    @get("/{book_id}")
    async def get_book_by_id(self, book_id: UUID) -> APIResult[Book, ValidationError | NotFoundError]:
        ...

    @post("/create", CreateBookDTO)
    async def create_book(self) -> APIResult[Book, ValidationError | NotFoundError]:
        ...


books = BooksController()


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

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

    book = (await books.get_book_by_id(UUID("12345678-1234-5678-1234-567812345678"))).unwrap()
    print(f"Book: {book.name}")

    match await books.create_book(id=UUID("87654321-4321-8765-4321-876543218765"), name="New Book"):
        case Error(error):
            print(f"Error: {error}")


asyncio.run(main())

License

saronia is MIT licensed

Project details


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.3.0.tar.gz (66.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.3.0-py3-none-any.whl (24.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: saronia-1.3.0.tar.gz
  • Upload date:
  • Size: 66.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.3.0.tar.gz
Algorithm Hash digest
SHA256 a768af140f1772c5df761e77a6feafc4a7d240d2b6a1b37850680b530237b64b
MD5 b742b2775d1e28a1f88c452ff3cbcc57
BLAKE2b-256 49718221c219563a3a594f9bb5cc81e56fb277ac5b332ee5aa57d382c288e0e1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: saronia-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 24.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ab1226a9e56fb0a1a5b0ab6e37addf4daccd833a89646142492179e14377cad
MD5 98f75d896dfc69c301717f9a7969605a
BLAKE2b-256 9878ada51ff93a7c81d41986b441aeecebafcab7da05b51ab4afb703b7ea3529

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