Reputation: 26057
I have a fastapi endpoint that calls a python script but has two problems on GCP:
I think the problem is blocking :-)
Here's a sample of my code:
async def curve_builder(secret: str):
os.system("python3 scripts/my_script.py")
return {"succcess": True, "status": "Batch job completed"}
Is there a way to let the script and then return a success/fail message once it's done? I'm not sure how to block it, it seems to just return a success as soon as the command is executed.
I'm not sure if this is specific to fastapi or general python.
Upvotes: 0
Views: 950
Reputation: 1070
Blocking operations could hang up your current worker. When you want to execute blocking code over a coroutine, send its logic to a executor.
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, func)
For your case, the final result will be:
async def curve_builder(secret: str):
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(None, lambda: os.system("python3 scripts/my_script.py"))
return {"status": result}
You can read further information in the docs: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor
Upvotes: 1
Reputation: 5359
Assign the ‘os.system()’ call to a variable. The exit code of your script is assigned, so it will wait till it finished, despite being a async method you are working from.
The answer was wrong, I've tested an example setup but could not reproduce the issue.
Script1:
import os
import asyncio
async def method1():
print("Start of method1")
os.system("python /path/to/other/script/script2.py")
print("End of method1")
print("start script1")
asyncio.run(method1())
print("end script1")
Script2:
import asyncio
async def method2():
print("Start method2")
await asyncio.sleep(3)
print("End method2")
print("start async script2")
asyncio.run(method2())
print("end async script2")
Output:
start script1
Start of method1
start async script2
Start method2
End method2
End async script2
End of method
end script1
Upvotes: 0