diff --git a/Docs/Libs/FastAPI/04-Post-Method.md b/Docs/Libs/FastAPI/04-Post-Method.md index dbb5f6a..17ad8b3 100644 --- a/Docs/Libs/FastAPI/04-Post-Method.md +++ b/Docs/Libs/FastAPI/04-Post-Method.md @@ -1,12 +1,19 @@ # 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 from fastapi import FastAPI @@ -32,59 +39,154 @@ def create_user(name: str, age: int): return {"msg": "User created successfully"} ``` ---- - -## Code Overview - -### POST Endpoint Definition +## Explanation ```python @app.post("/new_user") def create_user(name: str, age: int): ``` -* Registers an HTTP **POST** endpoint at `/new_user` -* Accepts input parameters: +This registers a `POST` endpoint at: - * `name` → string - * `age` → integer -* FastAPI automatically validates input types - ---- - -### Creating a New Resource - -```python -new_user = {"name": name, "age": age} -users.append(new_user) +```http +POST /new_user ``` -* Constructs a new user object -* Appends it to the in-memory `users` list -* Simulates creating a record in a database - ---- - -### JSON Response +The endpoint receives two parameters: ```python -return {"msg": "User created successfully"} +name: str +age: int ``` -* Returns a structured JSON response -* Automatically serialized by FastAPI - ---- +FastAPI automatically validates the input types. If `age` is not an integer, FastAPI returns a validation error. ## Example Request -### Using `curl` - ```bash 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 { @@ -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 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 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 -* 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 `POST` requests when creating new resources. +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. diff --git a/Docs/Libs/FastAPI/09-Json-Responce.md b/Docs/Libs/FastAPI/09-Json-Responce.md deleted file mode 100644 index 05ccade..0000000 --- a/Docs/Libs/FastAPI/09-Json-Responce.md +++ /dev/null @@ -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 - diff --git a/Docs/Libs/FastAPI/09-Responces.md b/Docs/Libs/FastAPI/09-Responces.md new file mode 100644 index 0000000..03d3c67 --- /dev/null +++ b/Docs/Libs/FastAPI/09-Responces.md @@ -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 FastAPI’s 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.