Compare commits

..

9 Commits

Author SHA1 Message Date
Sebastián Ramírez
90236c8135 🔖 Release version 0.44.1 2019-12-05 00:17:04 +01:00
Sebastián Ramírez
c200bc2240 📝 Update release notes 2019-11-29 09:02:21 +01:00
Sebastián Ramírez
e9861cd918 🍱 Add GitHub social preview assets to git (#752) 2019-11-29 08:52:03 +01:00
Sebastián Ramírez
202fa11d50 📝 Update release notes 2019-11-29 08:30:10 +01:00
Sebastián Ramírez
4b6e09296c 🔧 Update PyPI trove classifiers (#751) 2019-11-29 08:29:37 +01:00
Sebastián Ramírez
9bd0d6fa96 👷 Enable full Travis for Python 3.8 (#750) 2019-11-29 07:45:09 +01:00
Sebastián Ramírez
35510a5ea7 📝 Update the "new issue" templates (#749)
* 🔧 Update the "new issue" templates

* 💚 Trigger Travis CI after Travis migration
2019-11-29 07:35:25 +01:00
Sebastián Ramírez
c1788a25c7 📝 Update release notes 2019-11-29 07:04:01 +01:00
dmontagu
19c77e35bd 🐛 Fix issue with exotic pydantic error serialization (#748) 2019-11-29 07:02:10 +01:00
11 changed files with 212 additions and 41 deletions

View File

@@ -7,29 +7,48 @@ assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
### Describe the bug
**To Reproduce**
Steps to reproduce the behavior:
1. Create a file with '...'
2. Add a path operation function with '....'
3. Open the browser and call it with a payload of '....'
4. See error
Write here a clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
### To Reproduce
**Screenshots**
If applicable, add screenshots to help explain your problem.
Steps to reproduce the behavior with a minimum self-contained file.
**Environment:**
- OS: [e.g. Linux / Windows / macOS]
- FastAPI Version [e.g. 0.3.0], get it with:
Replace each part with your own scenario:
1. Create a file with:
```Python
import fastapi
print(fastapi.__version__)
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
```
3. Open the browser and call the endpoint `/`.
4. It returns a JSON with `{"Hello": "World"}`.
5. But I expected it to return `{"Hello": "Sara"}`.
### Expected behavior
Add a clear and concise description of what you expected to happen.
### Screenshots
If applicable, add screenshots to help explain your problem.
### Environment
- OS: [e.g. Linux / Windows / macOS]
- FastAPI Version [e.g. 0.3.0], get it with:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
- Python version, get it with:
@@ -38,5 +57,6 @@ print(fastapi.__version__)
python --version
```
**Additional context**
### Additional context
Add any other context about the problem here.

View File

@@ -7,14 +7,20 @@ assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I want to be able to [...] but I can't because [...]
### Is your feature request related to a problem
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
Is your feature request related to a problem?
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
Add a clear and concise description of what the problem is. Ex. I want to be able to [...] but I can't because [...]
### The solution you would like
Add a clear and concise description of what you want to happen.
### Describe alternatives you've considered
Add a clear and concise description of any alternative solutions or features you've considered.
### Additional context
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -7,11 +7,18 @@ assignees: ''
---
**Description**
### First check
* [ ] I used the GitHub search to find a similar issue and didn't find it.
* [ ] I searched the FastAPI documentation, with the integrated search.
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
### Description
How can I [...]?
Is it possible to [...]?
**Additional context**
### Additional context
Add any other context or screenshots about the feature request here.

View File

@@ -7,12 +7,11 @@ cache: pip
python:
- "3.6"
- "3.7"
- "3.8-dev"
- "3.8"
- "nightly"
matrix:
allow_failures:
- python: "3.8-dev"
- python: "nightly"
install:

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg8"
version="1.1"
viewBox="0 0 338.66665 169.33332"
height="169.33333mm"
width="338.66666mm"
sodipodi:docname="github-social-preview.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
inkscape:export-filename="/home/user/code/fastapi/docs/img/github-social-preview.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1025"
id="namedview9"
showgrid="false"
inkscape:zoom="0.52249777"
inkscape:cx="565.37328"
inkscape:cy="403.61034"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<rect
style="opacity:0.98000004;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
id="rect853"
width="338.66666"
height="169.33333"
x="-1.0833333e-05"
y="0.71613133"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<g
transform="matrix(0.73259569,0,0,0.73259569,64.842852,-4.5763945)"
id="layer1">
<path
style="opacity:0.98000004;fill:#009688;fill-opacity:1;stroke-width:3.20526505"
id="path817"
d="m 1.4365174,55.50154 c -17.6610514,0 -31.9886064,14.327532 -31.9886064,31.988554 0,17.661036 14.327555,31.988586 31.9886064,31.988586 17.6609756,0 31.9885196,-14.32755 31.9885196,-31.988586 0,-17.661022 -14.327544,-31.988554 -31.9885196,-31.988554 z m -1.66678692,57.63069 V 93.067264 H -11.384533 L 4.6417437,61.847974 V 81.912929 H 15.379405 Z"
inkscape:connector-curvature="0" />
<text
id="text979"
y="114.91215"
x="52.115433"
style="font-style:normal;font-weight:normal;font-size:79.71511078px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#009688;fill-opacity:1;stroke:none;stroke-width:1.99287772"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#009688;fill-opacity:1;stroke-width:1.99287772"
y="114.91215"
x="52.115433"
id="tspan977">FastAPI</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="169.60979"
y="119.20409"
id="text851"><tspan
sodipodi:role="line"
id="tspan849"
x="169.60979"
y="119.20409"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Roboto;-inkscape-font-specification:'Roboto Italic';text-align:center;text-anchor:middle;stroke-width:0.26458332">High performance, easy to learn,</tspan><tspan
sodipodi:role="line"
x="169.60979"
y="132.53661"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Roboto;-inkscape-font-specification:'Roboto Italic';text-align:center;text-anchor:middle;stroke-width:0.26458332"
id="tspan855">fast to code, ready for production</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,5 +1,13 @@
## Latest changes
## 0.44.1
* Add GitHub social preview images to git. PR [#752](https://github.com/tiangolo/fastapi/pull/752).
* Update PyPI "trove classifiers". PR [#751](https://github.com/tiangolo/fastapi/pull/751).
* Add full support for Python 3.8. Enable Python 3.8 in full in Travis. PR [749](https://github.com/tiangolo/fastapi/pull/749).
* Update "new issue" templates. PR [#749](https://github.com/tiangolo/fastapi/pull/749).
* Fix serialization of errors for exotic Pydantic types. PR [#748](https://github.com/tiangolo/fastapi/pull/748) by [@dmontagu](https://github.com/dmontagu).
## 0.44.0
* Add GitHub action [Issue Manager](https://github.com/tiangolo/issue-manager). PR [#742](https://github.com/tiangolo/fastapi/pull/742).

View File

@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.44.0"
__version__ = "0.44.1"
from starlette.background import BackgroundTasks

View File

@@ -1,3 +1,4 @@
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException
from starlette.requests import Request
@@ -19,5 +20,6 @@ async def request_validation_exception_handler(
request: Request, exc: RequestValidationError
) -> JSONResponse:
return JSONResponse(
status_code=HTTP_422_UNPROCESSABLE_ENTITY, content={"detail": exc.errors()}
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": jsonable_encoder(exc.errors())},
)

View File

@@ -8,15 +8,28 @@ author = "Sebastián Ramírez"
author-email = "tiangolo@gmail.com"
home-page = "https://github.com/tiangolo/fastapi"
classifiers = [
"License :: OSI Approved :: MIT License",
'Intended Audience :: Information Technology',
'Intended Audience :: System Administrators',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python',
'Topic :: Internet',
'Topic :: Software Development :: Libraries :: Application Frameworks',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development',
'Typing :: Typed',
"Development Status :: 4 - Beta",
"Environment :: Web Environment",
"Framework :: AsyncIO",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
"Topic :: Internet :: WWW/HTTP",
]
requires = [
"starlette >=0.12.9,<=0.12.9",

View File

@@ -1,7 +1,8 @@
from decimal import Decimal
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
from pydantic import BaseModel, condecimal
from starlette.testclient import TestClient
app = FastAPI()
@@ -9,7 +10,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
age: int
age: condecimal(gt=Decimal(0.0))
@app.post("/items/")
@@ -67,7 +68,7 @@ openapi_schema = {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"age": {"title": "Age", "type": "integer"},
"age": {"title": "Age", "exclusiveMinimum": 0.0, "type": "number"},
},
},
"ValidationError": {
@@ -99,6 +100,17 @@ openapi_schema = {
},
}
single_error = {
"detail": [
{
"ctx": {"limit_value": 0.0},
"loc": ["body", "item", 0, "age"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
multiple_errors = {
"detail": [
{
@@ -108,8 +120,8 @@ multiple_errors = {
},
{
"loc": ["body", "item", 0, "age"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
{
"loc": ["body", "item", 1, "name"],
@@ -118,8 +130,8 @@ multiple_errors = {
},
{
"loc": ["body", "item", 1, "age"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
]
}
@@ -137,7 +149,13 @@ def test_put_correct_body():
assert response.json() == {"item": [{"name": "Foo", "age": 5}]}
def test_put_incorrect_body():
def test_jsonable_encoder_requiring_error():
response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}])
assert response.status_code == 422
assert response.json() == single_error
def test_put_incorrect_body_multiple():
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
assert response.status_code == 422
assert response.json() == multiple_errors