Browse Source
* 🐛 Fix path and query parameters accepting dict * ✅ Add several tests to ensure invalid types are not accepted * 📝 Document (to include tested source) using query params with list * 🐛 Fix OpenAPI schema in query with list tutorialpull/288/head
committed by
GitHub
7 changed files with 227 additions and 3 deletions
@ -0,0 +1,9 @@ |
|||||
|
from fastapi import FastAPI, Query |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/items/") |
||||
|
async def read_items(q: list = Query(None)): |
||||
|
query_items = {"q": q} |
||||
|
return query_items |
@ -0,0 +1,77 @@ |
|||||
|
from typing import Dict, List, Tuple |
||||
|
|
||||
|
import pytest |
||||
|
from fastapi import FastAPI |
||||
|
from pydantic import BaseModel |
||||
|
|
||||
|
|
||||
|
def test_invalid_sequence(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
class Item(BaseModel): |
||||
|
title: str |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: List[Item]): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_tuple(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
class Item(BaseModel): |
||||
|
title: str |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: Tuple[Item, Item]): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_dict(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
class Item(BaseModel): |
||||
|
title: str |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: Dict[str, Item]): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_simple_list(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: list): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_simple_tuple(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: tuple): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_simple_set(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: set): |
||||
|
pass # pragma: no cover |
||||
|
|
||||
|
|
||||
|
def test_invalid_simple_dict(): |
||||
|
with pytest.raises(AssertionError): |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/items/{id}") |
||||
|
def read_items(id: dict): |
||||
|
pass # pragma: no cover |
@ -0,0 +1,91 @@ |
|||||
|
from starlette.testclient import TestClient |
||||
|
|
||||
|
from query_params_str_validations.tutorial013 import app |
||||
|
|
||||
|
client = TestClient(app) |
||||
|
|
||||
|
openapi_schema = { |
||||
|
"openapi": "3.0.2", |
||||
|
"info": {"title": "Fast API", "version": "0.1.0"}, |
||||
|
"paths": { |
||||
|
"/items/": { |
||||
|
"get": { |
||||
|
"responses": { |
||||
|
"200": { |
||||
|
"description": "Successful Response", |
||||
|
"content": {"application/json": {"schema": {}}}, |
||||
|
}, |
||||
|
"422": { |
||||
|
"description": "Validation Error", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/HTTPValidationError" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"summary": "Read Items", |
||||
|
"operationId": "read_items_items__get", |
||||
|
"parameters": [ |
||||
|
{ |
||||
|
"required": False, |
||||
|
"schema": {"title": "Q", "type": "array"}, |
||||
|
"name": "q", |
||||
|
"in": "query", |
||||
|
} |
||||
|
], |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"components": { |
||||
|
"schemas": { |
||||
|
"ValidationError": { |
||||
|
"title": "ValidationError", |
||||
|
"required": ["loc", "msg", "type"], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"loc": { |
||||
|
"title": "Location", |
||||
|
"type": "array", |
||||
|
"items": {"type": "string"}, |
||||
|
}, |
||||
|
"msg": {"title": "Message", "type": "string"}, |
||||
|
"type": {"title": "Error Type", "type": "string"}, |
||||
|
}, |
||||
|
}, |
||||
|
"HTTPValidationError": { |
||||
|
"title": "HTTPValidationError", |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"detail": { |
||||
|
"title": "Detail", |
||||
|
"type": "array", |
||||
|
"items": {"$ref": "#/components/schemas/ValidationError"}, |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
def test_openapi_schema(): |
||||
|
response = client.get("/openapi.json") |
||||
|
assert response.status_code == 200 |
||||
|
assert response.json() == openapi_schema |
||||
|
|
||||
|
|
||||
|
def test_multi_query_values(): |
||||
|
url = "/items/?q=foo&q=bar" |
||||
|
response = client.get(url) |
||||
|
assert response.status_code == 200 |
||||
|
assert response.json() == {"q": ["foo", "bar"]} |
||||
|
|
||||
|
|
||||
|
def test_query_no_values(): |
||||
|
url = "/items/" |
||||
|
response = client.get(url) |
||||
|
assert response.status_code == 200 |
||||
|
assert response.json() == {"q": None} |
Loading…
Reference in new issue