update services doc to libs

This commit is contained in:
RadinPirouz
2026-01-23 23:21:00 +03:30
parent 6be588aa58
commit 6fbd717868
16 changed files with 1 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
# FastAPI Environment Setup
This document describes the initial setup required to prepare a Python environment for developing a FastAPI application.
The steps below ensure isolation, dependency management, and reproducibility across environments.
---
## Prerequisites
Before starting, ensure the following are installed on your system:
* Python 3.8 or higher
* `pip` (Python package manager)
* `venv` module (included by default with most Python installations)
You can verify your Python version with:
```bash
python3 --version
```
---
## Step 1: Create a Virtual Environment
A virtual environment isolates project dependencies and prevents conflicts with system-wide Python packages.
From the project root directory, run:
```bash
python3 -m venv .venv
```
This command creates a `.venv` directory containing the isolated Python environment.
---
## Step 2: Activate the Virtual Environment
Activate the virtual environment before installing any dependencies.
### Linux / macOS
```bash
source .venv/bin/activate
```
### Windows (PowerShell)
```powershell
.venv\Scripts\Activate.ps1
```
After activation, your shell prompt should indicate that the virtual environment is active.
---
## Step 3: Install FastAPI
With the virtual environment activated, install FastAPI using `pip`:
```bash
pip install fastapi
```
This installs the FastAPI framework and its required dependencies.
> Note: In a real application, FastAPI is commonly used with an ASGI server such as `uvicorn`, which can be installed later if needed.
---
## Step 4: Freeze Dependencies
To ensure reproducibility across environments (local, CI/CD, staging, production), export the installed dependencies to a requirements file:
```bash
pip freeze > requirement.txt
```
This file should be committed to version control and used by deployment pipelines to install exact dependency versions.
---
## Resulting Files
After completing the steps above, your project directory should include:
* `.venv/` Python virtual environment (should not be committed to VCS)
* `requirement.txt` Dependency lock file
---
## Best Practices
* Always activate the virtual environment before working on the project
* Do not commit `.venv/` to source control
* Keep `requirement.txt` updated when adding or upgrading dependencies
* Use the same `requirement.txt` in CI/CD pipelines for consistent builds
---

View File

@@ -0,0 +1,90 @@
# FastAPI Simple Route Example
This document demonstrates how to create a basic FastAPI application with a single HTTP route and how to run it using `uvicorn`, which is the default and recommended ASGI server for FastAPI.
---
## Create a Simple FastAPI Application
Create a Python file named `main.py` and add the following content:
```python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home_dir():
return {"message": "Home Page"}
```
### Explanation
* `FastAPI()` initializes the application instance.
* `@app.get("/")` registers an HTTP GET endpoint at the root path (`/`).
* The `home_dir` function is the request handler and returns a JSON response.
* FastAPI automatically handles JSON serialization and response headers.
---
## Running the Application
FastAPI applications are typically run using **uvicorn**, an ASGI server designed for high performance.
### Option 1: Run Using FastAPI CLI (Development Mode)
FastAPI provides a development-friendly CLI wrapper that uses `uvicorn` internally:
```bash
fastapi dev main.py
```
This command:
* Starts the application in development mode
* Enables auto-reload on code changes
* Automatically binds to a local development interface
---
### Option 2: Run Directly with Uvicorn (Recommended)
For explicit control over runtime configuration, run the application directly with `uvicorn`:
```bash
uvicorn main:app --reload --host 0.0.0.0 --port 1234
```
#### Command Breakdown
* `main` → Python file name (without `.py`)
* `app` → FastAPI application instance
* `--reload` → Automatically reloads the server on code changes (development only)
* `--host 0.0.0.0` → Exposes the service on all network interfaces
* `--port 1234` → Custom application port
---
## Accessing the Application
Once running, the application will be available at:
* API Endpoint:
`http://localhost:1234/`
* Interactive API Docs (Swagger UI):
`http://localhost:1234/docs`
* Alternative API Docs (ReDoc):
`http://localhost:1234/redoc`
---
## Best Practices
* Use `--reload` only in development environments
* In production, run `uvicorn` behind a process manager (e.g., systemd, Docker, Kubernetes)
* Explicitly define host and port for containerized and cloud deployments
* Keep the application entry point (`main:app`) consistent across environments

View File

@@ -0,0 +1,169 @@
# FastAPI GET Endpoints and JSON Responses
This document demonstrates how to define multiple **GET endpoints** in FastAPI, return JSON responses, and use **path parameters** to retrieve specific data from an in-memory dataset.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def root_dir():
return {"message": "API is working"}
@app.get("/users")
def get_users():
return users
@app.get("/user/{name_input}")
def get_user_by_name(name_input: str):
for item in users:
if item["name"] == name_input:
return {"information": item}
return {"message": "User not found"}
```
---
## Code Overview
### Application Initialization
```python
app = FastAPI()
```
Initializes the FastAPI application instance.
---
### In-Memory Data Store
```python
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
```
* Simulates a database using a Python list
* Each user is represented as a JSON-compatible dictionary
* Suitable for development and testing purposes
---
## Defined Endpoints
### Root Endpoint
```http
GET /
```
**Response:**
```json
{
"message": "API is working"
}
```
Used as a health check or readiness probe.
---
### Get All Users
```http
GET /users
```
**Response:**
```json
[
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19}
]
```
Returns the full list of users as JSON.
---
### Get User by Name (Path Parameter)
```http
GET /user/{name_input}
```
**Example Request:**
```http
GET /user/abbas
```
**Successful Response:**
```json
{
"information": {
"name": "abbas",
"age": 20
}
}
```
**Failure Response:**
```json
{
"message": "User not found"
}
```
---
## Path Parameters
* `name_input` is a dynamic path parameter
* Automatically validated and converted to `str` by FastAPI
* Used to filter data at runtime
---
## Running the Application
Use `uvicorn` to start the service:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Use structured JSON responses (`key: value`) instead of tuples
* Validate user input when moving beyond in-memory data
* Replace in-memory storage with a database for production
* Use proper HTTP status codes (`404`, `200`) in real-world APIs
* Separate routing, models, and business logic as the project grows

View File

@@ -0,0 +1,127 @@
# 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.
---
## Example Application (POST Request)
Extend `main.py` with the following code:
```python
from fastapi import FastAPI
app = FastAPI()
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(name: str, age: int):
new_user = {"name": name, "age": age}
users.append(new_user)
return {"msg": "User created successfully"}
```
---
## Code Overview
### POST Endpoint Definition
```python
@app.post("/new_user")
def create_user(name: str, age: int):
```
* Registers an HTTP **POST** endpoint at `/new_user`
* Accepts input parameters:
* `name` → string
* `age` → integer
* 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
* Appends it to the in-memory `users` list
* Simulates creating a record in a database
---
### JSON Response
```python
return {"msg": "User created successfully"}
```
* Returns a structured JSON response
* Automatically serialized by FastAPI
---
## Example Request
### Using `curl`
```bash
curl -X POST "http://localhost:8000/new_user?name=ali&age=25"
```
### Response
```json
{
"msg": "User created successfully"
}
```
---
## Verifying the Result
After creating a user, retrieve the updated list:
```http
GET /users
```
Response will now include the newly added user.
---
## Running the Application
Start the FastAPI service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## 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

View File

@@ -0,0 +1,162 @@
# FastAPI PUT Method
This document demonstrates how to use the **HTTP PUT method** in FastAPI to update an existing resource.
It builds on previous GET and POST examples and completes a basic CRUD-style workflow.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI
app = FastAPI()
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 show_users():
return users
@app.post("/create_user")
def create_user(name: str, age: int):
new_user = {"name": name, "age": age}
users.append(new_user)
return {"msg": f"user {name} with age {age} created"}
@app.put("/update_user/{target_name}")
def update_user(target_name: str, age: int):
for user in users:
if user["name"] == target_name:
user["age"] = age
return {"msg": f"user {target_name} updated"}
return {"msg": "user not found"}
```
---
## Code Overview
### PUT Endpoint Definition
```python
@app.put("/update_user/{target_name}")
def update_user(target_name: str, age: int):
```
* Registers an HTTP **PUT** endpoint
* `target_name` is a **path parameter**
* `age` is a **query parameter**
* Used to update an existing users data
---
### Update Logic
```python
for user in users:
if user["name"] == target_name:
user["age"] = age
```
* Iterates over the in-memory users list
* Matches user by name
* Updates the `age` field in place
---
### Success Response
```json
{
"msg": "user abbas updated"
}
```
Returned when the target user exists and is updated successfully.
---
### Failure Response
```json
{
"msg": "user not found"
}
```
Returned when no matching user exists.
---
## Example Requests
### Update User Age (PUT)
```bash
curl -X PUT "http://localhost:8000/update_user/abbas?age=25"
```
### Verify Update
```http
GET /users
```
Updated response:
```json
[
{"name": "abbas", "age": 25},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19}
]
```
---
## Running the Application
Start the service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## HTTP Method Summary
| Method | Endpoint | Purpose |
| ------ | --------------------- | ----------------------- |
| GET | `/` | Health check |
| GET | `/users` | Retrieve all users |
| POST | `/create_user` | Create a new user |
| PUT | `/update_user/{name}` | Update an existing user |
---
## Best Practices
* Use **PUT** for full updates and **PATCH** for partial updates
* Return proper HTTP status codes (`404`, `200`, `201`)
* Avoid using in-memory data stores in production
* Use Pydantic models for request bodies instead of query parameters
* Add input validation and error handling
* Separate routes, services, and models as the project grows
* Make PUT operations idempotent

View File

@@ -0,0 +1,172 @@
# FastAPI DELETE Method (Remove Resource)
This document demonstrates how to use the **HTTP DELETE method** in FastAPI to remove an existing resource.
It completes the CRUD workflow using **GET, POST, PUT, and DELETE** operations.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI
app = FastAPI()
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 show_users():
return users
@app.post("/create_user")
def create_user(name: str, age: int):
new_user = {"name": name, "age": age}
users.append(new_user)
return {"msg": f"user {name} with age {age} created"}
@app.put("/update_user/{target_name}")
def update_user(target_name: str, age: int):
for user in users:
if user["name"] == target_name:
user["age"] = age
return {"msg": f"user {target_name} updated"}
return {"msg": "user not found"}
@app.delete("/delete_user/{target_name}")
def delete_user(target_name: str):
for user in users:
if user["name"] == target_name:
users.remove(user)
return {"msg": f"user {target_name} deleted"}
return {"msg": "user not found"}
```
---
## Code Overview
### DELETE Endpoint Definition
```python
@app.delete("/delete_user/{target_name}")
def delete_user(target_name: str):
```
* Registers an HTTP **DELETE** endpoint
* `target_name` is a **path parameter**
* Used to remove a user from the data store
---
### Delete Logic
```python
for user in users:
if user["name"] == target_name:
users.remove(user)
```
* Iterates through the users list
* Finds a matching user by name
* Removes the user from the list
---
### Success Response
```json
{
"msg": "user abbas deleted"
}
```
Returned when the user is successfully removed.
---
### Failure Response
```json
{
"msg": "user not found"
}
```
Returned when the specified user does not exist.
---
## Example Requests
### Delete a User
```bash
curl -X DELETE "http://localhost:8000/delete_user/abbas"
```
---
### Verify Deletion
```http
GET /users
```
Response:
```json
[
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19}
]
```
---
## Running the Application
Start the service with `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## CRUD Endpoint Summary
| Method | Endpoint | Description |
| ------ | --------------------- | ------------------ |
| GET | `/` | Health check |
| GET | `/users` | Retrieve all users |
| POST | `/create_user` | Create a user |
| PUT | `/update_user/{name}` | Update a user |
| DELETE | `/delete_user/{name}` | Delete a user |
---
## Best Practices
* Use **DELETE** only for resource removal
* Return appropriate HTTP status codes (`204`, `404`)
* Ensure delete operations are idempotent
* Avoid modifying in-memory data in production
* Add authentication and authorization for destructive operations
* Log delete actions for auditability
* Use database transactions when deleting persistent data

View File

@@ -0,0 +1,199 @@
# FastAPI Query Parameters
This document demonstrates how to use **query parameters** in FastAPI using multiple typing styles, including:
* Native Python union types (`str | None`)
* `Optional` from `typing`
* `Annotated` with `Query` validation
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, Query
from typing import Optional, Annotated
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "abbas", "age": 32},
{"name": "abbas", "age": 54},
{"name": "abbas", "age": 15},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def home_page():
return {"msg": "API is working"}
@app.get("/user")
def get_users(target_name: str | None = None):
if target_name:
return [item for item in users if item["name"] == target_name]
return users
@app.get("/user2")
def get_users_optional(target_name: Optional[str] = None):
if target_name:
return [item for item in users if item["name"] == target_name]
return users
@app.get("/user3")
def get_users_annotated(
target_name: Annotated[str | None, Query(max_length=50)] = None
):
if target_name:
return [item for item in users if item["name"] == target_name]
return users
```
---
## Query Parameter Overview
Query parameters are key-value pairs appended to the URL after `?`.
**Example:**
```
/user?target_name=abbas
```
---
## Defined Endpoints
### 1. Basic Query Parameter (Python Union Type)
```python
@app.get("/user")
def get_users(target_name: str | None = None):
```
* Uses Python 3.10+ union syntax
* `target_name` is optional
* If not provided, all users are returned
**Example Request:**
```
GET /user?target_name=abbas
```
---
### 2. Optional Query Parameter (`typing.Optional`)
```python
@app.get("/user2")
def get_users_optional(target_name: Optional[str] = None):
```
* Uses `Optional[str]` for compatibility with older Python versions
* Behavior is identical to the first endpoint
**Example Request:**
```
GET /user2?target_name=abbas
```
---
### 3. Validated Query Parameter (`Annotated + Query`)
```python
@app.get("/user3")
def get_users_annotated(
target_name: Annotated[str | None, Query(max_length=50)] = None
):
```
* Uses `Annotated` for metadata binding
* Adds validation rules:
* `max_length=50`
* Automatically returns validation errors if constraints are violated
**Example Invalid Request:**
```
GET /user3?target_name=verylongnamethatexceedslimit...
```
**Response:**
```json
{
"detail": [
{
"type": "string_too_long",
"loc": ["query", "target_name"],
"msg": "String should have at most 50 characters",
"input": "..."
}
]
}
```
---
## Example Responses
### Filtered Response
```json
[
{"name": "abbas", "age": 20},
{"name": "abbas", "age": 32},
{"name": "abbas", "age": 54},
{"name": "abbas", "age": 15}
]
```
---
### Default Response (No Query Parameter)
```json
[
{"name": "abbas", "age": 20},
{"name": "abbas", "age": 32},
{"name": "abbas", "age": 54},
{"name": "abbas", "age": 15},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19}
]
```
---
## Running the Application
Start the service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Use query parameters for filtering and searching
* Always provide defaults for optional parameters
* Use `Query()` for validation and constraints
* Return full datasets when no filters are applied
* Avoid large in-memory datasets in production
* Use pagination for large result sets
* Combine query parameters with database queries in real systems

View File

@@ -0,0 +1,192 @@
# FastAPI HTTP Status Codes and Error Handling
This document demonstrates how to use **HTTP status codes** in FastAPI to accurately represent the result of an API operation.
Correct status codes improve API reliability, observability, and client-side behavior.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, status, HTTPException
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/", status_code=status.HTTP_200_OK)
def home_page():
return {"msg": "API is working"}
@app.get("/users", status_code=status.HTTP_200_OK)
def show_users():
return users
@app.post("/create_user", status_code=status.HTTP_201_CREATED)
def create_user(name: str, age: int):
new_user = {"name": name, "age": age}
users.append(new_user)
return {"msg": f"user {name} with age {age} created"}
@app.put("/update_user/{target_name}", status_code=status.HTTP_202_ACCEPTED)
def update_user(target_name: str, age: int):
for user in users:
if user["name"] == target_name:
user["age"] = age
return {"msg": f"user {target_name} updated"}
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
@app.delete("/delete_user/{target_name}", status_code=status.HTTP_204_NO_CONTENT)
def delete_user(target_name: str):
for user in users:
if user["name"] == target_name:
users.remove(user)
return
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
```
---
## Status Code Overview
HTTP status codes communicate the result of an API request to clients and monitoring systems.
| Code | Meaning | Usage |
| ---- | ---------- | --------------------------------- |
| 200 | OK | Successful GET requests |
| 201 | Created | Resource successfully created |
| 202 | Accepted | Update request accepted |
| 204 | No Content | Resource deleted successfully |
| 404 | Not Found | Requested resource does not exist |
---
## Endpoint Behavior
### Root Endpoint
```http
GET /
```
* Returns HTTP **200 OK**
* Used as a health check
---
### Create User
```http
POST /create_user
```
* Returns HTTP **201 Created**
* Indicates successful resource creation
---
### Update User
```http
PUT /update_user/{target_name}
```
* Returns HTTP **202 Accepted** on success
* Raises HTTP **404 Not Found** if user does not exist
---
### Delete User
```http
DELETE /delete_user/{target_name}
```
* Returns HTTP **204 No Content** on success
* Returns no response body
* Raises HTTP **404 Not Found** if user does not exist
---
## Error Handling with `HTTPException`
```python
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
```
* Immediately stops request processing
* Returns structured error responses
* Automatically serialized by FastAPI
**Error Response Example:**
```json
{
"detail": "User not found"
}
```
---
## Example Requests
### Create User
```bash
curl -X POST "http://localhost:8000/create_user?name=ali&age=25"
```
### Update User
```bash
curl -X PUT "http://localhost:8000/update_user/ali?age=30"
```
### Delete User
```bash
curl -X DELETE "http://localhost:8000/delete_user/ali"
```
---
## Running the Application
Start the application using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Always return meaningful HTTP status codes
* Use `status` module instead of hard-coded numbers
* Use `HTTPException` for predictable error handling
* Do not return response bodies with `204 No Content`
* Align status codes with REST conventions
* Ensure monitoring systems rely on status codes, not messages
* Standardize error formats across services

View File

@@ -0,0 +1,122 @@
# 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,238 @@
# FastAPI Advanced Path and Query Parameters
This document demonstrates advanced usage of **path parameters** and **query parameters** in FastAPI, including:
* Validation rules
* Aliases
* Descriptions for OpenAPI
* Deprecation flags
* Clear separation of responsibilities between path and query parameters
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, Query, Path, status
from fastapi.responses import JSONResponse
app = FastAPI()
users_db = [
{"id": "1", "name": "radin"}
]
@app.get("/user/{target_id}")
def get_user_by_path(
target_id: int = Path(
...,
alias="User ID",
description="Enter target unique ID",
deprecated=True,
)
):
for item in users_db:
if int(item["id"]) == target_id:
return JSONResponse(
content={"msg": f"Your target user name is {item['name']}"},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"msg": "user not found"},
status_code=status.HTTP_404_NOT_FOUND,
)
@app.get("/user")
def get_user_by_query(
target: int | None = Query(
default=None,
gt=0,
alias="User ID",
description="Enter target unique ID",
)
):
for item in users_db:
if item["id"] == str(target):
return JSONResponse(
content={"msg": f"Your target user name is {item['name']}"},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"msg": "user not found"},
status_code=status.HTTP_404_NOT_FOUND,
)
```
---
## Path Parameter Example
### Endpoint
```http
GET /user/{target_id}
```
**Example Request:**
```
/user/1
```
### Characteristics
* Always required
* Defined as part of the route
* Used to identify a specific resource
* Missing value results in **404 Not Found**
* Supports validation, aliases, and documentation metadata
---
## Query Parameter Example
### Endpoint
```http
GET /user?User%20ID=1
```
### Characteristics
* Optional by default
* Used for filtering and searching
* Not part of the route path
* Supports validation and documentation metadata
* Uses default values when not provided
---
## Advanced Parameter Configuration
### `Path()` Example
```python
Path(
...,
alias="User ID",
description="Enter target unique ID",
deprecated=True
)
```
* `...` → parameter is required
* `alias` → custom name in documentation and URL
* `description` → shown in Swagger UI
* `deprecated` → marked as deprecated in OpenAPI
---
### `Query()` Example
```python
Query(
default=None,
gt=0,
alias="User ID",
description="Enter target unique ID"
)
```
* `gt=0` → value must be greater than zero
* Optional parameter with validation rules
* Appears in API documentation
---
## Path vs Query Parameters
### 1. Path Parameters
**What they are**
Values embedded directly in the URL path that identify a specific resource.
**When to use**
When the parameter is mandatory and uniquely identifies a resource.
**Example URL**
```
/users/42
```
**FastAPI Example**
```python
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
```
**Key Points**
* Always required
* Part of the route definition
* Used for IDs and unique identifiers
* Missing value → 404 error
---
### 2. Query Parameters
**What they are**
Key-value pairs appended to the URL after `?`.
**When to use**
For optional filtering, searching, sorting, and pagination.
**Example URL**
```
/users?limit=10&active=true
```
**FastAPI Example**
```python
@app.get("/users")
def list_users(limit: int = 10, active: bool = True):
return {"limit": limit, "active": active}
```
**Key Points**
* Optional by default
* Not part of the route path
* Used to modify or filter results
* Defaults are used when missing
---
## Side-by-Side Comparison
| Feature | Path Parameter | Query Parameter |
| ------------- | ------------------- | --------------------------------- |
| Location | Inside URL path | After `?` |
| Required | Yes | No (by default) |
| Purpose | Identify a resource | Filter or modify results |
| Example | `/items/5` | `/items?limit=10` |
| Missing Value | 404 Not Found | Default value or validation error |
---
## Best Practices
* Use path parameters for resource identification
* Use query parameters for filtering and modifiers
* Avoid spaces in parameter aliases for production APIs
* Deprecate parameters instead of removing them
* Use validation (`gt`, `lt`, `regex`) for safer APIs
* Keep URL design consistent across services
* Prefer response models over manual JSON responses when possible

View File

@@ -0,0 +1,226 @@
# POST Request Types and Content Types
This document explains the **body types of POST requests** and the most common **Content-Types** used in APIs.
Understanding these formats is essential for building interoperable and production-ready FastAPI services.
---
## POST Request Body Types
A POST request sends data to the server in the **request body**.
The format of this data is defined by the **Content-Type** header.
---
## 1. Form Data
### Description
Used primarily for HTML form submissions. Common in browser-based applications.
### Content-Type
```
application/x-www-form-urlencoded
```
or
```
multipart/form-data
```
### Characteristics
* Key-value pairs
* Supports file uploads (multipart)
* Common in login and upload forms
### Example
```http
POST /login
Content-Type: application/x-www-form-urlencoded
username=admin&password=secret
```
---
## 2. JSON
### Description
The most common data format for REST APIs.
### Content-Type
```
application/json
```
### Characteristics
* Structured, readable, and language-independent
* Easily parsed and validated
* Default choice for FastAPI APIs
### Example
```json
{
"name": "abbas",
"age": 25
}
```
---
## 3. XML
### Description
An older but still widely used data format in enterprise systems and legacy APIs.
### Content-Type
```
application/xml
```
or
```
text/xml
```
### Characteristics
* Verbose and schema-driven
* Common in SOAP-based services
* Less common in modern REST APIs
### Example
```xml
<user>
<name>abbas</name>
<age>25</age>
</user>
```
---
## 4. Plain Text
### Description
Used when sending raw text without structure.
### Content-Type
```
text/plain
```
### Characteristics
* No schema or structure
* Useful for logs, messages, or simple payloads
* Requires custom parsing on the server
### Example
```
Hello FastAPI
```
---
## 5. Binary Data
### Description
Used for sending non-textual data such as images, videos, or files.
### Content-Type
```
application/octet-stream
```
### Characteristics
* Raw binary format
* Common for file uploads and downloads
* Requires stream handling
### Example
```
(binary file data)
```
---
## 6. GraphQL
### Description
GraphQL uses POST requests to execute queries and mutations.
### Content-Type
```
application/json
```
### Characteristics
* Single endpoint
* Flexible client-driven queries
* Requires GraphQL server support
### Example
```json
{
"query": "query { users { id name } }"
}
```
---
## Common Content Types Summary
| Content-Type | Usage |
| ----------------------------------- | -------------------------- |
| `application/json` | REST APIs (default) |
| `application/x-www-form-urlencoded` | HTML forms |
| `multipart/form-data` | Forms with file uploads |
| `application/xml` | Legacy / SOAP APIs |
| `text/plain` | Raw text |
| `application/octet-stream` | Binary data |
| `application/graphql` | GraphQL (rare, often JSON) |
---
## FastAPI Considerations
* JSON is the recommended default for FastAPI
* Use Pydantic models for JSON validation
* Use `Form()` and `File()` for form and file uploads
* Always validate content type in production APIs
* Document supported content types clearly
---
## Best Practices
* Choose the simplest format that meets requirements
* Prefer `application/json` for APIs
* Avoid XML unless required by integration
* Secure file uploads (size limits, scanning)
* Validate all incoming request bodies
* Be explicit about supported Content-Types

View File

@@ -0,0 +1,165 @@
# FastAPI POST Requests with Form Data
This document demonstrates how to handle **form-based POST requests** in FastAPI using the `Form()` dependency.
Form data is commonly used in **HTML forms**, authentication flows, and legacy systems.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, Form, status
from fastapi.responses import JSONResponse
app = FastAPI()
users_db = [
{"id": "1", "name": "radin", "password": "123"}
]
@app.post("/user/")
def get_user_from_form(
target: int = Form(
...,
gt=0,
alias="User ID",
description="Enter target unique ID",
)
):
for item in users_db:
if item["id"] == str(target):
return JSONResponse(
content={"msg": f"Your target user name is {item['name']}"},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"msg": "user not found"},
status_code=status.HTTP_404_NOT_FOUND,
)
```
---
## Form Data Overview
### What is Form Data
Form data is sent in the request body using:
```
Content-Type: application/x-www-form-urlencoded
```
or
```
multipart/form-data
```
FastAPI requires the `Form()` dependency to explicitly declare form inputs.
---
## Endpoint Behavior
### Endpoint
```http
POST /user/
```
### Request Body (Form Data)
```
User ID=1
```
### Example Using `curl`
```bash
curl -X POST "http://localhost:8000/user/" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "User ID=1"
```
---
## Response Examples
### Success Response
```json
{
"msg": "Your target user name is radin"
}
```
Status Code: **200 OK**
---
### Failure Response
```json
{
"msg": "user not found"
}
```
Status Code: **404 Not Found**
---
## `Form()` Parameter Configuration
```python
Form(
...,
gt=0,
alias="User ID",
description="Enter target unique ID"
)
```
| Parameter | Description |
| ------------- | ------------------------------- |
| `...` | Field is required |
| `gt=0` | Value must be greater than zero |
| `alias` | Custom form field name |
| `description` | Displayed in API docs |
---
## Swagger / OpenAPI Behavior
* Form fields appear as input fields
* Aliases are reflected in the UI
* Validation rules are enforced automatically
* Errors are returned with clear messages
---
## Running the Application
Start the service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Use form data only when required (e.g. HTML forms)
* Prefer JSON for APIs and services
* Avoid exposing sensitive fields in plain form data
* Use HTTPS for all form submissions
* Validate and sanitize all inputs
* Use authentication and hashing for passwords
* Do not store credentials in plain text

View File

@@ -0,0 +1,161 @@
# FastAPI POST Requests with JSON Body (`Body`)
This document demonstrates how to receive data from the **request body** using `Body()` in FastAPI.
This approach is commonly used when clients send **JSON payloads**.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, Body, status
from fastapi.responses import JSONResponse
app = FastAPI()
users_db = [
{"id": "1", "name": "radin", "password": "123"}
]
@app.post("/user/")
def get_user_from_body(
target: int = Body(
...,
embed=True,
gt=0,
alias="User ID",
description="Enter target unique ID",
)
):
for item in users_db:
if item["id"] == str(target):
return JSONResponse(
content={"msg": f"Your target user name is {item['name']}"},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"msg": "user not found"},
status_code=status.HTTP_404_NOT_FOUND,
)
```
---
## JSON Body Overview
### What Is a Request Body
The request body contains structured data sent by the client, most commonly as **JSON**.
**Content-Type:**
```
application/json
```
---
## Request Format
### Example JSON Payload
```json
{
"User ID": 1
}
```
* `embed=True` requires the value to be wrapped inside a JSON object
* The key name is controlled by the `alias`
---
## Example Request Using `curl`
```bash
curl -X POST "http://localhost:8000/user/" \
-H "Content-Type: application/json" \
-d '{"User ID": 1}'
```
---
## Response Examples
### Success Response
```json
{
"msg": "Your target user name is radin"
}
```
Status Code: **200 OK**
---
### Failure Response
```json
{
"msg": "user not found"
}
```
Status Code: **404 Not Found**
---
## `Body()` Parameter Configuration
```python
Body(
...,
embed=True,
gt=0,
alias="User ID",
description="Enter target unique ID"
)
```
| Parameter | Purpose |
| ------------- | -------------------------------- |
| `...` | Field is required |
| `embed=True` | Wraps the value in a JSON object |
| `gt=0` | Validates input value |
| `alias` | Custom JSON key name |
| `description` | Shown in API documentation |
---
## Swagger / OpenAPI Behavior
* JSON schema is automatically generated
* Validation errors are returned if rules are violated
* Aliases and descriptions appear in Swagger UI
* Request body is clearly documented
---
## Running the Application
Start the service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Prefer request body over query parameters for POST requests
* Use Pydantic models instead of raw `Body()` for complex payloads
* Keep JSON structures consistent
* Avoid spaces in JSON keys for production APIs
* Never send sensitive data in plain text
* Use HTTPS for all JSON-based APIs

View File

@@ -0,0 +1,167 @@
# FastAPI POST Requests with File Uploads
This document demonstrates how to handle **file uploads** in FastAPI.
File uploads are essential for APIs that need to receive **images, documents, or binary data** from clients.
---
## Example Application
Create or update `main.py` with the following content:
```python
from fastapi import FastAPI, File, UploadFile, status
from fastapi.responses import JSONResponse
from typing import List
app = FastAPI()
users_db = [
{"id": "1", "name": "radin", "password": "123"}
]
@app.post("/file")
def upload_file_bytes(file: bytes = File(...)):
"""
Receive file as raw bytes.
Returns the size of the uploaded file.
"""
return {"file_size": len(file)}
@app.post("/uploadfile")
def upload_file_uploadfile(file: UploadFile):
"""
Receive file as UploadFile.
Returns filename, content type, and size.
"""
content = file.read()
return {
"filename": file.filename,
"content_type": file.content_type,
"file_size": len(content)
}
@app.post("/uploadmultifile")
def upload_multiple_files(files: List[UploadFile]):
"""
Receive multiple files as UploadFile list.
Returns filenames and content types.
"""
return [
{"filename": file.filename, "content_type": file.content_type}
for file in files
]
```
---
## File Upload Methods
### 1. `File` as Bytes
* Accepts the uploaded file as raw bytes
* Suitable for small files or direct in-memory processing
* Fast but lacks metadata (filename, content type)
**Example Request (curl):**
```bash
curl -X POST "http://localhost:8000/file" \
-F "file=@example.txt"
```
**Response:**
```json
{
"file_size": 128
}
```
---
### 2. `UploadFile`
* Accepts file as `UploadFile` object
* Provides metadata: `filename` and `content_type`
* Supports `.read()`, `.write()`, and `.seek()` operations
* More efficient for large files (uses spooled temporary files)
**Example Request (curl):**
```bash
curl -X POST "http://localhost:8000/uploadfile" \
-F "file=@example.txt"
```
**Response:**
```json
{
"filename": "example.txt",
"content_type": "text/plain",
"file_size": 128
}
```
---
### 3. Multiple File Uploads
* Accepts a list of `UploadFile`
* Allows uploading multiple files in one request
* Useful for batch uploads or form submissions
**Example Request (curl):**
```bash
curl -X POST "http://localhost:8000/uploadmultifile" \
-F "files=@file1.txt" \
-F "files=@file2.txt"
```
**Response:**
```json
[
{"filename": "file1.txt", "content_type": "text/plain"},
{"filename": "file2.txt", "content_type": "text/plain"}
]
```
---
## Content-Type
For file uploads, the request must include:
```
Content-Type: multipart/form-data
```
* Each file is sent as a separate part in the multipart request
---
## Running the Application
Start the service using `uvicorn`:
```bash
uvicorn main:app --reload
```
---
## Best Practices
* Use `UploadFile` for large or multiple files
* Validate file type and size on the server
* Avoid loading very large files fully into memory
* Use HTTPS for secure file transfer
* Store files in dedicated storage (S3, local disk, or DB)
* Return clear metadata (filename, size, content type) to clients
* Support multiple files when needed for batch operations

View File

@@ -0,0 +1,121 @@
# FastAPI Application Lifespan (Startup & Shutdown Events)
FastAPI allows you to run code when your application **starts up** or **shuts down**.
This is useful for initializing resources, database connections, caches, or background tasks.
---
## Deprecated Method: `@app.on_event`
Older FastAPI versions use the `@app.on_event` decorator for lifecycle events:
```python
from fastapi import FastAPI
app = FastAPI()
@app.on_event("startup")
def on_startup():
print("App is loading")
@app.on_event("shutdown")
def on_shutdown():
print("App is shutting down")
```
### Characteristics
* `startup` runs once when the app starts
* `shutdown` runs once when the app is stopped
* Works for synchronous and asynchronous functions
* Still supported but **deprecated** in favor of the `lifespan` parameter
---
## Recommended Modern Approach: `lifespan` with `asynccontextmanager`
FastAPI now recommends using the `lifespan` parameter in the `FastAPI` constructor.
This uses Python's `asynccontextmanager` to define a **single lifecycle context**.
```python
from fastapi import FastAPI
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
# Code to run before the app starts
print("App is loading")
yield # Application runs after this point
# Code to run after the app stops
print("App is shutting down")
app = FastAPI(lifespan=lifespan)
```
### How It Works
1. Code **before `yield`** executes on startup
2. Code **after `yield`** executes on shutdown
3. Supports async operations, e.g., connecting to a database
---
## Example: Using Lifespan for Database Initialization
```python
from fastapi import FastAPI
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.db = await connect_to_db()
print("Database connected")
yield
await app.state.db.close()
print("Database disconnected")
app = FastAPI(lifespan=lifespan)
```
* `app.state` is used to store shared resources
* Clean startup and shutdown handling
* Ensures proper resource cleanup
---
## Benefits of the Lifespan Approach
* Centralized lifecycle management
* Cleaner async support
* Avoids multiple scattered `@app.on_event` decorators
* Better for testing and production-ready apps
---
## Running the Application
Start the service with `uvicorn`:
```bash
uvicorn main:app --reload
```
* On startup, `App is loading` prints to the console
* On shutdown (Ctrl+C), `App is shutting down` prints to the console
---
## Best Practices
* Always use `lifespan` for new applications
* Use `app.state` to store shared resources
* Close database connections, caches, or background services in shutdown
* Keep startup logic lightweight to avoid blocking the server
* Avoid printing in production; use logging instead
---
This approach provides a **modern, production-ready pattern** for managing application startup and shutdown events in FastAPI.

172
Docs/Libs/Redis/Redis.md Normal file
View File

@@ -0,0 +1,172 @@
# Python + Redis Quick Guide
This document explains how to set up Python, connect to Redis, and perform basic cache operations.
---
## 1. Setup
Install Python and create a virtual environment:
```bash
sudo apt install python3-full
python3 -m venv .venv
source .venv/bin/activate
```
---
## 2. Connect and Test Redis Connection
```python
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
print(r.ping()) # Should print True
```
**Expected Output:**
```
True
```
---
## 3. Caching Scenario Example
This example demonstrates caching data in Redis with a TTL (Time To Live).
```python
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
def get_data_from_db():
print("Fetching from DB...")
time.sleep(2) # Simulate slow query
return {"user": "alice", "age": 30}
def get_user(user_id):
cache_key = f"user:{user_id}"
# Check cache first
cached = r.get(cache_key)
if cached:
print("Cache hit")
return eval(cached)
# Fetch from DB
data = get_data_from_db()
# Store in Redis with TTL (10 seconds)
r.set(cache_key, str(data), ex=10)
return data
print(get_user(1))
print(get_user(1)) # Should hit cache
```
---
## 4. Connect, Set, and Get Example
```python
import redis
r = redis.Redis(host="192.168.6.160", port=6379, db=0)
r.set('name', 'radin')
name = r.get('name')
print(name)
print(name.decode("utf-8"))
```
---
## 5. Interactive Read/Write Example
```python
import redis
method = int(input("Enter Method: (1.Read/2.Write) "))
r = redis.Redis(host="192.168.6.160", port=6379, db=0)
if method == 1:
key = str(input("Enter key name: "))
value = r.get(key)
if value is None:
print("Undefined Key")
else:
print(value)
elif method == 2:
key = str(input("Enter key name: "))
value = str(input("Enter value: "))
r.set(key, value)
else:
print("Incorrect Input")
```
---
## 6. Professional Version (Improved Code)
```python
import redis
import sys
def connect_redis(host="192.168.6.160", port=6379, db=0):
"""Establish a connection to Redis."""
try:
client = redis.Redis(host=host, port=port, db=db, decode_responses=True)
# Test connection
client.ping()
return client
except redis.ConnectionError as e:
print(f"Error connecting to Redis: {e}")
sys.exit(1)
def read_key(client):
"""Read a key from Redis."""
key = input("Enter key name: ").strip()
value = client.get(key)
if value is None:
print("Undefined Key")
else:
print(f"Value: {value}")
def write_key(client):
"""Write a key-value pair to Redis."""
key = input("Enter key name: ").strip()
value = input("Enter value: ").strip()
client.set(key, value)
print(f"Successfully set key '{key}' with value '{value}'.")
def main():
client = connect_redis()
print("Select Method:")
print("1. Read")
print("2. Write")
try:
method = int(input("Enter method (1 or 2): ").strip())
except ValueError:
print("Invalid input. Please enter 1 or 2.")
sys.exit(1)
if method == 1:
read_key(client)
elif method == 2:
write_key(client)
else:
print("Incorrect input. Please enter 1 or 2.")
sys.exit(1)
if __name__ == "__main__":
main()
```