Skip to content

Commit

Permalink
Merge pull request #125 from livechat/API-13060/Configurable_timeouts
Browse files Browse the repository at this point in the history
Enhanced timeouts for the WebsocketClient
  • Loading branch information
marcindebski authored Jan 15, 2024
2 parents 2332669 + 138f9d7 commit 1e5b0d2
Show file tree
Hide file tree
Showing 32 changed files with 269 additions and 91 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
### Changed
- 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.

### Bugfixes
- Enabled instantiation for `CustomerRtmV36` within the 3.6 version of the Customer RTM API.
Expand Down
29 changes: 25 additions & 4 deletions livechat/agent/rtm/api/v33.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,26 @@ class AgentRtmV33:
def __init__(self, url: str):
self.ws = WebsocketClient(url=f'wss://{url}/v3.3/agent/rtm/ws')

def open_connection(self) -> None:
''' Opens WebSocket connection. '''
self.ws.open()
def open_connection(self,
origin: dict = None,
ping_timeout: float = 3,
ping_interval: float = 5,
ws_conn_timeout: float = 10,
keep_alive: bool = True) -> None:
''' Opens WebSocket connection.
Args:
origin (dict): Specifies origin while creating websocket connection.
ping_timeout (int or float): timeout (in seconds) if the pong message is not received,
by default sets to 3 seconds.
ping_interval (int or float): automatically sends "ping" command every specified period (in seconds).
If set to 0, no ping is sent periodically, by default sets to 5 seconds.
ws_conn_timeout (int or float): timeout (in seconds) to wait for WebSocket connection,
by default sets to 10 seconds.
keep_alive(bool): Bool which states if connection should be kept, by default sets to `True`.
'''
self.ws.open(origin, ping_timeout, ping_interval, ws_conn_timeout,
keep_alive)

def close_connection(self) -> None:
''' Closes WebSocket connection. '''
Expand Down Expand Up @@ -378,7 +395,11 @@ def send_event(self,
opts['author_id'] = author_id
if payload is None:
payload = prepare_payload(locals())
return self.ws.send({'action': 'send_event', 'payload': payload, **opts})
return self.ws.send({
'action': 'send_event',
'payload': payload,
**opts
})

def send_rich_message_postback(self,
chat_id: str = None,
Expand Down
29 changes: 25 additions & 4 deletions livechat/agent/rtm/api/v34.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,26 @@ class AgentRtmV34:
def __init__(self, url: str):
self.ws = WebsocketClient(url=f'wss://{url}/v3.4/agent/rtm/ws')

def open_connection(self) -> None:
''' Opens WebSocket connection. '''
self.ws.open()
def open_connection(self,
origin: dict = None,
ping_timeout: float = 3,
ping_interval: float = 5,
ws_conn_timeout: float = 10,
keep_alive: bool = True) -> None:
''' Opens WebSocket connection.
Args:
origin (dict): Specifies origin while creating websocket connection.
ping_timeout (int or float): timeout (in seconds) if the pong message is not received,
by default sets to 3 seconds.
ping_interval (int or float): automatically sends "ping" command every specified period (in seconds).
If set to 0, no ping is sent periodically, by default sets to 5 seconds.
ws_conn_timeout (int or float): timeout (in seconds) to wait for WebSocket connection,
by default sets to 10 seconds.
keep_alive(bool): Bool which states if connection should be kept, by default sets to `True`.
'''
self.ws.open(origin, ping_timeout, ping_interval, ws_conn_timeout,
keep_alive)

def close_connection(self) -> None:
''' Closes WebSocket connection. '''
Expand Down Expand Up @@ -344,7 +361,11 @@ def send_event(self,
opts['author_id'] = author_id
if payload is None:
payload = prepare_payload(locals())
return self.ws.send({'action': 'send_event', 'payload': payload, **opts})
return self.ws.send({
'action': 'send_event',
'payload': payload,
**opts
})

def send_rich_message_postback(self,
chat_id: str = None,
Expand Down
29 changes: 25 additions & 4 deletions livechat/agent/rtm/api/v35.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,26 @@ class AgentRtmV35:
def __init__(self, url: str):
self.ws = WebsocketClient(url=f'wss://{url}/v3.5/agent/rtm/ws')

def open_connection(self) -> None:
''' Opens WebSocket connection. '''
self.ws.open()
def open_connection(self,
origin: dict = None,
ping_timeout: float = 3,
ping_interval: float = 5,
ws_conn_timeout: float = 10,
keep_alive: bool = True) -> None:
''' Opens WebSocket connection.
Args:
origin (dict): Specifies origin while creating websocket connection.
ping_timeout (int or float): timeout (in seconds) if the pong message is not received,
by default sets to 3 seconds.
ping_interval (int or float): automatically sends "ping" command every specified period (in seconds).
If set to 0, no ping is sent periodically, by default sets to 5 seconds.
ws_conn_timeout (int or float): timeout (in seconds) to wait for WebSocket connection,
by default sets to 10 seconds.
keep_alive(bool): Bool which states if connection should be kept, by default sets to `True`.
'''
self.ws.open(origin, ping_timeout, ping_interval, ws_conn_timeout,
keep_alive)

def close_connection(self) -> None:
''' Closes WebSocket connection. '''
Expand Down Expand Up @@ -344,7 +361,11 @@ def send_event(self,
opts['author_id'] = author_id
if payload is None:
payload = prepare_payload(locals())
return self.ws.send({'action': 'send_event', 'payload': payload, **opts})
return self.ws.send({
'action': 'send_event',
'payload': payload,
**opts
})

def send_rich_message_postback(self,
chat_id: str = None,
Expand Down
23 changes: 20 additions & 3 deletions livechat/agent/rtm/api/v36.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,26 @@ class AgentRtmV36:
def __init__(self, url: str):
self.ws = WebsocketClient(url=f'wss://{url}/v3.6/agent/rtm/ws')

def open_connection(self) -> None:
''' Opens WebSocket connection. '''
self.ws.open()
def open_connection(self,
origin: dict = None,
ping_timeout: float = 3,
ping_interval: float = 5,
ws_conn_timeout: float = 10,
keep_alive: bool = True) -> None:
''' Opens WebSocket connection.
Args:
origin (dict): Specifies origin while creating websocket connection.
ping_timeout (int or float): timeout (in seconds) if the pong message is not received,
by default sets to 3 seconds.
ping_interval (int or float): automatically sends "ping" command every specified period (in seconds).
If set to 0, no ping is sent periodically, by default sets to 5 seconds.
ws_conn_timeout (int or float): timeout (in seconds) to wait for WebSocket connection,
by default sets to 10 seconds.
keep_alive(bool): Bool which states if connection should be kept, by default sets to `True`.
'''
self.ws.open(origin, ping_timeout, ping_interval, ws_conn_timeout,
keep_alive)

def close_connection(self) -> None:
''' Closes WebSocket connection. '''
Expand Down
5 changes: 3 additions & 2 deletions livechat/agent/web/api/v33.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(access_token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.3/agent/action'

# Chats
Expand Down
5 changes: 3 additions & 2 deletions livechat/agent/web/api/v34.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(access_token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.4/agent/action'

# Chats
Expand Down
5 changes: 3 additions & 2 deletions livechat/agent/web/api/v35.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(access_token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.5/agent/action'

# Chats
Expand Down
5 changes: 3 additions & 2 deletions livechat/agent/web/api/v36.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(access_token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.6/agent/action'

# Chats
Expand Down
13 changes: 9 additions & 4 deletions livechat/agent/web/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from typing import Union

import httpx

from livechat.agent.web.api.v33 import AgentWebV33
from livechat.agent.web.api.v34 import AgentWebV34
from livechat.agent.web.api.v35 import AgentWebV35
Expand All @@ -27,6 +29,7 @@ def get_client(
proxies: dict = None,
verify: bool = True,
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)
) -> Union[AgentWebV33, AgentWebV34, AgentWebV35, AgentWebV36]:
''' Returns client for specific API version.
Expand All @@ -43,6 +46,8 @@ def get_client(
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
(which will disable verification). Defaults to `True`.
disable_logging (bool): indicates if logging should be disabled.
timeout (float): The timeout configuration to use when sending requests.
Defaults to 15 seconds.
Returns:
API client object for specified version.
Expand All @@ -53,16 +58,16 @@ def get_client(
client = {
'3.3':
AgentWebV33(access_token, base_url, http2, proxies, verify,
disable_logging),
disable_logging, timeout),
'3.4':
AgentWebV34(access_token, base_url, http2, proxies, verify,
disable_logging),
disable_logging, timeout),
'3.5':
AgentWebV35(access_token, base_url, http2, proxies, verify,
disable_logging),
disable_logging, timeout),
'3.6':
AgentWebV36(access_token, base_url, http2, proxies, verify,
disable_logging),
disable_logging, timeout),
}.get(version)
if not client:
raise ValueError('Provided version does not exist.')
Expand Down
5 changes: 3 additions & 2 deletions livechat/billing/api/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v1'

# direct_charge
Expand Down
7 changes: 6 additions & 1 deletion livechat/billing/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from __future__ import annotations

import httpx

from livechat.config import CONFIG

from .api import BillingApiV1
Expand All @@ -25,6 +27,7 @@ def get_client(
proxies: dict = None,
verify: bool = True,
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)
) -> BillingApiV1:
''' Returns client for specific Billing API version.
Expand All @@ -41,6 +44,8 @@ def get_client(
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
(which will disable verification). Defaults to `True`.
disable_logging (bool): indicates if logging should be disabled.
timeout (float): The timeout configuration to use when sending requests.
Defaults to 15 seconds.
Returns:
BillingApi: API client object for specified version.
Expand All @@ -51,7 +56,7 @@ def get_client(
client = {
'1':
BillingApiV1(token, base_url, http2, proxies, verify,
disable_logging),
disable_logging, timeout),
}.get(version)
if not client:
raise ValueError('Provided version does not exist.')
Expand Down
5 changes: 3 additions & 2 deletions livechat/configuration/api/v33.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.3/configuration/action'

# Agents
Expand Down
5 changes: 3 additions & 2 deletions livechat/configuration/api/v34.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.4/configuration/action'

# Agents
Expand Down
5 changes: 3 additions & 2 deletions livechat/configuration/api/v35.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.5/configuration/action'

# Agents
Expand Down
5 changes: 3 additions & 2 deletions livechat/configuration/api/v36.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ def __init__(self,
http2: bool,
proxies=None,
verify: bool = True,
disable_logging: bool = False):
disable_logging: bool = False,
timeout: float = httpx.Timeout(15)):
super().__init__(token, base_url, http2, proxies, verify,
disable_logging)
disable_logging, timeout)
self.api_url = f'https://{base_url}/v3.6/configuration/action'

# Agents
Expand Down
Loading

0 comments on commit 1e5b0d2

Please sign in to comment.