Skip to content

Models

Combadge is built on top of Pydantic, hence Pydantic models are natively supported in service protocols.

However, thanks to the Pydantic's TypeAdapter, Combadge automatically supports:

Built-in Python types

builtin.py
from typing_extensions import Annotated, Protocol

from combadge.core.markers import Extract
from combadge.support.httpx.backends.sync import HttpxBackend
from combadge.support.http.markers import Payload, http_method, path
from httpx import Client


class Httpbin(Protocol):
    @http_method("POST")
    @path("/anything")
    def post_anything(self, foo: Annotated[int, Payload()]) -> Annotated[int, Extract("data")]:
        ...


backend = HttpxBackend(Client(base_url="https://httpbin.org"))
assert backend[Httpbin].post_anything(42) == 42

Standard dataclasses

dataclasses.py
from dataclasses import dataclass

from typing_extensions import Protocol, Annotated

from combadge.support.httpx.backends.sync import HttpxBackend
from combadge.support.http.markers import Payload, http_method, path
from httpx import Client


@dataclass
class Request:
    foo: int


@dataclass
class Response:
    data: str


class Httpbin(Protocol):
    @http_method("POST")
    @path("/anything")
    def post_anything(self, foo: Annotated[Request, Payload()]) -> Response:
        ...


backend = HttpxBackend(Client(base_url="https://httpbin.org"))
assert backend[Httpbin].post_anything(Request(42)) == Response(data='{"foo": 42}')

Typed dictionaries

typed_dict.py
from typing_extensions import Protocol, TypedDict, Annotated

from combadge.support.httpx.backends.sync import HttpxBackend
from combadge.support.http.markers import Payload, http_method, path
from httpx import Client


class Request(TypedDict):
    foo: int


class Response(TypedDict):
    data: str


class Httpbin(Protocol):
    @http_method("POST")
    @path("/anything")
    def post_anything(self, foo: Annotated[Request, Payload()]) -> Response:
        ...


backend = HttpxBackend(Client(base_url="https://httpbin.org"))
assert backend[Httpbin].post_anything({"foo": 42}) == {"data": '{"foo": 42}'}