Skip to content

Commit ea26bdc

Browse files
committed
Several fixes and documentation
1 parent 7d12f9b commit ea26bdc

File tree

5 files changed

+76
-9
lines changed

5 files changed

+76
-9
lines changed

README.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs/index.md

apiclient/core.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@
1010

1111

1212
class BaseRouter:
13-
def _initialize(self):
13+
"""Base class implementing 'route mounting' functionality"""
14+
def _initialize(self, **kwargs):
15+
"""Looks for routers and routes and mount them
16+
17+
Also handles calling the _pre_init and _post_init hooks
18+
"""
19+
self._pre_init()
1420
self_is_router = isinstance(self, APIRouter)
1521
client = self.client if self_is_router else self
1622
for attr_name, attr_type in getattr(self, '__annotations__', {}).items():
@@ -21,11 +27,14 @@ def _initialize(self):
2127
attr = getattr(self, attr_name)
2228
if isinstance(attr, Endpoint):
2329
attr.register(router=self)
24-
self._post_init()
30+
self._post_init(**kwargs)
31+
32+
def _pre_init(self):
33+
pass
2534

2635
def _post_init(self, **kwargs):
2736
if kwargs:
28-
raise RuntimeError("Unexpected arguments passed!")
37+
raise RuntimeError("Unexpected argument {} passed!".format(next(iter(kwargs.keys()))))
2938

3039

3140
class APIClient(BaseRouter):
@@ -48,6 +57,7 @@ class APIRouter(BaseRouter):
4857
def __init__(self, client: APIClient):
4958
self.client = client
5059
self.session = client.session
60+
self.base_url = client.base_url
5161
self._post_processors = []
5262
self._initialize()
5363

@@ -76,16 +86,18 @@ def register(self, *, router: APIRouter):
7686
def __call__(self, *args, **kwargs):
7787
request = self.callback(self.router, *args, **kwargs)
7888

79-
httpx_request = self.session.build_request(**request.dict())
89+
httpx_request = self.session.build_request(**request.dict(router=self.router))
8090

8191
if inspect.iscoroutinefunction(self.session.send):
8292
return self.async_call(httpx_request)
8393
return self.sync_call(httpx_request)
8494

8595
def sync_call(self, httpx_request):
8696
response = self.session.send(httpx_request)
97+
print(self.post_processors, response)
8798
for post_processor in self.post_processors:
8899
response = post_processor(response)
100+
print(response)
89101
return response
90102

91103
async def async_call(self, httpx_request):

apiclient/methods.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ def dict(self, *, router: APIRouter):
3030
if self.absolute_url:
3131
url = self.url
3232
elif self.from_base_url:
33-
url = router.client.base_url + self.url
33+
url = router.base_url + self.url
3434
else:
35-
url = router.client.base_url + router.path + self.url
35+
url = router.base_url + getattr(router, 'path', '') + self.url
3636
req_dict['url'] = url
3737

3838
return req_dict

docs/index.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Introduction
2+
3+
If you've ever tried to make an API wrapper
4+
you probably know that the code written can
5+
only be used as sync or async, well, not anymore.
6+
7+
## Features
8+
9+
- **Lightweight**: Extremely lightweight and minimal
10+
- **Easy to use**: Implement features in no time with the
11+
- **Async and blocking**: Provides both async and blocking calls
12+
- **Test without a server**: Since the library internally uses httpx, it can be used to test itself using an `ASGI` or `WSGI` application.
13+
- **DRY**: _Don't repeat yourself_, helps avoid code duplication and write reusable code
14+
- **Routing**: An `APIRouter` class with simliar API to `APIClient`
15+
- **Modular**: Create reusable routers that can be added to any client, independant of each other
16+
17+
## Example Usage
18+
19+
```py
20+
21+
from apiclient import APIClient, endpoint, Post
22+
23+
class CodeExecClient(APIClient):
24+
base_url = "https://pathtomysite.com/api/1.0" # Note the missing / suffix
25+
@endpoint
26+
def run(self, language:str, code:str):
27+
# Do any processing with the data here!
28+
# Also note the / prefix in the url
29+
return Post("/execute", params={'lang':language, 'code':code})
30+
31+
```
32+
33+
## Documentation is under works

mkdocs.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
site_name: Instant API Client
2+
site_description: Create API wrappers/clients in minutes, enjoying both blocking and async interfaces from one codebase!
3+
4+
theme:
5+
name: material
6+
palette:
7+
scheme: slate
8+
primary: teal
9+
accent: purple
10+
11+
12+
markdown_extensions:
13+
- pymdownx.highlight
14+
- pymdownx.superfences
15+
16+
17+
plugins:
18+
- search
19+
- mkdocstrings:
20+
handler: python
21+
22+
nav:
23+
- Introduction: index.md
24+

0 commit comments

Comments
 (0)