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.1.1.tar.gz (65.3 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.1.1-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: saronia-1.1.1.tar.gz
  • Upload date:
  • Size: 65.3 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.1.1.tar.gz
Algorithm Hash digest
SHA256 05abc1e249e0741209f55be2341506b91e4d8ce3235c6de2ad818414c2561f8e
MD5 2c2882a1beadb05b2eeca8563e92adc2
BLAKE2b-256 0bfd184dd50cb386ecb9336a9301da9025ffa4fbafc3c39d8b8d8fcb1a8cc0a5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: saronia-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 23.2 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.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9d896b452fbacfedd168907dc4100997a1c8fe517a8ad3ee5f0e058baa70ba9e
MD5 c807121b8c43c7e398521c510f65479e
BLAKE2b-256 3771f06115f1f5a57bc7fb8fe6e52f7bfd095c5d0e56db17017978c7c3ff338c

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