最近用azure function做了一个api和llm交互,需要流式返回。但是默认不支持流返回,搜索了一下。记录。
根据文档需要以下步骤:
前置条件
- Azure Functions runtime version 4.34.1, or a later version.
- Python version 3.8, or a later supported version.
- Python v2 programming model
首先第一点,这个Azure Functions runtime version版本,可以在local.settings.json或者式环境变量里面设置,如果式本地 func start启动的话也需要加PYTHON_ENABLE_INIT_INDEXING这个变量设置为1,如果线上deploy的话就加到application setting里面。
python
{
"IsEncrypted": false,
"Values": {
"PYTHON_ENABLE_INIT_INDEXING": "1",
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_EXTENSION_VERSION":"4.34.1"
}
}
Azure Functions runtime version这个使用的版本可以用 func start --verbose输出更多参数查看到
第二点python版本不需要多讲。第三点azure programming版本的话就在host.json查看。
python
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
引入新包
bash
pip install azurefunctions-extensions-http-fastapi
编写代码
python
from azurefunctions.extensions.http.fastapi import Request, StreamingResponse
python
import time
import azure.functions as func
from azurefunctions.extensions.http.fastapi import Request, StreamingResponse
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
def generate_count():
"""Generate a stream of chronological numbers."""
count = 0
while True:
yield f"counting, {count}\n\n"
count += 1
@app.route(route="stream", methods=[func.HttpMethod.GET])
async def stream_count(req: Request) -> StreamingResponse:
"""Endpoint to stream of chronological numbers."""
try:
req_body = await req.json()
query = req_body.get('query')
logging.info('stream_count get parm: {query}')
except Exception:
traceback.print_exc()
return StreamingResponse(content='Request parm error need {"query":str} ',status_code=500, media_type="text/event-stream")
return StreamingResponse(generate_count(), media_type="text/event-stream")
如果是非流返回的api就不能使用默认的func.HttpResponse作为返回了,需要使用JSONResponse
python
from azurefunctions.extensions.http.fastapi import Request,JSONResponse
@app.route(route="all_u_need_create", methods=[func.HttpMethod.GET])
async def all_u_need_create(req: Request) -> JSONResponse:
...
return JSONResponse(content=ids,status_code=200)
测试
这边有点奇怪的是,我使用postman测试一直显示不了返回的流,我一度以为我代码有问题,找了半天,结果用 curl测试没有任何问题.有知道怎么解决的同学也可以给我讲一下。
bash
curl -X GET --data-raw '{"query":"xxxxx"}' -H "Content-Type: application/json" http://localhost:7071/api/all_u_need_search
所以之后的测试就一直用的curl测试了。