update services doc to libs
This commit is contained in:
100
Docs/Libs/FastAPI/01-Setup.md
Normal file
100
Docs/Libs/FastAPI/01-Setup.md
Normal 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
|
||||
|
||||
---
|
||||
90
Docs/Libs/FastAPI/02-Simple-Route.md
Normal file
90
Docs/Libs/FastAPI/02-Simple-Route.md
Normal 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
|
||||
|
||||
169
Docs/Libs/FastAPI/03-Get-Method.md
Normal file
169
Docs/Libs/FastAPI/03-Get-Method.md
Normal 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
|
||||
|
||||
127
Docs/Libs/FastAPI/04-Post-Method.md
Normal file
127
Docs/Libs/FastAPI/04-Post-Method.md
Normal 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
|
||||
|
||||
162
Docs/Libs/FastAPI/05-Put-Method.md
Normal file
162
Docs/Libs/FastAPI/05-Put-Method.md
Normal 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 user’s 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
|
||||
|
||||
172
Docs/Libs/FastAPI/06-Delete-Method.md
Normal file
172
Docs/Libs/FastAPI/06-Delete-Method.md
Normal 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
|
||||
|
||||
199
Docs/Libs/FastAPI/07-Query-Parameter.md
Normal file
199
Docs/Libs/FastAPI/07-Query-Parameter.md
Normal 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
|
||||
|
||||
192
Docs/Libs/FastAPI/08.Status-Codes.md
Normal file
192
Docs/Libs/FastAPI/08.Status-Codes.md
Normal 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
|
||||
|
||||
122
Docs/Libs/FastAPI/09-Json-Responce.md
Normal file
122
Docs/Libs/FastAPI/09-Json-Responce.md
Normal 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
|
||||
|
||||
238
Docs/Libs/FastAPI/10-Query-Path--AdvancedParm.md
Normal file
238
Docs/Libs/FastAPI/10-Query-Path--AdvancedParm.md
Normal 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
|
||||
|
||||
226
Docs/Libs/FastAPI/11-Post-Types.md
Normal file
226
Docs/Libs/FastAPI/11-Post-Types.md
Normal 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
|
||||
|
||||
165
Docs/Libs/FastAPI/12-From-Post.md
Normal file
165
Docs/Libs/FastAPI/12-From-Post.md
Normal 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
|
||||
|
||||
161
Docs/Libs/FastAPI/13-Body-Post.md
Normal file
161
Docs/Libs/FastAPI/13-Body-Post.md
Normal 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
|
||||
167
Docs/Libs/FastAPI/14-File-Post.md
Normal file
167
Docs/Libs/FastAPI/14-File-Post.md
Normal 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
|
||||
121
Docs/Libs/FastAPI/15-Life-Span.md
Normal file
121
Docs/Libs/FastAPI/15-Life-Span.md
Normal 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
172
Docs/Libs/Redis/Redis.md
Normal 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()
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user