Metadata-Version: 2.1
Name: combadge
Version: 0.1.0a1
Summary: Generic API client based on Pydantic
Home-page: https://github.com/kpn/combadge
License: Apache-2.0
Keywords: api,api-client,pydantic
Author: Pavel Perestoronin
Author-email: pavel.perestoronin@kpn.com
Requires-Python: >=3.8.1,<4.0.0
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System
Classifier: Topic :: System :: Networking
Classifier: Typing :: Typed
Provides-Extra: httpx
Provides-Extra: zeep
Requires-Dist: get-annotations (>=0.1.2,<0.2.0) ; python_version < "3.10"
Requires-Dist: httpx (>=0.23.3,<0.24.0) ; extra == "httpx"
Requires-Dist: pydantic (>=1.10.4,<2.0.0)
Requires-Dist: typing-extensions (>=4.4.0,<5.0.0)
Requires-Dist: zeep (>=4.2.1,<5.0.0) ; extra == "zeep"
Project-URL: Repository, https://github.com/kpn/combadge
Description-Content-Type: text/markdown

# Combadge

[![Checks](https://img.shields.io/github/checks-status/kpn/combadge/main?logo=github)](https://github.com/kpn/combadge/actions/workflows/check.yaml)
[![Coverage](https://codecov.io/gh/kpn/combadge/branch/main/graph/badge.svg?token=ZAqYAaTXwE)](https://codecov.io/gh/kpn/combadge)
![Code style](https://img.shields.io/badge/code%20style-black-000000.svg)
[![Python Version](https://img.shields.io/pypi/pyversions/combadge?logo=python&logoColor=yellow)](https://pypi.org/project/combadge/)
[![License](https://img.shields.io/github/license/kpn/combadge)](LICENSE)

**📻 Application to the service, please respond!**

## Features

- [**Pydantic**](https://docs.pydantic.dev/)-based request and response models
- Automatically derived exception classes
- Using [**Protocol**](https://peps.python.org/pep-0544/)s to define service classes
- Built-in backends:
  - [HTTPX](https://www.python-httpx.org/), sync and async
  - [Zeep](https://docs.python-zeep.org/en/master/), sync and async
- Pluggable backends

## Documentation

<a href="https://kpn.github.io/combadge/">
    <img alt="Documentation" height="30em" src="https://img.shields.io/github/actions/workflow/status/kpn/combadge/docs.yml?label=documentation&logo=github">
</a>

## 🚀 Quick example

```python title="quickstart_httpx.py"
from http import HTTPStatus
from typing import List

from httpx import Client
from pydantic import BaseModel, Field
from typing_extensions import Annotated, Protocol

from combadge.core.binder import bind
from combadge.support.http.markers import QueryParam, http_method, path
from combadge.support.httpx.backends.sync import HttpxBackend


# 1️⃣ Declare the response models:
class CurrentCondition(BaseModel):
    humidity: int
    temperature: Annotated[float, Field(alias="temp_C")]


class Weather(BaseModel):
    status: Annotated[HTTPStatus, Field(alias="__status_code__")]
    current: Annotated[List[CurrentCondition], Field(alias="current_condition")]


# 2️⃣ Declare the protocol:
class SupportsWttrIn(Protocol):
    @http_method("GET")
    @path("/{in_}")
    def get_weather(
        self,
        *,
        in_: str,
        format_: Annotated[str, QueryParam("format")] = "j1",
    ) -> Weather:
        raise NotImplementedError


# 3️⃣ Bind the service:
backend = HttpxBackend(Client(base_url="https://wttr.in"))
service = bind(SupportsWttrIn, backend)

# 🚀 Call the service:
response = service.get_weather(in_="amsterdam")
assert response.status == HTTPStatus.OK
assert response.current[0].humidity == 71
assert response.current[0].temperature == 8.0
```

