-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added timeout to kwargs for session.request #343
Conversation
Can you please show your current code where you're trying to set timeout, thanks. |
Thanks for providing such a thorough example. I've investigated the issue and the timeout param is indeed not used by Requests in the way we currently set it, after digging a bit deeper into Requests code I was surprised, that Session object provides the ability to get and set almost all request method params as properties except for timeout and allow_redirects which seems super weird to me and isn't documented anywhere. After searching their Github I found several issues where people suggest that those two params should also be supported at session level, but all those issues were closed because Kenneth Reitz believes that we should use adapters for these params as they are more of a network level ones... I personally disagree with this, but anyway... In terms of a suggested PR, I would do it a bit differently, how about we change the code in SyncEngine.create_session from the current: session = requests.Session()
for param in params:
setattr(session, param, params[param])
return session to the following: session = requests.Session
session.request = functools.partialmethod(session.request, **params)
return session() So basically the sync.py file would look like this: """
Synchronous blocking engine that processes requests one by one.
"""
import functools
import requests
from . import BaseEngine
class SyncEngine(BaseEngine):
@staticmethod
def create_session(**params):
session = requests.Session
session.request = functools.partialmethod(session.request, **params)
return session()
def process_bulk_request(self, method, url, container, bulk_params):
return [resource for params in bulk_params for resource in self.request(method, url, params=params)[container]] This way we would also support not only timeout, but also allow_redirects and any other future param they could introduce to the requests method in the future. Thoughts ? |
Having thought about this a bit more, the implementation I suggested above isn't the best idea, as we basically monkey patch the Session.request method and this can cause problems for other libraries that can run simultaneously with Python-Redmine, so we need to think a bit more about it. Maybe create a session object first and then use functools.partial on the bound method instead of functool.partialmethod. |
I think it's a good idea. There is also this suggestion: def construct_request_kwargs(self, method, headers, params, data):
"""
Constructs kwargs that will be used in all requests to Redmine.
:param string method: (required). HTTP verb to use for the request.
:param dict headers: (required). HTTP headers to send with the request.
:param dict params: (required). Params to send in the query string.
:param data: (required). Data to send in the body of the request.
:type data: dict, bytes or file-like object
"""
kwargs = {'data': data or {}, 'params': params or {}, 'headers': headers or {}, **self.requests} # add the keyword arguments passed to Redmine object for the requests module
if method in ('post', 'put', 'patch') and 'Content-Type' not in kwargs['headers']:
kwargs['data'] = json.dumps(data)
kwargs['headers']['Content-Type'] = 'application/json'
return kwargs |
Allright, let's do it your way, but we need to change the order in kwargs dict like this: kwargs = dict(self.requests, **{'data': data or {}, 'params': params or {}, 'headers': headers or {}}) otherwise we can have problems. Would you mind editing your PR ? |
Edited |
Awesome, thanks! |
We can pass optional parameters to Redmine for the requests module. In particular, we can set timeout. But in fact, this timeout was not passed to the requests module, it was simply written to the attribute of the session object.