From 81dfbdfb8e1544d2d6af985b443184a781778889 Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 30 Jul 2020 19:49:54 +0200 Subject: [PATCH] Added timeout_session, made inara use it timeout_session provides two things, TimeoutAdapter, a HTTP adapter subclass that automatically adds timeouts to all requests, and new_session, which automatically creates a request.Session with the adapter in the correct place. --- PLUGINS.md | 3 +++ plugins/inara.py | 3 ++- timeout_session.py | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 timeout_session.py diff --git a/PLUGINS.md b/PLUGINS.md index 8a43bf6f..8e1a8d77 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -47,6 +47,9 @@ breaking with future code changes.** `from monitor import gamerunning` - in case a plugin needs to know if we think the game is running. + +`import timeout_session` - provides a method called `new_session` that creates a requests.session with a default timeout +on all requests. Recommended to reduce noise in HTTP requests ```python diff --git a/plugins/inara.py b/plugins/inara.py index 5a253bb5..5cd381c0 100644 --- a/plugins/inara.py +++ b/plugins/inara.py @@ -21,6 +21,7 @@ import myNotebook as nb from config import appname, applongname, appversion, config import plug +import timeout_session logger = logging.getLogger(appname) if TYPE_CHECKING: @@ -34,7 +35,7 @@ CREDIT_RATIO = 1.05 # Update credits if they change by 5% over the course of a this: Any = sys.modules[__name__] # For holding module globals -this.session = requests.Session() +this.session = timeout_session.new_session() this.queue = Queue() # Items to be sent to Inara by worker thread this.lastlocation = None # eventData from the last Commander's Flight Log event this.lastship = None # eventData from the last addCommanderShip or setCommanderShip event diff --git a/timeout_session.py b/timeout_session.py new file mode 100644 index 00000000..dea65dfa --- /dev/null +++ b/timeout_session.py @@ -0,0 +1,40 @@ + +import requests +from requests.adapters import HTTPAdapter + +REQUEST_TIMEOUT = 10 # reasonable timeout that all HTTP requests should use + + +class TimeoutAdapter(HTTPAdapter): + """ + TimeoutAdapter is an HTTP Adapter that enforces an overridable default timeout on HTTP requests. + """ + def __init__(self, timeout, *args, **kwargs): + self.default_timeout = timeout + if kwargs.get("timeout") is not None: + del kwargs["timeout"] + + super().__init__(*args, **kwargs) + + def send(self, *args, **kwargs): + if kwargs["timeout"] is None: + kwargs["timeout"] = self.default_timeout + + super().send(*args, **kwargs) + + +def new_session(timeout: int = REQUEST_TIMEOUT, session: requests.Session = None) -> requests.Session: + """ + new_session creates a new requests.Session and overrides the default HTTPAdapter with a TimeoutAdapter. + + :param timeout: the timeout to set the TimeoutAdapter to, defaults to REQUEST_TIMEOUT + :param session: the Session object to attach the Adapter to, defaults to a new session + :return: The created Session + """ + if session is None: + session = requests.Session() + + adapter = TimeoutAdapter(timeout) + session.mount("http://", adapter) + session.mount("https://", adapter) + return session