Here are two test that checks
import pytest
from urllib.parse import quote_plus
from pydantic import constr
@pytest.fixture
def client():
# https://fastapi.tiangolo.com/tutorial/path-params/#path-convertor
app = FastAPI()
@app.get("/files/{file_path:path}"). #(1)
def get_file(file_path: str):
return {"path": file_path}
@app.get("/files/{file_path:path}/{version}"). #(2)
def get_file_with_version(
file_path:str, version: constr(regex=r"[\d\.]+")
):
return {"path": file_path, "version": version}
with TestClient(app) as cli:
yield cli
def test_with_double_slash(client):
file_path = "/home/johndoe/myfile.txt"
# Users // as noted in the Tip in https://fastapi.tiangolo.com/tutorial/path-params/#path-convertor
resp = client.get(f"/files/{file_path}")
assert resp.status_code == 200, resp.json()
assert resp.json()["path"] == file_path
resp = client.get(f"/files/{file_path}/3.5.4")
assert resp.status_code == 200, resp.json()
assert resp.json()["path"] == file_path
assert resp.json()["version"] == "3.5.4"
def test_with_quoted_path(client):
file_path = "/home/johndoe/myfile.txt"
quoted_path = quote_plus(file_path)
print()
print("Request done with:", f"/file/{quoted_path}")
print()
resp = client.get(f"/files/{quoted_path}")
assert resp.status_code == 200, resp.json()
assert resp.json()["path"] == file_path
resp = client.get(f"/files/{quoted_path}/3.5.4")
assert resp.status_code == 200, resp.json()
assert resp.json()["path"] == file_path
assert resp.json()["version"] == "3.5.4"
Dear FastAPI gurus,
I am trying to add a route as files/{file_path}/{version}, where file_path: Path and version: str.
I am aware that the path convertor allows the file path but as soon as I try adding an extra parameter, it is not able to separate both entries.
I also noticed that the order in which the routes are included, produce different result.
#(2) and then #(1)#(2) instead of #(1)I also noticed that the order in which the routes are included, produce different result.
You are supposed to notice! Check this: https://fastapi.tiangolo.com/tutorial/path-params/?h=+order+matter#order-matters
I also noticed that the order in which the routes are included, produce different result.
You are supposed to notice! Check this: https://fastapi.tiangolo.com/tutorial/path-params/?h=+order+matter#order-matters
Thx @Kludex I missed that one.
But it still does not explain the issues with the path
I need to investigate. If someone has time, or if you want @pcrespov, you can check https://github.com/encode/starlette/blob/master/starlette/routing.py and search for path:path and try to find out why you have this issue.
Solution until then: if you use a forward slash at the end, like /home/johndoe/myfile.txt/, it works as supposed.
Code that works:
from fastapi import FastAPI
from pydantic import constr
app = FastAPI()
@app.get("/files/{file_path:path}/{version}")
def get_file_with_version(file_path:str, version: constr(regex=r"[\d\.]+")):
return {"path": file_path, "version": version}
@app.get("/files/{file_path:path}")
def get_file(file_path: str):
return {"path": file_path}
I need to investigate. If someone has time, or if you want @pcrespov, you can check https://github.com/encode/starlette/blob/master/starlette/routing.py and search for
path:pathand try to find out why you have this issue.
@Kludex thx again! I will investigate the issue in starlette as well