Simple and expressive REST clients without the fuss
Project description
Slink
Inspired by uplink, a simple way to build rest API clients without OpenAPI, and without a lot of requests boilerplate.
Install
poetry install
Basic Usage
Model your resource in Pydantic
from pydantic import BaseModel
class MyResource(BaseModel):
name: str
value: int
Create an API
from slink import Api, get, post, Query, Body
class MyTestApi(Api):
# Define a get
@get("rest/api/3/{resource_key}")
def get_resource(self, resource_key: str):
return MyResource(**self.response.json())
# Define it with some query params
@get("rest/api/3/{resource_key}/param", testvalue=Query())
def get_resource_with_param(self, resource_key: str, testvalue: str):
return MyResource(**self.response.json())
# And post your body content
@post("rest/api/3/{resource_key}", body=Body())
def post_resource(self, resource_key: str, body: dict):
return MyResource(**self.response.json())
Then use it:
api = MyTestApi(base_url="http://example.com/")
result = api.get_resource(resource_key="REST")
result = api.get_resource_with_param(resource_key="REST", testvalue="test")
result = api.post_resource(resource_key="TEST", body={"foo": "bar"})
Pagination
Slink allows you to elegantly iterate most style of paged APIs. As example, we can implement one of the most common pagination patterns, an an offseted pagination API. With such an API, you request an offset of the dataset with some limit on the size of the data returned:
class OffsettedPager:
def __init__(self, results_per_page=5) -> None:
self.results_per_page = results_per_page
self.startAt = 0
self.total = None # needs to be determined
def pages(self, url):
while self.total is None or self.startAt < self.total:
# yield a tuple of the next url and any parameters to be added to the original request
yield url, {"startAt": self.startAt, "results_per_page": self.maxCount}
self.startAt += self.results_per_page
def process(self, response):
# update the Pager with any response variables; usually either info about the next page or the total number of pages
self.total = response.json()["total"]
You can then use the pager with the @get_pages
decorator to iterate through the pages:
class PagedApi(Api):
@get_pages("rest/api/3/pages", pager=OffsetedPager())
def get_paginated(self)
# our data field in the json result just contains a list of ints, but they could be a much more complicated object
for value in self.response.json()["data"]:
yield int(value)
api = PagedApi(base_url=base_url)
all_results = [e for e in api.get_paginated()]
Another example would be a pagination API where there is a next link:
class LinkedPager:
def __init__(self) -> None:
self.next_url = None
def pages(self, url):
yield url, {} # first page is just the raw url
while self.next_url:
yield self.next_url, {}
def process(self, response):
self.next_url = response.json()["links"].get("next")
Note in both cases, iteration can be stopped early by simply stopping calling the endpoint, ie the following will make any more requests once it finds the required value:
for e in api.get_paginated():
if e == value_to_find:
break
Limitations and TODOs
- error handling and robustness
- retry patterns
- put, patch, del
- supporting other http client libraries, including async ones
Project details
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 slink_api-0.1.2.tar.gz
.
File metadata
- Download URL: slink_api-0.1.2.tar.gz
- Upload date:
- Size: 3.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.4.0 CPython/3.11.2 Linux/5.15.0-1034-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85f86074050d11eefe57c4b05a1f4a84d4965f0c438a039450505f05ba3f413b |
|
MD5 | 8bb93881a688e4cc11f9b6a3fa1c1163 |
|
BLAKE2b-256 | fea6f6a19bca4403a862fd06b87372471ddd76c75880e70ebf3300c24b475ade |
File details
Details for the file slink_api-0.1.2-py3-none-any.whl
.
File metadata
- Download URL: slink_api-0.1.2-py3-none-any.whl
- Upload date:
- Size: 3.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.4.0 CPython/3.11.2 Linux/5.15.0-1034-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85a58a2bb04bfdd10684d1fae3703a42ef30071aeb52f1c30e6df9a38a28adbe |
|
MD5 | 6e3b6cedd7e9a3b8836eddeac0dd29fe |
|
BLAKE2b-256 | 30033533c576dc383814a539be2522e0277516249332d1f11537239222ffed93 |