From ee811e17226f788dd4d3c402db3e673745f745eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Fr=C4=85ckowski?= <45572849+kacperf531@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:25:53 +0100 Subject: [PATCH] introduce AccessToken dataclass (#128) --- changelog.md | 1 + examples/agent_rtm_example.py | 6 +++++- examples/agent_web_example.py | 5 ++++- examples/configuration_api_example.py | 4 +++- examples/customer_rtm_example.py | 4 +++- examples/customer_web_example.py | 4 +++- examples/reports_api_example.py | 4 +++- livechat/agent/rtm/api/v33.py | 8 +++++--- livechat/agent/rtm/api/v34.py | 8 +++++--- livechat/agent/rtm/api/v35.py | 8 +++++--- livechat/agent/rtm/api/v36.py | 8 +++++--- livechat/agent/web/api/v33.py | 3 ++- livechat/agent/web/api/v34.py | 3 ++- livechat/agent/web/api/v35.py | 3 ++- livechat/agent/web/api/v36.py | 3 ++- livechat/agent/web/base.py | 3 ++- livechat/configuration/api/v33.py | 5 ++++- livechat/configuration/api/v34.py | 5 ++++- livechat/configuration/api/v35.py | 5 +++-- livechat/configuration/api/v36.py | 5 +++-- livechat/configuration/base.py | 3 ++- livechat/customer/rtm/api/v33.py | 10 ++++++++-- livechat/customer/rtm/api/v34.py | 10 ++++++++-- livechat/customer/rtm/api/v35.py | 10 ++++++++-- livechat/customer/rtm/api/v36.py | 10 ++++++++-- livechat/customer/web/api/v33.py | 3 ++- livechat/customer/web/api/v34.py | 3 ++- livechat/customer/web/api/v35.py | 3 ++- livechat/customer/web/api/v36.py | 3 ++- livechat/customer/web/base.py | 5 +++-- livechat/reports/api/v33.py | 5 ++++- livechat/reports/api/v34.py | 5 ++++- livechat/reports/api/v35.py | 5 ++++- livechat/reports/api/v36.py | 5 ++++- livechat/reports/base.py | 3 ++- livechat/tests/test_customer_rtm_client.py | 4 +++- livechat/utils/http_client.py | 7 +++++-- livechat/utils/structures.py | 19 +++++++++++++++++++ 38 files changed, 156 insertions(+), 52 deletions(-) diff --git a/changelog.md b/changelog.md index b2dc3f2..b6a7e2b 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - Updated outdated packages. - Enhanced error logging for improved troubleshooting: Automatically includes response headers in the log for server errors, providing detailed information (such as x-debug-id) for more effective issue diagnosis. - Enhanced timeouts for the RTM and WEB clients. +- Introduced `AccessToken` structure which allows keeping token type in separate field. Previous way of passing tokens as a string of format `type: token` remains supported for backwards compatibility. ### Bugfixes - Enabled instantiation for `CustomerRtmV36` within the 3.6 version of the Customer RTM API. diff --git a/examples/agent_rtm_example.py b/examples/agent_rtm_example.py index 30f89d0..44e5ecb 100644 --- a/examples/agent_rtm_example.py +++ b/examples/agent_rtm_example.py @@ -1,10 +1,14 @@ ''' Agent RTM client example usage. ''' from livechat.agent.rtm.base import AgentRTM +from livechat.utils.structures import AccessToken, TokenType agent_rtm = AgentRTM.get_client() agent_rtm.open_connection() -agent_rtm.login(token='') + +# token can be also passed as a raw string like `Bearer dal:A420qcNvdVS4cRMJP269GfgT1LA` +agent_rtm.login(token=AccessToken(scheme=TokenType.BEARER, + token='dal:A420qcNvdVS4cRMJP269GfgT1LA')) response = agent_rtm.start_chat(continuous=True) chat_id = response.payload.get('chat_id') thread_id = response.payload.get('thread_id') diff --git a/examples/agent_web_example.py b/examples/agent_web_example.py index 06acf6a..2a9d6a3 100644 --- a/examples/agent_web_example.py +++ b/examples/agent_web_example.py @@ -1,8 +1,11 @@ ''' Agent WEB client example usage. ''' from livechat.agent.web.base import AgentWeb +from livechat.utils.structures import AccessToken, TokenType -agent_web = AgentWeb.get_client(access_token='') +# token can be also passed as a raw string like `Bearer dal:A420qcNvdVS4cRMJP269GfgT1LA` +agent_web = AgentWeb.get_client(access_token=AccessToken( + scheme=TokenType.BEARER, token='dal:A420qcNvdVS4cRMJP269GfgT1LA')) results = agent_web.start_chat(continuous=True) chat_id = results.json().get('chat_id') thread_id = results.json().get('thread_id') diff --git a/examples/configuration_api_example.py b/examples/configuration_api_example.py index df00366..60b8bdb 100644 --- a/examples/configuration_api_example.py +++ b/examples/configuration_api_example.py @@ -1,9 +1,11 @@ ''' Configuration API client example usage. ''' from livechat.configuration.base import ConfigurationApi +from livechat.utils.structures import AccessToken, TokenType # Get list of existing groups. -configuration_api = ConfigurationApi.get_client(token='') +configuration_api = ConfigurationApi.get_client(token=AccessToken( + scheme=TokenType.BEARER, token='dal:A420qcNvdVS4cRMJP269GfgT1LA')) groups = configuration_api.list_groups() print(groups.json()) diff --git a/examples/customer_rtm_example.py b/examples/customer_rtm_example.py index 2e3aa43..f224740 100644 --- a/examples/customer_rtm_example.py +++ b/examples/customer_rtm_example.py @@ -1,11 +1,13 @@ ''' Customer RTM client example usage. ''' from livechat.customer.rtm.base import CustomerRTM +from livechat.utils.structures import AccessToken, TokenType customer_rtm = CustomerRTM.get_client( organization_id='142cf3ad-5d54-4cf6-8ce1-3773d14d7f3f') customer_rtm.open_connection() -customer_rtm.login(token='Bearer ') +customer_rtm.login(token=AccessToken(scheme=TokenType.BEARER, + token='dal:A6420cNvdVS4cRMJP269GfgT1LA')) response = customer_rtm.start_chat(continuous=True) chat_id = response.payload.get('chat_id') thread_id = response.payload.get('thread_id') diff --git a/examples/customer_web_example.py b/examples/customer_web_example.py index bdf7dd4..66e3bbe 100644 --- a/examples/customer_web_example.py +++ b/examples/customer_web_example.py @@ -1,10 +1,12 @@ ''' Customer WEB client example usage. ''' from livechat.customer.web.base import CustomerWeb +from livechat.utils.structures import AccessToken, TokenType customer_web = CustomerWeb.get_client( organization_id='142cf3ad-5d54-4cf6-8ce1-3773d14d7f3f', - access_token='') + access_token=AccessToken(scheme=TokenType.BEARER, + token='dal:A6420cNvdVS4cRMJP269GfgT1LA')) results = customer_web.start_chat(continuous=True) chat_id = results.json().get('chat_id') thread_id = results.json().get('thread_id') diff --git a/examples/reports_api_example.py b/examples/reports_api_example.py index 5bcbbc0..8a514af 100644 --- a/examples/reports_api_example.py +++ b/examples/reports_api_example.py @@ -1,9 +1,11 @@ ''' Reports API client example usage. ''' from livechat.reports.base import ReportsApi +from livechat.utils.structures import AccessToken, TokenType # Get number of chats occured during specified period. -reports_api = ReportsApi.get_client(token='') +reports_api = ReportsApi.get_client(token=AccessToken( + scheme=TokenType.BEARER, token='dal:A420qcNvdVS4cRMJP269GfgT1LA')) chats_occured = reports_api.total_chats(filters={ 'to': '2020-09-14T23:59:59+02:00', 'from': '2020-09-01T00:00:00+02:00' diff --git a/livechat/agent/rtm/api/v33.py b/livechat/agent/rtm/api/v33.py index 4a9766e..b01be40 100644 --- a/livechat/agent/rtm/api/v33.py +++ b/livechat/agent/rtm/api/v33.py @@ -1,9 +1,9 @@ ''' Module containing Agent RTM API client implementation for v3.3. ''' -from typing import Any, Optional +from typing import Any, Optional, Union from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient # pylint: disable=unused-argument, too-many-arguments, invalid-name, redefined-builtin @@ -789,7 +789,7 @@ def unfollow_customer(self, # Status def login(self, - token: str = None, + token: Union[AccessToken, str] = None, timezone: str = None, reconnect: bool = None, push_notifications: dict = None, @@ -822,6 +822,8 @@ def login(self, RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/agent/rtm/api/v34.py b/livechat/agent/rtm/api/v34.py index 7c24903..4c24482 100644 --- a/livechat/agent/rtm/api/v34.py +++ b/livechat/agent/rtm/api/v34.py @@ -1,9 +1,9 @@ ''' Module containing Agent RTM API client implementation for v3.4. ''' -from typing import Any, Optional +from typing import Any, Optional, Union from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient # pylint: disable=unused-argument, too-many-arguments, invalid-name, redefined-builtin @@ -755,7 +755,7 @@ def unfollow_customer(self, # Status def login(self, - token: str = None, + token: Union[AccessToken, str] = None, timezone: str = None, reconnect: bool = None, push_notifications: dict = None, @@ -788,6 +788,8 @@ def login(self, RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/agent/rtm/api/v35.py b/livechat/agent/rtm/api/v35.py index 76cb371..40b80b6 100644 --- a/livechat/agent/rtm/api/v35.py +++ b/livechat/agent/rtm/api/v35.py @@ -1,9 +1,9 @@ ''' Module containing Agent RTM API client implementation for v3.5. ''' -from typing import Any, Optional +from typing import Any, Optional, Union from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient # pylint: disable=unused-argument, too-many-arguments, invalid-name, redefined-builtin @@ -755,7 +755,7 @@ def unfollow_customer(self, # Status def login(self, - token: str = None, + token: Union[AccessToken, str] = None, timezone: str = None, reconnect: bool = None, push_notifications: dict = None, @@ -788,6 +788,8 @@ def login(self, RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/agent/rtm/api/v36.py b/livechat/agent/rtm/api/v36.py index 7885997..9a9478c 100644 --- a/livechat/agent/rtm/api/v36.py +++ b/livechat/agent/rtm/api/v36.py @@ -1,9 +1,9 @@ ''' Module containing Agent RTM API client implementation for v3.6. ''' -from typing import Any, Optional +from typing import Any, Optional, Union from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient # pylint: disable=unused-argument, too-many-arguments, invalid-name, redefined-builtin @@ -727,7 +727,7 @@ def unfollow_customer(self, # Status def login(self, - token: str = None, + token: Union[AccessToken, str] = None, timezone: str = None, reconnect: bool = None, push_notifications: dict = None, @@ -760,6 +760,8 @@ def login(self, RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/agent/web/api/v33.py b/livechat/agent/web/api/v33.py index 0ca4c13..57f1142 100644 --- a/livechat/agent/web/api/v33.py +++ b/livechat/agent/web/api/v33.py @@ -9,12 +9,13 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class AgentWebV33(HttpClient): ''' Agent Web API Class containing methods in version 3.3. ''' def __init__(self, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/agent/web/api/v34.py b/livechat/agent/web/api/v34.py index 03b756b..9317b76 100644 --- a/livechat/agent/web/api/v34.py +++ b/livechat/agent/web/api/v34.py @@ -9,6 +9,7 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken # pylint: disable=R0903 @@ -16,7 +17,7 @@ class AgentWebV34(HttpClient): ''' Agent Web API Class containing methods in version 3.4. ''' def __init__(self, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/agent/web/api/v35.py b/livechat/agent/web/api/v35.py index 6196f78..60a2913 100644 --- a/livechat/agent/web/api/v35.py +++ b/livechat/agent/web/api/v35.py @@ -9,6 +9,7 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken # pylint: disable=R0903 @@ -16,7 +17,7 @@ class AgentWebV35(HttpClient): ''' Agent Web API Class containing methods in version 3.5. ''' def __init__(self, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/agent/web/api/v36.py b/livechat/agent/web/api/v36.py index e25e242..9d36868 100644 --- a/livechat/agent/web/api/v36.py +++ b/livechat/agent/web/api/v36.py @@ -9,6 +9,7 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken # pylint: disable=R0903 @@ -16,7 +17,7 @@ class AgentWebV36(HttpClient): ''' Agent Web API Class containing methods in version 3.6. ''' def __init__(self, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/agent/web/base.py b/livechat/agent/web/base.py index 18f1eb0..9a172aa 100644 --- a/livechat/agent/web/base.py +++ b/livechat/agent/web/base.py @@ -12,6 +12,7 @@ from livechat.agent.web.api.v35 import AgentWebV35 from livechat.agent.web.api.v36 import AgentWebV36 from livechat.config import CONFIG +from livechat.utils.structures import AccessToken stable_version = CONFIG.get('stable') api_url = CONFIG.get('url') @@ -22,7 +23,7 @@ class AgentWeb: API version. ''' @staticmethod def get_client( - access_token: str, + access_token: Union[AccessToken, str], version: str = stable_version, base_url: str = api_url, http2: bool = False, diff --git a/livechat/configuration/api/v33.py b/livechat/configuration/api/v33.py index 9efec0c..e69b819 100644 --- a/livechat/configuration/api/v33.py +++ b/livechat/configuration/api/v33.py @@ -1,15 +1,18 @@ ''' Configuration API module with client class in version 3.3. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ConfigurationApiV33(HttpClient): ''' Configuration API client class in version 3.3. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/configuration/api/v34.py b/livechat/configuration/api/v34.py index 04c3461..9ddf022 100644 --- a/livechat/configuration/api/v34.py +++ b/livechat/configuration/api/v34.py @@ -1,15 +1,18 @@ ''' Configuration API module with client class in version 3.4. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ConfigurationApiV34(HttpClient): ''' Configuration API client class in version 3.4. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/configuration/api/v35.py b/livechat/configuration/api/v35.py index bcf7567..3d9abfe 100644 --- a/livechat/configuration/api/v35.py +++ b/livechat/configuration/api/v35.py @@ -1,17 +1,18 @@ ''' Configuration API module with client class in version 3.5. ''' -from typing import List +from typing import List, Union import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ConfigurationApiV35(HttpClient): ''' Configuration API client class in version 3.5. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/configuration/api/v36.py b/livechat/configuration/api/v36.py index 5a72e2b..1733ed6 100644 --- a/livechat/configuration/api/v36.py +++ b/livechat/configuration/api/v36.py @@ -1,11 +1,12 @@ ''' Configuration API module with client class in version 3.6. ''' -from typing import List +from typing import List, Union import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken # pylint: disable=unused-argument,too-many-arguments,redefined-builtin,invalid-name @@ -13,7 +14,7 @@ class ConfigurationApiV36(HttpClient): ''' Configuration API client class in version 3.6. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/configuration/base.py b/livechat/configuration/base.py index 9b95faa..7dc6e02 100644 --- a/livechat/configuration/base.py +++ b/livechat/configuration/base.py @@ -13,6 +13,7 @@ from livechat.configuration.api.v34 import ConfigurationApiV34 from livechat.configuration.api.v35 import ConfigurationApiV35 from livechat.configuration.api.v36 import ConfigurationApiV36 +from livechat.utils.structures import AccessToken stable_version = CONFIG.get('stable') api_url = CONFIG.get('url') @@ -23,7 +24,7 @@ class ConfigurationApi: API version. ''' @staticmethod def get_client( - token: str, + token: Union[AccessToken, str], version: str = stable_version, base_url: str = api_url, http2: bool = False, diff --git a/livechat/customer/rtm/api/v33.py b/livechat/customer/rtm/api/v33.py index b877b23..00e637f 100644 --- a/livechat/customer/rtm/api/v33.py +++ b/livechat/customer/rtm/api/v33.py @@ -2,8 +2,10 @@ # pylint: disable=C0103,R0903,R0913,W0107,W0231,W0613,W0622 +from typing import Optional, Union + from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient @@ -492,7 +494,9 @@ def get_customer(self, payload: dict = None) -> RtmResponse: # Status - def login(self, token: str = None, payload: dict = None) -> RtmResponse: + def login(self, + token: Optional[Union[AccessToken, str]] = None, + payload: dict = None) -> RtmResponse: ''' Logs in customer. Args: @@ -504,6 +508,8 @@ def login(self, token: str = None, payload: dict = None) -> RtmResponse: RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/customer/rtm/api/v34.py b/livechat/customer/rtm/api/v34.py index b61a2e3..0a0ed7c 100644 --- a/livechat/customer/rtm/api/v34.py +++ b/livechat/customer/rtm/api/v34.py @@ -2,8 +2,10 @@ # pylint: disable=C0103,R0903,R0913,W0107,W0231,W0613,W0622 +from typing import Optional, Union + from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient @@ -492,7 +494,9 @@ def get_customer(self, payload: dict = None) -> RtmResponse: # Status - def login(self, token: str = None, payload: dict = None) -> RtmResponse: + def login(self, + token: Optional[Union[AccessToken, str]] = None, + payload: dict = None) -> RtmResponse: ''' Logs in customer. Args: @@ -504,6 +508,8 @@ def login(self, token: str = None, payload: dict = None) -> RtmResponse: RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/customer/rtm/api/v35.py b/livechat/customer/rtm/api/v35.py index 563b3d0..3ed73dc 100644 --- a/livechat/customer/rtm/api/v35.py +++ b/livechat/customer/rtm/api/v35.py @@ -2,8 +2,10 @@ # pylint: disable=C0103,R0903,R0913,W0107,W0231,W0613,W0622 +from typing import Optional, Union + from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient @@ -492,7 +494,9 @@ def get_customer(self, payload: dict = None) -> RtmResponse: # Status - def login(self, token: str = None, payload: dict = None) -> RtmResponse: + def login(self, + token: Optional[Union[AccessToken, str]] = None, + payload: dict = None) -> RtmResponse: ''' Logs in customer. Args: @@ -504,6 +508,8 @@ def login(self, token: str = None, payload: dict = None) -> RtmResponse: RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/customer/rtm/api/v36.py b/livechat/customer/rtm/api/v36.py index 6255605..bafcbf0 100644 --- a/livechat/customer/rtm/api/v36.py +++ b/livechat/customer/rtm/api/v36.py @@ -2,8 +2,10 @@ # pylint: disable=C0103,R0903,R0913,W0107,W0231,W0613,W0622 +from typing import Optional, Union + from livechat.utils.helpers import prepare_payload -from livechat.utils.structures import RtmResponse +from livechat.utils.structures import AccessToken, RtmResponse from livechat.utils.ws_client import WebsocketClient @@ -492,7 +494,9 @@ def get_customer(self, payload: dict = None) -> RtmResponse: # Status - def login(self, token: str = None, payload: dict = None) -> RtmResponse: + def login(self, + token: Optional[Union[AccessToken, str]] = None, + payload: dict = None) -> RtmResponse: ''' Logs in customer. Args: @@ -504,6 +508,8 @@ def login(self, token: str = None, payload: dict = None) -> RtmResponse: RtmResponse: RTM response structure (`request_id`, `action`, `type`, `success` and `payload` properties) ''' + if token: + token = str(token) if payload is None: payload = prepare_payload(locals()) return self.ws.send({'action': 'login', 'payload': payload}) diff --git a/livechat/customer/web/api/v33.py b/livechat/customer/web/api/v33.py index 7403c42..4ddcc75 100644 --- a/livechat/customer/web/api/v33.py +++ b/livechat/customer/web/api/v33.py @@ -7,13 +7,14 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class CustomerWebV33(HttpClient): ''' Customer Web API Class containing methods in version 3.3. ''' def __init__(self, license_id: int, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/customer/web/api/v34.py b/livechat/customer/web/api/v34.py index c6b54ff..3b1020b 100644 --- a/livechat/customer/web/api/v34.py +++ b/livechat/customer/web/api/v34.py @@ -7,13 +7,14 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class CustomerWebV34(HttpClient): ''' Customer Web API Class containing methods in version 3.4. ''' def __init__(self, organization_id: str, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/customer/web/api/v35.py b/livechat/customer/web/api/v35.py index dd63d73..6e07b8a 100644 --- a/livechat/customer/web/api/v35.py +++ b/livechat/customer/web/api/v35.py @@ -7,13 +7,14 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class CustomerWebV35(HttpClient): ''' Customer Web API Class containing methods in version 3.5. ''' def __init__(self, organization_id: str, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/customer/web/api/v36.py b/livechat/customer/web/api/v36.py index 401aa58..e7d303e 100644 --- a/livechat/customer/web/api/v36.py +++ b/livechat/customer/web/api/v36.py @@ -7,13 +7,14 @@ from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class CustomerWebV36(HttpClient): ''' Customer Web API Class containing methods in version 3.6. ''' def __init__(self, organization_id: str, - access_token: str, + access_token: typing.Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/customer/web/base.py b/livechat/customer/web/base.py index a403f24..dee887d 100644 --- a/livechat/customer/web/base.py +++ b/livechat/customer/web/base.py @@ -3,7 +3,7 @@ # pylint: disable=W0613,R0913,W0622,C0103 from __future__ import annotations -from typing import Union +from typing import Optional, Union import httpx @@ -12,6 +12,7 @@ from livechat.customer.web.api.v34 import CustomerWebV34 from livechat.customer.web.api.v35 import CustomerWebV35 from livechat.customer.web.api.v36 import CustomerWebV36 +from livechat.utils.structures import AccessToken stable_version = CONFIG.get('stable') api_url = CONFIG.get('url') @@ -24,7 +25,7 @@ class CustomerWeb: @staticmethod def get_client( license_id: int = None, - access_token: str = None, + access_token: Optional[Union[AccessToken, str]] = None, version: str = stable_version, base_url: str = api_url, http2: bool = False, diff --git a/livechat/reports/api/v33.py b/livechat/reports/api/v33.py index 56d96a8..8a5c924 100644 --- a/livechat/reports/api/v33.py +++ b/livechat/reports/api/v33.py @@ -1,15 +1,18 @@ ''' Reports API module with client class in version 3.3. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ReportsApiV33(HttpClient): ''' Reports API client class in version 3.3. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/reports/api/v34.py b/livechat/reports/api/v34.py index 94c4765..0b02968 100644 --- a/livechat/reports/api/v34.py +++ b/livechat/reports/api/v34.py @@ -1,15 +1,18 @@ ''' Reports API module with client class in version 3.4. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ReportsApiV34(HttpClient): ''' Reports API client class in version 3.4. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/reports/api/v35.py b/livechat/reports/api/v35.py index caa3566..86c555a 100644 --- a/livechat/reports/api/v35.py +++ b/livechat/reports/api/v35.py @@ -1,15 +1,18 @@ ''' Reports API module with client class in version 3.5. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ReportsApiV35(HttpClient): ''' Reports API client class in version 3.5. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/reports/api/v36.py b/livechat/reports/api/v36.py index 9998d4f..d919b3d 100644 --- a/livechat/reports/api/v36.py +++ b/livechat/reports/api/v36.py @@ -1,15 +1,18 @@ ''' Reports API module with client class in version 3.6. ''' +from typing import Union + import httpx from livechat.utils.helpers import prepare_payload from livechat.utils.http_client import HttpClient +from livechat.utils.structures import AccessToken class ReportsApiV36(HttpClient): ''' Reports API client class in version 3.6. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, diff --git a/livechat/reports/base.py b/livechat/reports/base.py index 5ed134e..a00c39a 100644 --- a/livechat/reports/base.py +++ b/livechat/reports/base.py @@ -14,6 +14,7 @@ from livechat.reports.api.v34 import ReportsApiV34 from livechat.reports.api.v35 import ReportsApiV35 from livechat.reports.api.v36 import ReportsApiV36 +from livechat.utils.structures import AccessToken stable_version = CONFIG.get('stable') api_url = CONFIG.get('url') @@ -24,7 +25,7 @@ class ReportsApi: API version. ''' @staticmethod def get_client( - token: str, + token: Union[AccessToken, str], version: str = stable_version, base_url: str = api_url, http2: bool = False, diff --git a/livechat/tests/test_customer_rtm_client.py b/livechat/tests/test_customer_rtm_client.py index 6143a54..dafcae8 100644 --- a/livechat/tests/test_customer_rtm_client.py +++ b/livechat/tests/test_customer_rtm_client.py @@ -6,6 +6,7 @@ from livechat.config import CONFIG from livechat.customer.rtm.base import CustomerRTM +from livechat.utils.structures import AccessToken, TokenType stable_version = CONFIG.get('stable') dev_version = CONFIG.get('dev') @@ -92,7 +93,8 @@ def test_rtm_response_structure(): ''' Test if returned `RtmResponse` structure contains expected properties. ''' client = CustomerRTM.get_client(organization_id=ORGANIZATION_ID) client.open_connection() - response = client.login(token='Bearer 10386012') + response = client.login( + token=AccessToken(scheme=TokenType.BEARER, token='10386012')) client.close_connection() assert isinstance(response.request_id, str) and len(response.request_id) >= 1 diff --git a/livechat/utils/http_client.py b/livechat/utils/http_client.py index 7b20eb2..580f2c2 100644 --- a/livechat/utils/http_client.py +++ b/livechat/utils/http_client.py @@ -1,15 +1,18 @@ ''' Base module with HTTP client class for session, sending requests and headers manipulation. ''' +from typing import Union + import httpx from livechat.utils.httpx_logger import HttpxLogger +from livechat.utils.structures import AccessToken class HttpClient: ''' HTTP client class for session, sending requests and headers manipulation. ''' def __init__(self, - token: str, + token: Union[AccessToken, str], base_url: str, http2: bool, proxies=None, @@ -19,7 +22,7 @@ def __init__(self, logger = HttpxLogger(disable_logging=disable_logging) self.base_url = base_url self.session = httpx.Client(http2=http2, - headers={'Authorization': token}, + headers={'Authorization': str(token)}, event_hooks={ 'request': [logger.log_request], 'response': [logger.log_response] diff --git a/livechat/utils/structures.py b/livechat/utils/structures.py index d1f66fd..c0835f2 100644 --- a/livechat/utils/structures.py +++ b/livechat/utils/structures.py @@ -1,5 +1,8 @@ ''' Module containing structures. ''' +from dataclasses import dataclass +from enum import Enum + class RtmResponse: ''' RTM response structure class. ''' @@ -30,3 +33,19 @@ def success(self) -> bool: def payload(self) -> dict: ''' `payload` from the RTM response. ''' return self.rtm_response.get('payload') + + +class TokenType(Enum): + ''' Token type enum class. ''' + BEARER = 'Bearer' + BASIC = 'Basic' + + +@dataclass +class AccessToken: + ''' Access token structure class. ''' + token: str + scheme: TokenType + + def __str__(self) -> str: + return f'{self.scheme.value} {self.token}'