如何Request从中间件函数为对象设置任意属性?
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def set_custom_attr(request: Request, call_next):
request.custom_attr = "This is my custom attribute"
response = await call_next(request)
return response
@app.get("/")
async def root(request: Request):
return {"custom_attr": request.custom_attr}
Run Code Online (Sandbox Code Playgroud)
此设置引发异常,
AttributeError:“请求”对象没有属性“custom_attr”
那么,如何获取"This is my custom attribute"路由器中的值呢?
我正在使用 pytest 来测试 FastAPI 端点,该端点以二进制格式输入图像,如
@app.post("/analyse")
async def analyse(file: bytes = File(...)):
image = Image.open(io.BytesIO(file)).convert("RGB")
stats = process_image(image)
return stats
Run Code Online (Sandbox Code Playgroud)
启动服务器后,我可以通过运行调用来成功手动测试端点 requests
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
url = "http://127.0.0.1:8000/analyse"
filename = "./example.jpg"
m = MultipartEncoder(
fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}
)
r = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)
assert r.status_code == 200
Run Code Online (Sandbox Code Playgroud)
但是,以以下形式设置测试:
from fastapi.testclient import TestClient
from requests_toolbelt.multipart.encoder import MultipartEncoder
from app.server import app
client = TestClient(app)
def test_image_analysis():
filename = "example.jpg"
m = MultipartEncoder( …Run Code Online (Sandbox Code Playgroud) 我在 Starlette/FastApi 中定义了一条路线 -
@router.post("/{part}")
def post_method(part):
return "ok"
@router.post("/{part}/{another_part}")
def another_post_method(part, another_part):
return "ok"
Run Code Online (Sandbox Code Playgroud)
我的路径组件中有一些正斜杠,我想发出以下请求来访问post_method
curl -X POST "http://127.0.0.1:5000/api/path%2Fpath" -H "accept: application/json" -d ""
导致 Starlette/Fastapi 日志中出现 404 错误。
INFO: 127.0.0.1:50233 - "POST /api/path/path HTTP/1.1" 404
如何获取正确的路径组件?
我目前正在开发我的第一个 web 应用程序,前端React使用FastAPI.
我正在尝试与 Chrome 联合测试它——看看前端是否对后端进行了正确的 API 调用,并显示结果。我在使用 cookie 时遇到了问题,我需要帮助。提前为这篇长文章道歉——过去几天我浏览了很多资源,此时我不确定什么是相关的,什么是不相关的。
localhost:8080http://127.0.0.1:8000FastAPI后端代码正确设置 CORS(我相信):app = FastAPI()
origins = [
"http://localhost:8080"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Run Code Online (Sandbox Code Playgroud)
情况:前端GET向http://127.0.0.1:8000/api/abc后端发出请求,后端设置 cookie。
/*====================
尝试 1:
使用以下后端代码设置 cookie:
response.set_cookie(key="abcCookieKey", value="abcCookieValue")
Run Code Online (Sandbox Code Playgroud)
并GET使用以下前端 JS 代码发出请求:
fetch('http://127.0.0.1:8000/api/abc', {
method: 'GET',
credentials: 'include',
})
Run Code Online (Sandbox Code Playgroud)
尝试 1 的结果:
在ConsoleChrome的选项卡上,我收到以下警告:
A cookie associated with a cross-site resource at http://127.0.0.1/ was set …Run Code Online (Sandbox Code Playgroud) 我正在通过挂载从FastAPI提供React应用程序
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.route('/session')
async def renderReactApp(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
Run Code Online (Sandbox Code Playgroud)
通过这个 React 应用程序得到服务,React 路由在客户端也可以正常工作,但是一旦客户端重新加载一个没有在服务器上定义但在 React 应用程序中使用的路由,FastAPI 返回not found来解决这个问题,我做了如下的一些事情。
@app.route('/network')@app.route('/gat')@app.route('/session')async def renderReactApp(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
Run Code Online (Sandbox Code Playgroud)
但这对我来说似乎很奇怪和错误,因为我需要在后端和前端添加每条路线。
我确定@flask_app.add_url_rule('/<path:path>', 'index', index)FastAPI 中必须有类似 Flask的东西,它将为所有任意路径提供服务
当我们调用端点并且由于缺少尾部斜杠而发生重定向时遇到问题。如下图所示,当向https ://.../notifications发出请求时,FastAPI 服务器响应重定向到http ://...notifications/
我怀疑这是一个应用程序配置问题,而不是服务器配置问题。有没有人知道如何解决这个问题?
我使用 fastapi 和 uvicorn 编写了一个服务。我的服务中有一个启动 uvicorn 的 main (见下文)。主要是,我做的第一件事是加载配置设置。我有一些 INFO 输出,可以在加载配置时输出设置。我注意到当我启动服务时,配置加载方法似乎运行了两次。
# INITIALIZE
if __name__ == "__main__":
# Load the config once at bootstrap time. This outputs the string "Loading configuration settings..."
config = CdfAuthConfig()
print("Loaded Configuration")
# Create FastAPI object
app = FastAPI()
# Start uvicorn
uvicorn.run(app, host="127.0.0.1", port=5050)
Run Code Online (Sandbox Code Playgroud)
我运行该服务时的输出如下所示:
Loading configuration settings...
Loading configuration settings...
Loaded Configuration
Run Code Online (Sandbox Code Playgroud)
为什么“CdfAuthConfig()”类被实例化两次?它显然与“uvicorn.run”命令有关。
我通常使用 Tornado,并尝试迁移到 FastAPI。
假设我有一个非常基本的 API,如下所示:
@app.post("/add_data")
async def add_data(data):
return data
Run Code Online (Sandbox Code Playgroud)
当我运行以下 Curl 请求时:
curl http://127.0.0.1:8000/add_data -d 'data=Hello'
我收到以下错误:
{"detail":[{"loc":["query","data"],"msg":"field required","type":"value_error.missing"}]}
所以我确信我错过了一些非常基本的东西,但我不知道那可能是什么。
FastAPI 显示您可以response_model_exclude_none=True在装饰器中设置为省略值为 的字段None:https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter
我想这样做,但None我想要排除的字段嵌套在父响应模型中。IE
class InnerResponse(BaseModel):
id: int
name: Optional[str] = None
class Response(BaseModel):
experience: int
prices: List[InnerResponse]
@app.post("/dummy", response_model=apitypes.Response, response_model_exclude_none=True)
async def backend_dummy(payload: apitypes.Request):
...
Run Code Online (Sandbox Code Playgroud)
然而,当我收到回复时,这里的“价格”列表仍然InnerResponse有"name": null.
有没有办法在嵌套模型上应用排除规则?
fastapi ×10
python ×4
python-3.x ×3
starlette ×2
uvicorn ×2
cookies ×1
curl ×1
flask ×1
middleware ×1
mongodb ×1
mongoengine ×1
motorengine ×1
multipart ×1
pydantic ×1
pytest ×1
reactjs ×1
samesite ×1