You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have looked into the README and have not found a suitable solution or answer.
I have looked into the documentation and have not found a suitable solution or answer.
I have searched the issues and have not found a suitable solution or answer.
I have searched the Slack Community and have not found a suitable solution or answer. (I do not have a slack account, nor do I feel that I have to create one just to delete it afterwards)
And when the wrapper's .read() is called from different co-routine as an example, this happens quite frequently:
File "/app/openfga_wrapper/__init__.py", line 82, in read
return await self.session.read(body, self.options)
...
RuntimeError: Timeout context manager should be used inside a task
And attempting to create a task specifically yields the same result:
It still complains that the Timeout context is not executed from within a task.
I'm not entirely comfortable with asyncio in general, but from what I can tell it's mainly because of how OpenFGA attempts to find/use the currently running event loop, instead of consistently using one defined loop.
And attempting to create a secondary long lasting asyncio loop with threads will produce:
attached to a different loop
Obviously if you have the option to wrap everything in one asyncio.run() call, that's the ideal solution. However if using certain libraries or threads this becomes troublesome.
Expectation
A way to set a target event loop in either ClientConfiguration or OpenFgaClient
Reproduction
Below is a sample code of an API that will generate the issue.
Note that fixing the below code to work, by creating a async def _main() and avoid using separate threads would fix this particular code - but it's intended to show the threaded issue.
Run curl http://127.0.0.1:8888 against:
importasyncioimportbase64importjsonimportrandomimportstringimporttimeimportthreadingimportloggingfromfastapiimportFastAPIfromhypercorn.configimportConfigfromhypercorn.asyncioimportservefromopenfga_sdk.exceptionsimportApiExceptionfromopenfga_sdkimportClientConfiguration, OpenFgaClient, ReadRequestTupleKeyclassOpenFGAWrapper(threading.Thread):
def__init__(self):
self.configuration=ClientConfiguration(
api_url=f"http://openfga:8080"
)
self.session=Noneself.options=Noneself.store_id=Noneself.loop=Nonethreading.Thread.__init__(self)
self.start()
defrun(self):
asyncio.run(self._reconnect())
defclose(self):
try:
self.loop=asyncio.get_running_loop()
exceptRuntimeError:
self.loop=asyncio.new_event_loop()
returnself.loop.run_until_complete(openfga.session.close())
asyncdef_reconnect(self):
ifself.sessionisNone:
try:
self.loop=asyncio.get_running_loop()
exceptRuntimeError:
self.loop=asyncio.new_event_loop()
self.session=OpenFgaClient(self.configuration)
pageination_options= {
"page_size": 25,
"continuation_token": base64.urlsafe_b64encode(json.dumps({
"pk":"LATEST_NSCONFIG_auth0store",
"sk":''.join(random.SystemRandom().choice(string.ascii_uppercase+string.digits) for_inrange(12))
}).encode()).decode()
}
# After connecting, use set_store_id() to set a default store for# this session.try:
response=awaitself.session.list_stores(pageination_options)
exceptApiExceptionaserror:
print(error.parsed_exception)
raiseerrorforstoreinresponse.stores:
self.session.set_store_id(store.id)
self.store_id=store.id# We set default options for later use, that use the last# available authorization model.try:
response=awaitself.session.read_authorization_models()
exceptApiExceptionaserror:
print(error.parsed_exception)
raiseerrorformodelinresponse.authorization_models:
self.options= {
"authorization_model_id": model.id
}
whileTrue:
time.sleep(0.25)
asyncdefread(self, body):
task=awaitself.loop.create_task(self.session.read(body, self.options))
returntask.result()
if__name__=='__main__':
logging.getLogger("hypercorn.error").setLevel(logging.DEBUG)
logging.getLogger("hypercorn.access").setLevel(logging.DEBUG)
corn_conf=Config()
corn_conf.bind=f"127.0.0.1:8888"corn_conf.loglevel="DEBUG"corn_conf.accesslog='-'corn_conf.errorlog='-'openfga=OpenFGAWrapper()
app=FastAPI(
title="TestAPI"
)
@app.get("/")asyncdefentrypoint():
body=ReadRequestTupleKey(
user=f"user:testuser",
relation="owner",
object="document:",
)
try:
response=awaitopenfga.read(body)
exceptApiExceptionaserror:
print(error.parsed_exception)
raiseerrorasyncio.run(serve(app, corn_conf))
openfga.close()
SDK Checklist
JS SDK
Go SDK
.NET SDK
Python SDK
Java SDK
OpenFGA SDK version
0.6.0
OpenFGA version
v1.4.3
SDK Configuration
See example code
Logs
No response
References
No response
The text was updated successfully, but these errors were encountered:
Checklist
Description
In a wrapper class, in short I have:
And when the wrapper's
.read()
is called from different co-routine as an example, this happens quite frequently:And attempting to create a task specifically yields the same result:
It still complains that the Timeout context is not executed from within a task.
I'm not entirely comfortable with
asyncio
in general, but from what I can tell it's mainly because of howOpenFGA
attempts to find/use the currently running event loop, instead of consistently using one defined loop.And attempting to create a secondary long lasting asyncio loop with threads will produce:
Obviously if you have the option to wrap everything in one
asyncio.run()
call, that's the ideal solution. However if using certain libraries or threads this becomes troublesome.Expectation
A way to set a target event loop in either
ClientConfiguration
orOpenFgaClient
Reproduction
Below is a sample code of an API that will generate the issue.
Note that fixing the below code to work, by creating a
async def _main()
and avoid using separate threads would fix this particular code - but it's intended to show the threaded issue.Run
curl http://127.0.0.1:8888
against:SDK Checklist
OpenFGA SDK version
0.6.0
OpenFGA version
v1.4.3
SDK Configuration
See example code
Logs
No response
References
No response
The text was updated successfully, but these errors were encountered: