OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.35k stars 6.46k forks source link

[Python] How to make http asyncrhonous calls with generated python client #3696

Open jpascualsana opened 5 years ago

jpascualsana commented 5 years ago
Description

I'm creating a auto-generated API client using the openapi-generator for python. This API has some asynchronous functions that returns lines of data: JSON asynchronously.

I would like to have a callback that get this data and process it on a separate thread but I don't know how to use the async=True option when the call is instantiated. As I show it return a Thread but I don't know how to set the callback for it.

openapi-generator version
➜ openapi-generator version
4.0.3
OpenAPI declaration file content or url

https://gitlab.com/snippets/1882068/raw

Note: this YAML is auto generated from a Doxygen documentation for RetroShare project using this

Command line used for generation
openapi-generator generate -i wrapper_openapi.yml -g python -o ../openapi-python-retroshare-api-wrapper
Steps to reproduce

You can generate the wrapper using the command above with the provided YAML or cloning this.

I tested this code:

thread = api_instance.rs_gxs_channels_turtle_search_request(async_req=True,              req_rs_gxs_channels_turtle_search_request=req_rs_gxs_channels_turtle_search_request)
result = thread.get()
print("should be printed")

The program just stop, the "should be printed" string is never printed until the connection is closed by the server, so is not async, so is not a separated thread or I don't know how to use it.

In addition I would like that the responses received asynchronously be processed in a callback function

Related issues/PRs

I just opened an stackoverflow question:

https://stackoverflow.com/questions/57486784/python-openapi-generator-how-to-make-http-asyncrhonous-calls

auto-labeler[bot] commented 5 years ago

👍 Thanks for opening this issue! 🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

wing328 commented 5 years ago

Would the following example (test) help?

https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/python/tests/test_pet_api.py#L142-L184

jpascualsana commented 5 years ago

Hi sorry for the late response.

No, the example doesn't help because is not defined anywhere a callback function that process the response asynchronously in a separated thread. The workflow is:

  1. Open the http connection
  2. While the connection is open you receive lines of data:JSON
  3. The connection is closed on timeout.

Usually you define a callback on separated thread that process this data:JSON lines. Is there a way to define this?

Also if I have:

thread = api_instance.rs_gxs_channels_turtle_search_request(async_req=True,              req_rs_gxs_channels_turtle_search_request=req_rs_gxs_channels_turtle_search_request)
result = thread.get()
print("should be printed")

The phrase "should be printed" is not printed... So, where the asynchronous is done?

And finally, I will have long response times for this issue but I'm going to answer... If you like, please, re-open this issue

G10h4ck commented 5 years ago

The use case referred by @jpascualsana is usually called event stream, or server-sent events it is even standardized by W3C, you can read something about it here, https://www.html5rocks.com/en/tutorials/eventsource/basics/ and here https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

So basically once one call an event stream API as first line one receive the call return value, and then the followinf lines are the param that would have been passed to an eventual callback serialized as JSON, here it goes a sample output

data: {"retval":true}

data: {"event":{"mType":3,"mTime":1566848265,"mTime_sixtyfour_str":"1566848265","mSuccess":true,"mSslId":"07a27a8aa825d529f20819064467a061","mSslCn":"776DC2E16223535C","mPgpId":"776DC2E16223535C","mErrorMsg":""}}

data: {"event":{"mType":5,"mTime":1566848266,"mTime_sixtyfour_str":"1566848266","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["15cea903dbf3b4b051069384cba41cec"],"mDistantSearchReqs":[]}}

data: {"event":{"mType":5,"mTime":1566848267,"mTime_sixtyfour_str":"1566848267","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["18b63e12ffc0622a44abf93525c4e691"],"mDistantSearchReqs":[]}}

data: {"event":{"mType":5,"mTime":1566848268,"mTime_sixtyfour_str":"1566848268","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["1cbe4242965a7748a8d1c06b2bdab0c3"],"mDistantSearchReqs":[]}}

data: {"event":{"mType":5,"mTime":1566848269,"mTime_sixtyfour_str":"1566848269","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["21657994f612784c615311a37de78692"],"mDistantSearchReqs":[]}}

data: {"event":{"mType":5,"mTime":1566848270,"mTime_sixtyfour_str":"1566848270","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["2197d090fbf1a0da716286169dfd2021"],"mDistantSearchReqs":[]}}

data: {"event":{"mType":5,"mTime":1566848271,"mTime_sixtyfour_str":"1566848271","mServiceType":529,"mMsgs":[],"mMsgsMeta":[],"mGrps":[],"mGrpsMeta":["21ac11562f71163da61d9ef39e391670"],"mDistantSearchReqs":[]}}

This way the callback can be called in the client passing the parameter deserialized

jpascualsana commented 5 years ago

It seems that will be not a way to do that with the current template, so the solution could be to modify the template to add this feature?

reidmeyer commented 2 years ago

@jpascualsana, did you find a way to consume sse using the openapi generated sdk?