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

Python async client #99

Closed
hyzyla opened this issue Aug 17, 2021 · 14 comments
Closed

Python async client #99

hyzyla opened this issue Aug 17, 2021 · 14 comments
Labels
stale Feedback from one or more authors is required to proceed.

Comments

@hyzyla
Copy link

hyzyla commented Aug 17, 2021

Is your feature request related to a problem? Please describe.

I want to use ory/kratos in asynchronous python app, built using aiohttp

Describe the solution you'd like

Add python asynchronous client, especially when openapi-generator-cli, supports generating clients based on asyncio

Describe alternatives you've considered

Build wrapper around API by myself, only for my project

@aeneasr
Copy link
Member

aeneasr commented Aug 17, 2021

How well is that generator supported?

@hyzyla
Copy link
Author

hyzyla commented Aug 17, 2021

https://openapi-generator.tech/docs/generators/python

It's possible to build a separate package specially for asyncio. Something like ory-kratos-client-async. Ideally if it will be one package that support both libraries: urllib3 and asyncio, but I didn't find if this possible by generator at all.

image

@aeneasr
Copy link
Member

aeneasr commented Aug 17, 2021

I think a good first try would be to generate the client as a PoC and see how well the generated code works. Would you be up for that?

Also, would asyncio also support synchronous operations? Or can we only have one or the other?

@hyzyla
Copy link
Author

hyzyla commented Aug 17, 2021

Would you be up for that?

Yes, I will try to add in few days

Also, would asyncio also support synchronous operations? Or can we only have one or the other?

You can use asynchronous functions in synchronous code, but it's not easy to do. For every asynchronous function, synchronous code should start event loop, run asynchronous function and then shutdown event loop.

@lorddaedra
Copy link

You can use async_to_sync and sync_to_async helpers to do that

https://github.com/django/asgiref/blob/main/asgiref/sync.py

@aeneasr
Copy link
Member

aeneasr commented Aug 19, 2021

So what do today's python developers prefer? Async or sync? Or is it 50/50?

@lorddaedra
Copy link

lorddaedra commented Aug 19, 2021

For I/O bound tasks async client looks as advantage. That's why I would like to see async-first client. Even Django can be deployed using ASGI interface and use async code in views and middleware. (Django ORM is still sync so need use sync_to_async wrapper).

Starlette/FastAPI (one of the server implementation to create OpenAPI compatible APIs) communities are big enough (completely async web frameworks). Ariadne (GraphQL server) based on Starlette too.

But there are tasks where you will not see any difference between sync and async and because of sync code looks simpler to write and understand for newbies developers will use it too (for pet or small business or legacy projects)...

But for current project (and for any projects like "Python client to some server") async implementation looks better.

@lorddaedra
Copy link

lorddaedra commented Aug 19, 2021

Also check https://grpc.github.io/grpc/python/grpc_asyncio.html
May be you should create gRPC based client instead of OpenAPI based...

@lorddaedra
Copy link

lorddaedra commented Aug 19, 2021

@hyzyla
Check this https://www.scrapingbee.com/blog/best-python-http-clients/
AIOHTTP and HTTPX looks better than urllib3 (But even better to use gRPC instead of OpenAPI endpoints for modern environments.)

@aeneasr
Copy link
Member

aeneasr commented Aug 23, 2021

gRPC would be a completely different beast ;) For one, it doesn't work very well in browser (e.g. AJAX) environments. First we need to get the REST API clients generated correctly! :)

@Benehiko
Copy link
Contributor

Although it is true to have I/O tasks asynchronous from the get go, I do feel like if you have synchronous code you can wrap it yourself using your own asynchronous implementation (the other way around isn't always that straight-forward). I would leave it as it is and allow each user to decide for themselves how they would like it implemented.

If the demand is really high for asynchronous clients then releasing a separate client would probably be the best route to go.

Just my 2 cents

@ermik
Copy link

ermik commented Aug 23, 2021

All points about async-bias as well as industry shift towards gRPC make sense to me. There's a very similar ticket in the kubernetes-client repo which has a lot of useful thoughts on the matter, while the repo itself has some great patterns for SDK maintenance.

Haven't tried the OpenAPI codegen for Python in a little bit, so I wonder — and I understand asyncio is preferred as a much more versatile framework — have you tried using the async_req mode for the existing libraries?

async_req: typing.Optional[bool] = None,

@nitedani
Copy link

nitedani commented Aug 2, 2022

If you pass async_req=True, it doesn't return an awaitable. It returns a multiprocessing.pool.ApplyResult
To convert that to an asyncio awaitable, I do this:

import asyncio
from typing import Union
from multiprocessing.pool import ApplyResult, AsyncResult


async def async_result_to_awaitable(result: Union[ApplyResult, AsyncResult]):
    timeout = 10
    breaker = True

    async def awaitable():
        while breaker:
            await asyncio.sleep(0.001)
            if result.ready():
                return result.get()

    try:
        return await asyncio.wait_for(awaitable(), timeout=timeout)
    except asyncio.TimeoutError as e:
        breaker = False
        raise e

@github-actions
Copy link

github-actions bot commented Aug 3, 2023

Hello contributors!

I am marking this issue as stale as it has not received any engagement from the community or maintainers for a year. That does not imply that the issue has no merit! If you feel strongly about this issue

  • open a PR referencing and resolving the issue;
  • leave a comment on it and discuss ideas on how you could contribute towards resolving it;
  • leave a comment and describe in detail why this issue is critical for your use case;
  • open a new issue with updated details and a plan for resolving the issue.

Throughout its lifetime, Ory has received over 10.000 issues and PRs. To sustain that growth, we need to prioritize and focus on issues that are important to the community. A good indication of importance, and thus priority, is activity on a topic.

Unfortunately, burnout has become a topic of concern amongst open-source projects.

It can lead to severe personal and health issues as well as opening catastrophic attack vectors.

The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone.

If this issue was marked as stale erroneously you can exempt it by adding the backlog label, assigning someone, or setting a milestone for it.

Thank you for your understanding and to anyone who participated in the conversation! And as written above, please do participate in the conversation if this topic is important to you!

Thank you 🙏✌️

@github-actions github-actions bot added the stale Feedback from one or more authors is required to proceed. label Aug 3, 2023
@github-actions github-actions bot closed this as completed Sep 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Feedback from one or more authors is required to proceed.
Projects
None yet
Development

No branches or pull requests

6 participants