如何在脚本为 运行 之前阻止对 fastapi 的响应?
How to block response on fastapi until script is ran?
我有一个调用 python 脚本的 fastapi 端点,但在 GCP 上有两个问题:
- 它总是给出成功代码(因为它没有阻塞)
- 实例总是 运行 因为云运行不知道什么时候关闭它(因为它没有阻塞)。
我认为问题正在阻塞:-)
这是我的代码示例:
async def curve_builder(secret: str):
os.system("python3 scripts/my_script.py")
return {"succcess": True, "status": "Batch job completed"}
有没有办法让脚本完成后 return 一条 success/fail 消息?我不确定如何阻止它,它似乎只是 return 命令一执行就成功了。
我不确定这是特定于 fastapi 还是通用 python。
将“os.system()”调用分配给一个变量。您的脚本的退出代码已分配,因此它会等到它完成,尽管您正在使用异步方法。
答案错误,我已经测试了一个示例设置但无法重现该问题。
脚本 1:
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")
脚本 2:
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")
输出:
start script1
Start of method1
start async script2
Start method2
End method2
End async script2
End of method
end script1
阻塞操作可能会挂断您当前的工作人员。当您想在协程上执行阻塞代码时,将其逻辑发送给执行程序。
- 获取事件循环
loop = asyncio.get_running_loop()
- 任何阻塞代码都必须在您的协程之外。因此,您当前的工作人员将能够执行其他协程。
await loop.run_in_executor(None, func)
对于您的情况,最终结果将是:
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}
您可以在文档中阅读更多信息:https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor
我有一个调用 python 脚本的 fastapi 端点,但在 GCP 上有两个问题:
- 它总是给出成功代码(因为它没有阻塞)
- 实例总是 运行 因为云运行不知道什么时候关闭它(因为它没有阻塞)。
我认为问题正在阻塞:-)
这是我的代码示例:
async def curve_builder(secret: str):
os.system("python3 scripts/my_script.py")
return {"succcess": True, "status": "Batch job completed"}
有没有办法让脚本完成后 return 一条 success/fail 消息?我不确定如何阻止它,它似乎只是 return 命令一执行就成功了。
我不确定这是特定于 fastapi 还是通用 python。
将“os.system()”调用分配给一个变量。您的脚本的退出代码已分配,因此它会等到它完成,尽管您正在使用异步方法。
答案错误,我已经测试了一个示例设置但无法重现该问题。
脚本 1:
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")
脚本 2:
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")
输出:
start script1
Start of method1
start async script2
Start method2
End method2
End async script2
End of method
end script1
阻塞操作可能会挂断您当前的工作人员。当您想在协程上执行阻塞代码时,将其逻辑发送给执行程序。
- 获取事件循环
loop = asyncio.get_running_loop()
- 任何阻塞代码都必须在您的协程之外。因此,您当前的工作人员将能够执行其他协程。
await loop.run_in_executor(None, func)
对于您的情况,最终结果将是:
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}
您可以在文档中阅读更多信息:https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor