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.

Hooking of Session Unit Example
 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.

Hooking of Request Unit Example
 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.