-
Notifications
You must be signed in to change notification settings - Fork 133
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 requests session to ApiClient #80
base: develop
Are you sure you want to change the base?
Conversation
@seantibor Thank you for your work! We just switched over to using the responses library for better and cleaner testing. I'm going to leave this PR open but, my guess is that when you merge develop in to your branch, this will no longer be relevant. That being said thank you for your effort in trying to improve this library! |
I was able to accept all of the incoming changes from develop, particularly in test_util. The util.ApiClient uses a session object from requests now, which should save some resources and time when making large numbers of requests sequentially. |
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.
Thanks for taking the time to add this in and it's a great start! I added a suggestion that would make this a bit more flexible and retain backwards compatibility for those who need it.
Could I also trouble you to write some tests for this? Thank you!
zoomus/util.py
Outdated
@@ -30,6 +30,7 @@ def __init__(self, base_uri=None, timeout=15, **kwargs): | |||
self.timeout = timeout | |||
for k, v in kwargs.items(): | |||
setattr(self, k, v) | |||
self.session = requests.Session() |
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 is a great start! For the sake of flexibility can we make this a configurable option and have the ability to start a new session. I.e. Let's make the method signature
def __init__(self, base_uri=None, timeout=15, use_session=True, **kwargs):
Then we can do something like
self.session = requests.Session() ? use_session : requests
This should then either use the Session
or requests
depending on what was requested.
We'd then also want to add a new method called something like new_session
or something like that so that if someone needs a new session for some reason, they could do that without having to reinstantiate the ApiClient
.
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.
Perhaps it might even be better if this let the client be used as a context manager, rather than having to explicitly say use_session
. So then, reusing an example from the readme, a user could do something like:
with ApiClient() as client:
users = client.user.list().content
meetings = {user["id"]: client.meeting.list(user_id=user["id"]).content for user in users}
This could be implemented by adding basically
def __enter__(self):
self.session = requests.Session()
def __exit__(self):
self.session = None
And the individual get
/post
, etc, optionally call the client if it's present.
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.
Even better! Great idea!
Ok -- this should be working now. I've implemented the context manager methods, added tests for the context manager and methods, but I have not added tests for the v2 client yet. Do we want to write V2 client context manager tests too? I've added a lot of tests for the context manager code so I'm not sure if the value is there. Or we could move them to v2 client calls? |
zoomus/util.py
Outdated
@@ -30,6 +30,7 @@ def __init__(self, base_uri=None, timeout=15, **kwargs): | |||
self.timeout = timeout | |||
for k, v in kwargs.items(): | |||
setattr(self, k, v) | |||
self.session = requests |
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 is a little bit alarming and confusing to see without proper context. I think this probably warrants an explanatory comment, or maybe self.session
could become a property instead? Along the lines of...
@property
def session(self):
"""Provide a session if one is in use; otherwise, provide the requests module directly."""
if self._session is not None:
return self._session
return requests
@session.setter
def session(self, val):
self._session = val
@session.deleter
def session(self):
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.
REALLY fair point. I'll include your suggestions now. This approach seems a lot more sane
Updated session approach to use setter, getter, and deleter property methods. |
Tests passed for all supported Python versions. Would like @prschmid to take a look before confirming merge. |
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.
Thank you for taking this on and for your patience in getting this approved!!! Just ran the tests locally and it looks like some tests are failing -- based on the error that I'm seeing, if you merge in the latest develop to your branch, those tests should fix themselves.
(~/Development/zoomus:[feature/requests-session]) # nosetests .
....................................................................................................................................................................EEEEEEEEEEEE.EEE.....................................................................................S.S......
======================================================================
ERROR: test_api_version_defaults_to_2 (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 91, in test_api_version_defaults_to_2
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_api_key (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 95, in test_can_get_api_key
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_api_secret (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 104, in test_can_get_api_secret
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_meeting_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 113, in test_can_get_meeting_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_phone_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 135, in test_can_get_phone_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_recording_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 129, in test_can_get_recording_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_report_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 117, in test_can_get_report_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_user_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 121, in test_can_get_user_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_get_webinar_component (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 125, in test_can_get_webinar_component
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_set_api_key (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 99, in test_can_set_api_key
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_set_api_secret (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 108, in test_can_set_api_secret
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_can_use_client_with_context (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 139, in test_can_use_client_with_context
with ZoomClient("KEY", "SECRET") as client:
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_init_creates_all_components (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 48, in test_init_creates_all_components
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_init_sets_config (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 20, in test_init_sets_config
client = ZoomClient("KEY", "SECRET")
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
======================================================================
ERROR: test_init_sets_config_with_timeout (tests.zoomus.test_client.ZoomClientTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/prschmid/Development/zoomus/tests/zoomus/test_client.py", line 37, in test_init_sets_config_with_timeout
client = ZoomClient("KEY", "SECRET", timeout=500)
File "/Users/prschmid/Development/zoomus/zoomus/client.py", line 64, in __init__
"token": util.generate_jwt(api_key, api_secret),
File "/Users/prschmid/Development/zoomus/zoomus/util.py", line 286, in generate_jwt
return token.decode("utf-8")
AttributeError: 'str' object has no attribute 'decode'
Name Stmts Miss Branch BrPart Cover
---------------------------------------------------------------------
zoomus/__init__.py 5 0 0 0 100%
zoomus/client.py 46 0 2 0 100%
zoomus/components/__init__.py 2 0 0 0 100%
zoomus/components/base.py 13 0 4 0 100%
zoomus/components/meeting.py 48 0 10 0 100%
zoomus/components/metric.py 22 0 0 0 100%
zoomus/components/past_meeting.py 16 0 0 0 100%
zoomus/components/phone.py 15 0 0 0 100%
zoomus/components/recording.py 34 0 8 0 100%
zoomus/components/report.py 39 0 0 0 100%
zoomus/components/user.py 39 0 0 0 100%
zoomus/components/webinar.py 66 0 10 0 100%
zoomus/util.py 108 1 40 2 98%
---------------------------------------------------------------------
TOTAL 453 1 74 2 99%
----------------------------------------------------------------------
Ran 274 tests in 0.751s
FAILED (SKIP=2, errors=15)
Also, looks like the files don't conform to the black
formatting guidelines. Can I trouble you to also make sure to run black .
when you re-submit your PR? Thanks!
(~/Development/zoomus:[feature/requests-session]) # black . --check
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/phone/test_call_logs.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/phone/test_calling_plans.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/phone/test_numbers_list.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/phone/test_users.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/phone/test_numbers_get.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/past_meeting/test_participants.py
would reformat /Users/prschmid/Development/zoomus/zoomus/components/metric.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/meeting/test_update.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/meeting/test_create.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/components/webinar/test_register.py
would reformat /Users/prschmid/Development/zoomus/tests/zoomus/test_util.py
Oh no! 💥 💔 💥
11 files would be reformatted, 57 files would be left unchanged.
Ok -- I think I got it. I've run black on everything and merged develop. Tests are running against 3.6.13 and passing. Let me know if you need anything else. |
@seantibor Thanks for fixing up those tests! I just verified and they indeed do pass now. I did notice, however, that there still appears to be one file that is in need of formatting
Assuming you are running the same version of black as the repo ( Thanks for dealing with these formatting details! |
Sorry for the many extra commits on this trying to get my pre-commit to work. I finally manually ran black 21.4b and skipped the pre-commit hook that was formatting the test_util.py wrong. I'm not entirely sure why my pre-commit got so messed up but this should bring it back in line. |
Fixes #62 by adding requests session to ApiClient utility instances. This may be a naive approach, so please let me know if we need additional changes to support this.