Skip to content
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

Add an asyncio version of the HttpApi class #168

Closed
wants to merge 13 commits into from

Conversation

Cadair
Copy link
Contributor

@Cadair Cadair commented Jan 3, 2018

This adds a Python 3.5+ async def / await version of the MatrixHttpAPI class. It also adds an import shim to give a nice (i.e. not syntax) error if a user tries to import it on <3.5.

I have asked a couple of people knowledgeable in such things and I expect no issues with having sections of the package to have different Python version requirements than others, as long as it is not imported there will be no trouble.

@Cadair
Copy link
Contributor Author

Cadair commented Jan 3, 2018

This is a version of the code in this repo: https://github.com/opsdroid/connector-matrix (that I am the author of).

matrix_client/_api_asyncio.py Outdated Show resolved Hide resolved
loop.run_until_complete(main())
"""

def __init__(self, base_url, client_session, token=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think being able to pass in a client session is definitely a nice thing, but
in the interest of simplicity, is there any way we could have a default
client_session if none is provided? This would require changing the sdk to
have an optional dependency on aiohttp; are optional dependencies a thing that
exists in python-land?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is the recommended way to create the session is with a context manager. I am not the sure of the best way to handle closing the session if it is created in the constructor of the class.

Copy link
Collaborator

@non-Jedi non-Jedi Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you link me to some docs on the "sessions" you're talking about? Having a hard time understanding what cleanup is necessary. EDIT: nevermind I found it.

Copy link
Collaborator

@non-Jedi non-Jedi Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first example on the first page for using aiohttp client uses ClientSession outside of a context manager, so I think we're okay on that front. Bigger question to me is if we want to tie ourselves to aiohttp as the default or if asks is the better option with the way the ecosystem seems to be leaning away from asyncio and towards curio/trio.

Copy link
Collaborator

@non-Jedi non-Jedi Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I've flip-flopped on this again in the past 10 minutes. We should write the api class as generically as possible so that wrappers at the same abstraction level as MatrixClient can use whatever their preferred coroutine library is with this easily, so given that I think you can use asks with this as is, it's probably pretty good right now..

@non-Jedi
Copy link
Collaborator

I need some tests on this code before I can merge it. I know that's a
complicated request because of how this only works with some versions, but I
don't want to signup to support code so abstracted away from the core of the
library if I won't at least get some sort of warning when I break it by changing
something in the main library.

Copy link
Collaborator

@non-Jedi non-Jedi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also comment about needing tests. Ideally tests should be adapted such that same set of tests that is run against blocking api also runs on this.

method,
path,
content=None,
query_params={},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, this instantiates a single empty dictionary that's reused across all calls
to this method. Probably not what we really want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it was like this in _send in the API class as well. I copy and paste all bugs.

content=None,
query_params={},
headers={},
api_path="/_matrix/client/r0"):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should pull from the same place as MatrixHttpApi gets its default url
path so that we can update that all at once in a single location.


if "Content-Type" not in headers:
headers["Content-Type"] = "application/json"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of this is copy-pasted from MatrixHttpApi. Please move common
functionality out to a helper function rather than duplicating code.

headers["Content-Type"] = "application/json"

if self.token:
query_params["access_token"] = self.token
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This right here is why we need to make sure we're not reusing the same
dictionary between requests.

matrix_client/_api_asyncio.py Outdated Show resolved Hide resolved
import sys

if sys.version_info < (3, 5):
raise ValueError("The asyncio version of the api is only supported on Python 3.5+")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure ValueError is the correct error here, but I'm not sure what the
ideal would be anyways. Figuring it out might not be a worthwhile endeavor given
how often this code-path should be run (never).

@Cadair
Copy link
Contributor Author

Cadair commented Nov 5, 2018

@Zil0 @non-Jedi I have updated this, added tests and cleaned it up. I think it is good to go, if either of you have time to look it over :)

@Cadair
Copy link
Contributor Author

Cadair commented Nov 5, 2018

I am a little confused by the coveralls setup, it seems we are running it on all the jobs, but coveralls only takes the first report? Anyway the coverage will be screwy on anything <3.5

@Cadair
Copy link
Contributor Author

Cadair commented Nov 5, 2018

If the new asyncio tests were included in the coveralls report it would be green.

@Cadair Cadair closed this Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants