-
Notifications
You must be signed in to change notification settings - Fork 4
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
Support python requests keyword arguments when making remote calls #1
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you have lots of changes here and I partly disagree with your style in RequestMixin
, see the comments in the diff for more info :).
simple_salesforce/api.py
Outdated
@@ -37,8 +38,60 @@ def _warn_request_deprecation(): | |||
) | |||
|
|||
|
|||
class RequestMixin(object): | |||
def __init__(self, session=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MixIn
-objects generally do not initialize themselves. See examples here: https://github.com/pallets/werkzeug/blob/master/werkzeug/wrappers.py#L1281-L1628
https://github.com/django/django/blob/master/django/contrib/auth/mixins.py
Also this blog post explains some concepts: https://www.ianlewis.org/en/mixins-and-python
Basic idea behind Mixins
(as I understand them), is that you give devs possibilities to add "automatic" features to other classes. In this case, your Mixin
would not implement _call_salesforce
method, it would implement something like request
. The Salesforce
-class would then always use self.request()
-method but depending on the Mixin
inherited, the behaviour would change.
I recommend either renaming this class, or thinking how to implement it in a more "generic" mixin style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I think this is subject to different interpretations, but I see your point. I'll make some changes to simplify the implementation. Using a mixin
may stir the wrong interpretation.
simple_salesforce/api.py
Outdated
@@ -3,6 +3,7 @@ | |||
|
|||
# has to be defined prior to login import | |||
DEFAULT_API_VERSION = '29.0' | |||
TIMEOUT = 60 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to have TIMEOUT
as a global property... If the idea is for the user of Salesforce
to pass the timeout
parameter for requests
, timeout
should be empty by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could also be configurable when you instantiate the Salesforce
class...
simple_salesforce/api.py
Outdated
self.session_id = "sessionId" | ||
self.name = "" | ||
|
||
def _call_salesforce(self, method, url, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You defined timeout
as a global property, it could be also implemented here as an argument for this function. This would make more sense, since you can also provide default value for it.
simple_salesforce/api.py
Outdated
"""Describes all available objects | ||
|
||
Keyword Args: Parameters passed down to requests.request method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case Keyword Args
is actually passed down to requests.Sessions.request
-method, not requests.request
. The documentation for those functions is (almost) the same, but we want to be accurate in our own documentation :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember the backticks for requests.request
. The original documentation also uses * kwargs
instead of Keyword Args
. Is this change intentional?
@@ -774,22 +807,12 @@ def __init__(self, username, password, security_token, sandbox=False, | |||
|
|||
def _exception_handler(result, name=""): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function has been defined as "private" (by Python naming standards). Why not remove it instead of marking it deprecated?
_single_leading_underscore : weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
-- https://www.python.org/dev/peps/pep-0008/#public-and-internal-interfaces
Use one leading underscore only for non-public methods and instance variables.
-- https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
Any backwards compatibility guarantees apply only to public interfaces. Accordingly, it is important that users be able to clearly distinguish between public and internal interfaces.
Documented interfaces are considered public, unless the documentation explicitly declares them to be provisional or internal interfaces exempt from the usual backwards compatibility guarantees. All undocumented interfaces should be assumed to be internal.
-- https://www.python.org/dev/peps/pep-0008/#descriptive-naming-styles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my initial approach but I thought its possible to have someone (mis)use it since its not really private. I would rather go through the deprecation processes.
The project has been forked quite a bit. I would not want to break extensions that exist already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But as PEP8 describes, it is never a guarantee for undocumented private-functions to stay backward compatible. My personal opinion is to remove this function, but the upstream author has, of course, the ultimate say :).
Edit: You can keep the current implementation, or do my proposed change. It is up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll probably remove it anyway. Let's see what the maintainer comments. I'll add a comment about this.
@@ -21,7 +21,7 @@ | |||
def SalesforceLogin( | |||
username=None, password=None, security_token=None, | |||
organizationId=None, sandbox=False, sf_version=DEFAULT_API_VERSION, | |||
proxies=None, session=None, client_id=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did the documented proxies
Keyword Argument vanish?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's one of the requests kwargs and hence part of the requests' documentation.
https://github.com/kennethreitz/requests/blob/master/requests/api.py#L16
simple_salesforce/tests/test_api.py
Outdated
@@ -575,12 +577,14 @@ def setUp(self): | |||
self.mockresult = Mock() | |||
self.mockresult.url = 'http://www.example.com/' | |||
self.mockresult.json.return_value = 'Example Content' | |||
self.mock_mixin = RequestMixin() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this called mock_mixin
when it is, in fact, the real Mixin
-class?
self.mockresult.status_code = 404 | ||
resource_name = 'SpecialContacts' | ||
with self.assertRaises(SalesforceResourceNotFound) as exception: | ||
_exception_handler(result=self.mockresult, name=resource_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you remove the (currently) deprecated _exception_handler
, you can also remove this test and the import for _exception_handler
:).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it there as a regression test. Once it's really deprecated then it can be removed.
simple_salesforce/api.py
Outdated
@@ -38,7 +37,7 @@ def _warn_request_deprecation(): | |||
) | |||
|
|||
|
|||
class RequestMixin(object): | |||
class RequestBase(object): | |||
def __init__(self, session=None): | |||
""" | |||
Mixin class to encapsulate all remote operations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed a docstring here :)
simple_salesforce/api.py
Outdated
@@ -810,7 +809,7 @@ def _exception_handler(result, name=""): | |||
warnings.warn('This global exception handler is deprecated. It has been moved' | |||
'to the RequestMixin class.', DeprecationWarning) | |||
|
|||
mixin = RequestMixin() | |||
mixin = RequestBase() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mixin
name appears here as well.
simple_salesforce/api.py
Outdated
@@ -61,7 +60,7 @@ def _call_salesforce(self, method, url, **kwargs): | |||
} | |||
additional_headers = kwargs.pop('headers', dict()) | |||
headers.update(additional_headers or dict()) | |||
timeout = kwargs.pop('timeout', TIMEOUT) | |||
timeout = kwargs.pop('timeout', 60) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think you should add timeout
as an argument with a default value, make it configurable in the __init__()
-function or keep it unchanged in kwargs
. This timeout = kwargs.pop
looks too verbose and, frankly, ugly here...
simple_salesforce/tests/test_api.py
Outdated
@@ -577,8 +576,8 @@ def setUp(self): | |||
self.mockresult = Mock() | |||
self.mockresult.url = 'http://www.example.com/' | |||
self.mockresult.json.return_value = 'Example Content' | |||
self.mock_mixin = RequestMixin() | |||
self.exec_handler = self.mock_mixin._exception_handler | |||
self.mixin = RequestBase() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mixin
name here as well.
Since this library is heavily dependent on
python requests
for making remote calls, it is necessary to pass down parameters such astimeout
andheader
to requests methods.This PR is related to simple-salesforce#148