Skip to main content

Asas

Asas framework, high performance, easy to learn, fast to code, ready for production

PyPI version Python versions License


Asas is a Python framework for building typed, simple API clients in a few lines. You write a subclass, annotate methods with @get/@post/…, and Asas handles request building, parameter routing, Pydantic validation, authentication, refresh-and-retry, and paging for you — for synchronous and asynchronous code with the same decorators.

Why Asas?

Traditional HTTP clients bury your API's shape in a pile of requests.get(...) calls, string URLs, and manual JSON wrangling. Asas flips that: your client class is your API client, declared once and typed end-to-end.

  • Write your whole API client as a class with decorators — no boilerplate to maintain.
  • One signature drives path segments, query params, and JSON bodies automatically.
  • Pydantic in, validated Pydantic out. No hand-rolling json.loads + dict lookups.
  • Ready for real APIs: auth, automatic token refresh (even on custom conditions), and resource CRUD with paging that needs no page-loop code.

Installation

pip install asas-py             # + Pydantic + httpx (the default engine)
pip install "asas-py[requests]" # + the optional sync-only requests engine

Python 3.9+ (see Documentation for the Arabic guide).

Quick start

Subclass a client and declare your endpoints. That's it.

from pydantic import BaseModel

from asas import AsasClient, get


class Todo(BaseModel):
    id: int
    todo: str
    completed: bool


class TodoClient(AsasClient):
    @get("/todos/{id}", response_model=Todo)
    def get_todo(self, todo: Todo, id: int) -> Todo:
        return todo


client = TodoClient(base_url="https://dummyjson.com")
task = client.get_todo(id=1)
print(task.todo)

id is a path placeholder, Todo validates the JSON response, and todo is injected as the first argument after self. Want async? Use @get on an async def with AsasAsyncClient — the decorators are identical. This snippet runs as-is against dummyjson.com (a free public REST API).

Try it live

from typing import List

from pydantic import BaseModel

from asas import AsasClient, get


class Product(BaseModel):
    id: int
    title: str
    price: float


class ProductPage(BaseModel):
    products: List[Product]


class StoreClient(AsasClient):
    @get("/products", response_model=ProductPage)
    def products(self, page: ProductPage) -> List[Product]:
        return page.products


client = StoreClient(base_url="https://dummyjson.com")
first = client.products()
print(f"{len(first)} products, first: {first[0].title} (${first[0].price})")

Resources & lazy pagination — no page-loop code

from pydantic import BaseModel

from asas import AsasClient, AsasResource, OffsetPaginator


class User(BaseModel):
    id: int
    name: str


class Users(AsasResource):
    path = "/users"
    model = User
    paginator = OffsetPaginator(limit=100, items_key="users")


class Client(AsasClient):
    users = Users()


client = Client(base_url="https://api.example.com")
for user in client.users:          # pages fetched on demand, loop ends itself
    print(user.name)

single = client.users.get(42)      # generated CRUD, too

Authentication & automatic refresh

from asas import AsasClient, RefreshingBearerAuth, Response, get, refresh_on_keyword

auth = RefreshingBearerAuth(
    "expired-token",
    refresh_callback=lambda: mint_new_token(),
    refresh_when=refresh_on_keyword("token_expired"),  # refresh on a 200, too
)


class MyClient(AsasClient):
    @get("/me")
    def me(self, response: Response) -> dict:
        return response.json()


client = MyClient(base_url="https://api.example.com", auth=auth)

Features

  • Sync & async clients that share the same @get/@post/@put/@delete/@patch decorators — Asas auto-detects async def.
  • Automatic parameter routing — path placeholders, Pydantic-model bodies, and query params from a single method signature.
  • Pydantic responses via response_model: validated, typed results with zero manual parsing.
  • Resources + lazy paginationAsasResource gives list/get/create/update/ delete and iterator-style paging (page-number, offset, cursor, and Link-header strategies).
  • Authentication out of the boxNoAuth, BasicAuth, BearerAuth, APIKeyAuth (header/query/cookie), RefreshingBearerAuth, and CompositeAuth, with swappable runtime auth and easy-to-test refresh conditions.
  • Transport-agnostic corehttpx is bundled; bring your own engine (an optional, sync-only requests engine ships behind the [requests] extra).

Roadmap

Planned and share-worthy next features:

  • OpenAPI / Swagger client generation — generate a full typed client (Pydantic models + client code) straight from an OpenAPI schema.
  • GraphQL support — query / mutation / subscription decorators with typed responses.
  • Testing module — fixtures and helpers to make writing client tests trivial (respx mocks, base harnesses, captured requests).
  • Plugin / hook system — request/response lifecycle hooks, middleware, and event listeners.
  • Cookie & session helpers — first-class session management, cookie jars, and CSRF handling.

Have a feature in mind? Open an issue or start a discussion — contributions and ideas are very welcome.

Contributing

Contributions of all kinds are welcome — bug reports, documentation, examples, and features.

  1. Fork & clone the repo.
  2. Set up: make dev-install (installs deps + git hooks).
  3. Develop: write your code with type hints, then make format and make lint.
  4. Test: make test.
  5. Commit with a clear message and open a Pull Request.

See CONTRIBUTING.md for the full workflow and coding standards.

Documentation

Full docs (English + العربية): heshammoawad.github.io/asas-py

License

Released under the MIT License.

Download files

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

Source Distribution

asas_py-0.1.0.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

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

asas_py-0.1.0-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file asas_py-0.1.0.tar.gz.

File metadata

  • Download URL: asas_py-0.1.0.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for asas_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75993e69080004479270e12c5e007a0e7cd011e3949c4199b7c97cf2f90ea5fa
MD5 65d1568c647481fc2c9a241bc00e8923
BLAKE2b-256 15518a30b0a4c0fdb9d149a91ebf1aa5342f18b762990b6d20434eafa53e6cab

See more details on using hashes here.

File details

Details for the file asas_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: asas_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for asas_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3079be4879d842b5b49abc0034c4cd3550744adb1e4446f2526a1d371fd259ea
MD5 fc6dbf02f4b876a4d54aee68c0429a2d
BLAKE2b-256 4805e56c0ff1ba5abc4e7670627baeb0d0a4cfdae314f6dc41c4b55a29013fab

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

0.0.1

2 files

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