Experimental Features¶
As experiment, there is also a Fetch descriptor, that
helps reduce boilerplate and lets you write wrappers
in almost declarative way:
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Generic, List, Mapping, TypeVar
from apiwrappers import AsyncDriver, Driver, Request, Url
from apiwrappers.xfeatures import Fetch
T = TypeVar("T", Driver, AsyncDriver)
@dataclass
class Repo:
id: int
name: str
class Github(Generic[T]):
get_repos = Fetch(List[Repo])
def __init__(self, host: str, driver: T):
self.url = Url(host)
self.driver: T = driver
@get_repos.request
def get_repos_request(self, username: str) -> Request:
url = self.url("/users/{username}/repos", username=username)
return Request("GET", url)
Here we did the following:
First, we defined
Repodataclass that describes what we want to get from responseNext, we used
Fetchdescriptor to declare API methodEach
Fetchobject also needs a so-called request factory. We provide one by usingget_repos.requestdecorator on theget_repos_requestmethodget_repos_requestis a pure function and easy to testNo need to use overload - mypy will understand the return type of the
.get_reposcall
There are several trade-offs using this approach:
no auto-completion when calling a method, which is a really huge flaw.
mypy won’t check the signature of the method due to limited support of the callable argument
for end user it will be hard to understand what’s going on and where to look in case of any problem