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
Repo
dataclass that describes what we want to get from responseNext, we used
Fetch
descriptor to declare API methodEach
Fetch
object also needs a so-called request factory. We provide one by usingget_repos.request
decorator on theget_repos_request
methodget_repos_request
is a pure function and easy to testNo need to use overload - mypy will understand the return type of the
.get_repos
call
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