Implementing of own synchronous clientΒΆ

Requires requests package to be installed.

  1"""
  2Here we gonna create our own client
  3with one of web lib
  4that we, may be, want to use
  5instead of ready to use clients.
  6
  7Used `requests` package for this goal.
  8"""
  9
 10import logging
 11from typing import (
 12    Any,
 13    Optional
 14)
 15
 16import requests
 17
 18from freedictionaryapi.clients.base_sync_client import BaseDictionaryApiClient
 19# or `from freedictionaryapi.clients import BaseDictionaryApiClient`
 20from freedictionaryapi.errors import DictionaryApiError
 21# or `from freedictionaryapi import DictionaryApiError`
 22from freedictionaryapi.languages import (
 23    LanguageCodes,
 24    DEFAULT_LANGUAGE_CODE
 25)
 26
 27logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 28logger = logging.getLogger(__name__)
 29
 30
 31# So, lets implement:
 32# 1. simple class with requests
 33# 2. class with requests.Session
 34
 35
 36class SimpleOwnDictionaryApiClient(BaseDictionaryApiClient):
 37
 38    def fetch_api_response(self, url: str) -> tuple[int, Any]:
 39        # implement abstract method
 40        # from docs we see
 41        # '''
 42        # ...
 43        # The most important part is returning - method must return tuple of:
 44        #     1. integer code of the API response;
 45        #     2. python object loaded from API response with JSON decoding.
 46        # ...
 47        # '''
 48
 49        response = requests.get(url)
 50        response_status_code = response.status_code
 51        json_response = response.json()
 52
 53        return (response_status_code, json_response)
 54
 55
 56class NotSoSimpleOwnDictionaryApiClient(BaseDictionaryApiClient):
 57
 58    def __init__(self, default_language_code: LanguageCodes = DEFAULT_LANGUAGE_CODE, *,
 59                 session: Optional[requests.Session] = None) -> None:
 60        super().__init__(default_language_code)
 61
 62        if session is None:
 63            self._session = requests.session()
 64        else:
 65            self._session = session
 66
 67            if not isinstance(self._session, requests.Session):
 68                raise TypeError('I`m expecting to get session with `requests.Session` type...')
 69
 70    def __enter__(self) -> 'NotSoSimpleOwnDictionaryApiClient':
 71        return self
 72
 73    def __exit__(self, exc_type, exc_val, exc_tb):
 74        self.close()
 75
 76        logger.info('Session has been closed')
 77
 78    def fetch_api_response(self, url: str) -> tuple[int, Any]:
 79        # implement abstract method
 80        # from docs we see
 81        # '''
 82        # ...
 83        # The most important part is returning - method must return tuple of:
 84        #     1. integer code of the API response;
 85        #     2. python object loaded from API response with JSON decoding.
 86        # ...
 87        # '''
 88
 89        response = self._session.get(url)
 90        response_status_code = response.status_code
 91        json_response = response.json()
 92
 93        return (response_status_code, json_response)
 94
 95    def close(self) -> None:
 96        self._session.close()
 97
 98
 99def main():
100    # lets test our clients
101
102    # # simple one
103    simple_client = SimpleOwnDictionaryApiClient()
104    word = ' tests '
105    print('{:*^20}'.format(word))
106    try:
107        parser = simple_client.fetch_parser(word)
108    except DictionaryApiError:
109        logger.error('API error')
110    else:
111        print(f'Definitions: {parser.get_all_definitions()!r}')
112
113    # # and not so simple one
114    with NotSoSimpleOwnDictionaryApiClient() as not_so_simple_client:
115        word = ' program '
116        print('{:*^20}'.format(word))
117        try:
118            parser = not_so_simple_client.fetch_parser(word)
119        except DictionaryApiError:
120            logger.error('API error')
121        else:
122            print(f'Definitions: {parser.get_all_definitions()!r}')
123
124
125if __name__ == '__main__':
126    main()