Pre Hooking / Post Hooking¶
In ahttp_client, hooking means refining data before and after receiving a HTTP request. A hooking supports session unit hooking and request unit hooking.
A hooking is used as follows.
- Before Hook (Pre-request):
Setup the required HTTP-Compoenent (ex. authorization)
Vaildate that the correct arguments are in.
- After Hook (Post-request)
Parses data in raw form to a data class.
Act based on HTTP status code
Session Hooking¶
A Session unit hooking is created by overridding a method.
1class GithubService(Session):
2 def __init__(self, token: str):
3 self._token = token # Private Attribute
4 super().__init__("https://api.github.com")
5
6 # overridding before_hook method
7 async def before_hook(self, req_obj: RequestCore, path: str):
8 req_obj.headers["Authorization"] = self._token
9 req_obj.headers["Accepts"] = "application/vnd.github+json;"
10 return req_obj, path
11
12 # overridding after_hook method
13 async def after_hook(self, response: aiohttp.ClientResponse):
14 if response.status_code != 200:
15 raise HTTPException()
16 return response
17
18 @request("GET", "/users/{user}/repos")
19 def list_repositories(
20 self, user: Annotated[str, Path]
21 ) -> dict[str, Any]:
22 return await response.json()
A Github Service object are defined by overriding before_hook and after_hook.
Store the token required for authentication as a private attribute and insert it in header in before_hook. When a method on a GithubService object is called, such as list_repositories method, before_hook method is called first to insert the necessary HTTP compoenents.
After finishing the HTTP request, the after_hook method is called to check HTTP status code. If the HTTP status code is not 200(OK), a HTTPException(A predefined exception) is raised.
Request Hooking¶
A request unit hooking is created using the decorating method.
1token = "GITHUB TOKEN"
2
3@Session.single_session(base_url="https://api.github.com")
4@request("GET", "/repos/{user}/{repo}/topics", directly_response=True)
5def repository_topic(
6 self,
7 user: Annotated[str, Path],
8 repo: Annotated[str, Path]
9) -> list[str]:
10 pass
11
12# before_hook method
13@repository_topic.before_hook
14async def before_hook(self, req_obj: RequestCore, path: str):
15 req_obj.headers["Authorization"] = token
16 req_obj.headers["Accepts"] = "application/vnd.github+json;"
17 return req_obj, path
18
19# after_hook method
20@repository_topic.after_hook
21async def after_hook(self, response: aiohttp.ClientResponse):
22 data = await response.json()
23 return data["names"]
To get the topic of a repository, repository_topic method defined. And defined the hooking with the before_hook decoration method and after_hook decoration method of the repository_topic method.
The before_hook method inserts the necessary compoenents(authorization key…etc) before the HTTP request of the repository_topic method is called.
The after_hook method refines and return the result received in response. It removes unnesscessary keys.