Updated Some Doc

This commit is contained in:
RadinPirouz
2026-05-13 17:00:43 +03:30
parent 4cc57be794
commit 7c08e19545
3 changed files with 804 additions and 170 deletions

View File

@@ -1,12 +1,19 @@
# FastAPI POST Endpoint and JSON Input # FastAPI POST Endpoint and JSON Input
This section demonstrates how to handle **POST requests** in FastAPI to create new resources using request data and return JSON responses. ## Overview
This document explains how to create a `POST` endpoint in FastAPI for adding new users. It covers two approaches:
1. Sending input as query parameters
2. Sending input as a JSON request body using a Pydantic model
For real API development, the Pydantic model approach is recommended because it provides a cleaner structure, better validation, and more realistic request handling.
--- ---
## Example Application (POST Request) # 1. Example Application Using Query Parameters
Extend `main.py` with the following code: Create or update `main.py` with the following code:
```python ```python
from fastapi import FastAPI from fastapi import FastAPI
@@ -32,59 +39,154 @@ def create_user(name: str, age: int):
return {"msg": "User created successfully"} return {"msg": "User created successfully"}
``` ```
--- ## Explanation
## Code Overview
### POST Endpoint Definition
```python ```python
@app.post("/new_user") @app.post("/new_user")
def create_user(name: str, age: int): def create_user(name: str, age: int):
``` ```
* Registers an HTTP **POST** endpoint at `/new_user` This registers a `POST` endpoint at:
* Accepts input parameters:
* `name` → string ```http
* `age` → integer POST /new_user
* FastAPI automatically validates input types
---
### Creating a New Resource
```python
new_user = {"name": name, "age": age}
users.append(new_user)
``` ```
* Constructs a new user object The endpoint receives two parameters:
* Appends it to the in-memory `users` list
* Simulates creating a record in a database
---
### JSON Response
```python ```python
return {"msg": "User created successfully"} name: str
age: int
``` ```
* Returns a structured JSON response FastAPI automatically validates the input types. If `age` is not an integer, FastAPI returns a validation error.
* Automatically serialized by FastAPI
---
## Example Request ## Example Request
### Using `curl`
```bash ```bash
curl -X POST "http://localhost:8000/new_user?name=ali&age=25" curl -X POST "http://localhost:8000/new_user?name=ali&age=25"
``` ```
### Response ## Example Response
```json
{
"msg": "User created successfully"
}
```
## Important Note
In this version, the data is sent through query parameters, not as a JSON body.
This is acceptable for simple testing, but it is not the best practice for real APIs that create resources.
---
# 2. Recommended Application Using JSON Body
A better approach is to define a Pydantic model and receive the user data as JSON.
```python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def home_page():
return {"msg": "API is working"}
@app.post("/new_user")
def create_user(user: User):
new_user = {"name": user.name, "age": user.age}
users.append(new_user)
return {"msg": "User created successfully"}
```
## Explanation
```python
class User(BaseModel):
name: str
age: int
```
This creates a request model named `User`.
The model defines the expected structure of the JSON input:
```json
{
"name": "ali",
"age": 25
}
```
FastAPI uses this model to:
Validate incoming data
Convert JSON into a Python object
Generate automatic API documentation
Return useful validation errors when input is invalid
---
# 3. POST Endpoint Definition
```python
@app.post("/new_user")
def create_user(user: User):
```
This creates a `POST` endpoint at:
```http
POST /new_user
```
The endpoint expects a JSON request body matching the `User` model.
---
# 4. Creating a New Resource
```python
new_user = {"name": user.name, "age": user.age}
users.append(new_user)
```
This code creates a new dictionary using the received request data and appends it to the `users` list.
The `users` list acts as temporary in-memory storage.
This simulates inserting a new record into a database.
---
# 5. Returning a JSON Response
```python
return {"msg": "User created successfully"}
```
FastAPI automatically converts the returned dictionary into a JSON response.
Example response:
```json ```json
{ {
@@ -94,34 +196,174 @@ curl -X POST "http://localhost:8000/new_user?name=ali&age=25"
--- ---
## Verifying the Result # 6. Example Request Using curl
After creating a user, retrieve the updated list: ```bash
curl -X POST "http://localhost:8000/new_user" \
-H "Content-Type: application/json" \
-d '{"name": "ali", "age": 25}'
```
## Response
```json
{
"msg": "User created successfully"
}
```
---
# 7. Verifying the Result
To verify that the user was added, you should also define a `GET /users` endpoint.
```python
@app.get("/users")
def get_users():
return users
```
Then send this request:
```http ```http
GET /users GET /users
``` ```
Response will now include the newly added user. Example response:
```json
[
{
"name": "abbas",
"age": 20
},
{
"name": "mmd",
"age": 37
},
{
"name": "asghar",
"age": 19
},
{
"name": "ali",
"age": 25
}
]
```
--- ---
## Running the Application # 8. Complete Recommended Version
Start the FastAPI service using `uvicorn`: ```python
from fastapi import FastAPI, status
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def home_page():
return {"msg": "API is working"}
@app.get("/users")
def get_users():
return users
@app.post("/new_user", status_code=status.HTTP_201_CREATED)
def create_user(user: User):
new_user = {"name": user.name, "age": user.age}
users.append(new_user)
return {
"msg": "User created successfully",
"user": new_user
}
```
---
# 9. Running the Application
Start the FastAPI application using `uvicorn`:
```bash ```bash
uvicorn main:app --reload uvicorn main:app --reload
``` ```
The API will run at:
```text
http://localhost:8000
```
Interactive API documentation will be available at:
```text
http://localhost:8000/docs
```
--- ---
## Best Practices # 10. Best Practices
* POST requests should be used to create resources Use `POST` requests when creating new resources.
* Avoid modifying in-memory data in production environments
* Use request bodies with Pydantic models instead of query parameters for real APIs
* Return appropriate HTTP status codes (`201 Created`)
* Validate and sanitize all client-provided input
* Replace in-memory storage with persistent databases
Use Pydantic models for request bodies instead of query parameters.
Return proper HTTP status codes, such as:
```http
201 Created
```
Do not use in-memory lists for production data storage.
Use a real database such as PostgreSQL, MySQL, or MongoDB in production.
Validate and sanitize all client-provided input.
Keep model names clear and professional. For example, use `User` instead of `user_class`.
Return meaningful responses that include the created resource when useful.
Use `/docs` to test and verify API behavior during development.
---
# 11. Production Note for DevOps
The in-memory `users` list is reset every time the application restarts. In production environments, application data must be stored in a persistent database.
For production deployment, the FastAPI application should usually run behind a process manager and reverse proxy, such as:
```text
Gunicorn / Uvicorn workers
Nginx or Traefik
Docker or Kubernetes
PostgreSQL or another persistent database
```
The development command:
```bash
uvicorn main:app --reload
```
should not be used in production because `--reload` is intended only for local development.

View File

@@ -1,122 +0,0 @@
# FastAPI JSONResponse (Explicit JSON Responses)
This document demonstrates how to return **explicit JSON responses** in FastAPI using `JSONResponse`.
While FastAPI automatically serializes dictionaries to JSON, `JSONResponse` is useful when you need **full control** over the response.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/")
def home():
return JSONResponse(
content={"msg": "API is working"},
status_code=status.HTTP_200_OK
)
```
---
## Why Use `JSONResponse`
FastAPI automatically converts Python dictionaries into JSON responses.
However, `JSONResponse` is useful when you need to:
* Explicitly control the response type
* Set custom status codes dynamically
* Customize headers
* Return non-standard JSON structures
* Override default response behavior
---
## Response Behavior
### Endpoint
```http
GET /
```
### Response Body
```json
{
"msg": "API is working"
}
```
### HTTP Status Code
```
200 OK
```
---
## Comparison: Default Response vs JSONResponse
### Default FastAPI Response
```python
@app.get("/")
def home():
return {"msg": "API is working"}
```
* Automatically serialized to JSON
* Simpler and recommended for most cases
---
### Explicit JSONResponse
```python
return JSONResponse(
content={"msg": "API is working"},
status_code=status.HTTP_200_OK
)
```
* Explicit control over response
* Useful for advanced use cases
---
## When to Use `JSONResponse`
* Returning conditional status codes
* Adding custom headers
* Returning responses outside standard request flow
* Building middleware or exception handlers
* Integrating with legacy systems
---
## Running the Application
Start the application using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Prefer returning dictionaries for simple APIs
* Use `JSONResponse` only when additional control is required
* Keep response formats consistent across endpoints
* Avoid mixing response styles unnecessarily
* Use response models for structured APIs

View File

@@ -0,0 +1,514 @@
# FastAPI Response Model and JSONResponse
## Overview
This document explains two important FastAPI response concepts:
1. Using `response_model` to control what data is returned to the client
2. Using `JSONResponse` when you need explicit control over the response body, status code, or headers
Response models are especially useful when you want to hide sensitive fields such as passwords from API responses.
---
# 1. Response Model
## Incorrect Example
The following code has several issues:
```python
from fastapi import FastAPI, status , HTTPExption
from pydantic import BaseModel
app = FastAPI()
class usersin(BaseModel):
username: str
pass: str
class usersout(BaseModel):
username: str
@app.post("/user")
def home(user: usersin, responce_model=usersout):
return user
```
## Problems in the Code
### 1. `HTTPExption` is misspelled
Correct import:
```python
HTTPException
```
### 2. `pass` cannot be used as a field name
`pass` is a reserved keyword in Python.
Instead of:
```python
pass: str
```
Use:
```python
password: str
```
### 3. `response_model` is written in the wrong place
This is incorrect:
```python
def home(user: usersin, responce_model=usersout):
```
`response_model` must be passed inside the route decorator.
Correct:
```python
@app.post("/user", response_model=UserOut)
```
### 4. `responce_model` is misspelled
Correct spelling:
```python
response_model
```
---
# 2. Correct Response Model Example
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
class UserOut(BaseModel):
username: str
@app.post("/user", response_model=UserOut)
def create_user(user: UserIn):
return user
```
---
# 3. How Response Model Works
## Input Model
```python
class UserIn(BaseModel):
username: str
password: str
```
This model defines the data that the API receives from the client.
Example request body:
```json
{
"username": "abbas",
"password": "123456"
}
```
The API accepts both fields:
```text
username
password
```
---
## Output Model
```python
class UserOut(BaseModel):
username: str
```
This model defines the data that the API returns to the client.
Even though the endpoint receives the password, the response only returns the username.
Example response:
```json
{
"username": "abbas"
}
```
The password is removed from the response automatically.
---
# 4. Endpoint Definition
```python
@app.post("/user", response_model=UserOut)
def create_user(user: UserIn):
return user
```
This creates a `POST` endpoint at:
```http
POST /user
```
The endpoint receives data based on `UserIn` and returns data based on `UserOut`.
FastAPI uses `response_model` to filter the response before sending it to the client.
---
# 5. Example Request
## Using curl
```bash
curl -X POST "http://localhost:8000/user" \
-H "Content-Type: application/json" \
-d '{"username": "abbas", "password": "123456"}'
```
## Response
```json
{
"username": "abbas"
}
```
The password is not included in the response.
---
# 6. Why Use Response Models
Response models are useful because they help you:
Protect sensitive data
Keep API responses consistent
Control exactly what the client receives
Improve automatic documentation
Validate response data before sending it
Separate input schemas from output schemas
---
# 7. Better Version with Status Code
For user creation endpoints, it is better to return `201 Created`.
```python
from fastapi import FastAPI, status
from pydantic import BaseModel
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
class UserOut(BaseModel):
username: str
@app.post(
"/user",
response_model=UserOut,
status_code=status.HTTP_201_CREATED
)
def create_user(user: UserIn):
return user
```
---
# 8. JSONResponse
FastAPI automatically converts Python dictionaries into JSON responses.
For most endpoints, this is enough:
```python
@app.get("/")
def home():
return {"msg": "API is working"}
```
However, FastAPI also allows you to use `JSONResponse` when you need more control.
---
# 9. Example Application Using JSONResponse
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/")
def home():
return JSONResponse(
content={"msg": "API is working"},
status_code=status.HTTP_200_OK
)
```
---
# 10. Response Behavior
## Endpoint
```http
GET /
```
## Response Body
```json
{
"msg": "API is working"
}
```
## HTTP Status Code
```http
200 OK
```
---
# 11. Default Response vs JSONResponse
## Default FastAPI Response
```python
@app.get("/")
def home():
return {"msg": "API is working"}
```
This is the recommended style for most simple APIs.
FastAPI automatically serializes the dictionary into JSON.
---
## Explicit JSONResponse
```python
return JSONResponse(
content={"msg": "API is working"},
status_code=status.HTTP_200_OK
)
```
This gives more direct control over the response.
---
# 12. When to Use JSONResponse
Use `JSONResponse` when you need to:
Return dynamic status codes
Add custom headers
Customize the response structure manually
Return responses from exception handlers
Return responses from middleware
Override FastAPIs default response behavior
---
# 13. Example: JSONResponse with Custom Status Code
```python
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
@app.post("/login")
def login():
return JSONResponse(
content={"msg": "Login successful"},
status_code=status.HTTP_200_OK
)
```
---
# 14. Example: JSONResponse with Headers
```python
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/custom")
def custom_response():
return JSONResponse(
content={"msg": "Custom response"},
headers={"X-App-Version": "1.0.0"}
)
```
---
# 15. Complete Example with Response Model and JSONResponse
```python
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
class UserOut(BaseModel):
username: str
@app.get("/")
def home():
return JSONResponse(
content={"msg": "API is working"},
status_code=status.HTTP_200_OK
)
@app.post(
"/user",
response_model=UserOut,
status_code=status.HTTP_201_CREATED
)
def create_user(user: UserIn):
return user
```
---
# 16. Running the Application
Start the FastAPI application using `uvicorn`:
```bash
uvicorn main:app --reload
```
The API will run at:
```text
http://localhost:8000
```
Interactive API documentation will be available at:
```text
http://localhost:8000/docs
```
---
# 17. Best Practices
Use `response_model` to control API output.
Never return sensitive data such as passwords, tokens, or secrets.
Use separate models for input and output.
Use clear class names such as `UserIn` and `UserOut`.
Use `password` instead of `pass` because `pass` is a reserved Python keyword.
Place `response_model` inside the route decorator, not inside the function parameters.
Prefer returning normal dictionaries for simple responses.
Use `JSONResponse` only when extra control is required.
Use proper HTTP status codes, such as:
```http
200 OK
201 Created
400 Bad Request
401 Unauthorized
404 Not Found
500 Internal Server Error
```
Do not use `uvicorn --reload` in production.
---
# 18. DevOps Production Note
In production, the FastAPI application should usually run behind a production-grade ASGI server setup and a reverse proxy.
A common production stack is:
```text
FastAPI
Gunicorn with Uvicorn workers
Nginx or Traefik
Docker or Kubernetes
PostgreSQL or another persistent database
```
The development command:
```bash
uvicorn main:app --reload
```
is only for local development.
For production, use a more stable process configuration, such as Gunicorn with Uvicorn workers, container health checks, logging, monitoring, and proper secret management.