The python framework, providing quick way to build client-side API wrappers. Use type annotations, to build requests, with little or no implementation
Project description
sensei
The python framework, providing quick way to build client-side API wrappers. Use type annotations, to build requests, with little or no implementation
Source code is made available under the MIT License.
Quick Overview
API Wrapper should follow these principles:
- Provide sync and async code versions
- Validate data before accessing the API. Because better outcome is catching exception, thrown due to wrong data, than getting json explaining reason of error.
- Handle QPS (Queries per second) limits.
To follow these principles, you either to violate DRY or have to maintain bad code architecture. Sensei is tool to avoid these issues.
Example of OOP code.
from typing import Annotated, Any, Self
from sensei import Router, Query, Path, APIModel, Header, Args, pascal_case, format_str, RateLimit
router = Router('https://reqres.in/api', rate_limit=RateLimit(5, 1))
@router.model()
class BaseModel(APIModel):
def __finalize_json__(self, json: dict[str, Any]) -> dict[str, Any]:
return json['data']
def __prepare_args__(self, args: Args) -> Args:
args.headers['X-Token'] = 'secret_token'
return args
def __header_case__(self, s: str) -> str:
return pascal_case(s)
class User(BaseModel):
email: str
id: int
first_name: str
last_name: str
avatar: str
@classmethod
@router.get('/users')
def query(
cls,
page: Annotated[int, Query(1)],
per_page: Annotated[int, Query(3, le=7)],
bearer_token: Annotated[str, Header('secret', le=10)],
) -> list[Self]:
...
@classmethod
@router.get('/users/{id_}')
def get(cls, id_: Annotated[int, Path(alias='id')]) -> Self:
...
@router.delete('/users/{id_}')
def delete(self) -> Self:
...
@delete.prepare
def _delete_in(self, args: Args) -> Args:
url = args.url
url = format_str(url, {'id_': self.id})
args.url = url
return args
users = User.query(per_page=7)
user_id = users[0].id
user = User.get(user_id)
print(user == users[0])
Example of functional style.
from typing import Annotated
from sensei import Router, Path, APIModel
router = Router('https://pokeapi.co/api/v2/')
class Pokemon(APIModel):
name: str
id: int
height: int
weight: int
types: list
@router.get('/pokemon/{pokemon_name}')
def get_pokemon(
pokemon_name: Annotated[str, Path()],
) -> Pokemon:
...
pokemon = get_pokemon(pokemon_name="pikachu")
print(pokemon)
Installing sensei
To install sensei
from PyPi, you can use that:
pip install sensei
To install sensei
from GitHub, use that:
pip install git+https://github.com/CrocoFactory/sensei.git
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file sensei-0.1.0rc3.tar.gz
.
File metadata
- Download URL: sensei-0.1.0rc3.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.20
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cc2fe4dbc2cafab2fd6a858fc3a2a0add027690ac958104948aee0630acae4f0 |
|
MD5 | f7e093981cd012dc3ca1767dcb3b4a37 |
|
BLAKE2b-256 | 36b89d8b32eb0526f43697578b040c437cd90ef50d090c85b94d6b050e1c417c |
File details
Details for the file sensei-0.1.0rc3-py3-none-any.whl
.
File metadata
- Download URL: sensei-0.1.0rc3-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.20
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4a0f9844b76f921e03649da370d42f88a2c62175097b7ba97c1f26d5f683d6f5 |
|
MD5 | 055a9fd824a76e32e8d0528aa18de28c |
|
BLAKE2b-256 | 33243c2acf39c4c0ba4668b56d16c78368f067103198f12e3de96c60de8407be |