first commit
This commit is contained in:
16
api/.dockerignore
Normal file
16
api/.dockerignore
Normal file
@@ -0,0 +1,16 @@
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.Python
|
||||
env/
|
||||
venv/
|
||||
.venv/
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
*.log
|
||||
.DS_Store
|
||||
.env
|
||||
15
api/Dockerfile
Normal file
15
api/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
RUN pip install --no-cache-dir fastapi uvicorn[standard] pydantic
|
||||
|
||||
# Copy application
|
||||
COPY main.py .
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8001
|
||||
|
||||
# Run the application
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"]
|
||||
87
api/README.md
Normal file
87
api/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# API Service - FastAPI
|
||||
|
||||
A RESTful API service built with FastAPI featuring Swagger documentation.
|
||||
|
||||
## Features
|
||||
|
||||
- 📚 Automatic Swagger/OpenAPI documentation
|
||||
- 🔄 RESTful API endpoints
|
||||
- ✅ Data validation with Pydantic
|
||||
- 📊 Statistics and monitoring endpoints
|
||||
- ❤️ Health check endpoints
|
||||
|
||||
## Local Development
|
||||
|
||||
### Run with Python
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run the application
|
||||
python main.py
|
||||
|
||||
# Or use uvicorn directly
|
||||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
### Run with Docker
|
||||
|
||||
```bash
|
||||
# Build image
|
||||
docker build -t fastapi-api .
|
||||
|
||||
# Run container
|
||||
docker run -p 8000:8000 fastapi-api
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Items
|
||||
- `GET /items` - List all items (with pagination)
|
||||
- `GET /items/{item_id}` - Get specific item
|
||||
- `POST /items` - Create new item
|
||||
- `PUT /items/{item_id}` - Update item
|
||||
- `DELETE /items/{item_id}` - Delete item
|
||||
|
||||
### Users
|
||||
- `GET /users` - List all users
|
||||
- `GET /users/{user_id}` - Get specific user
|
||||
- `POST /users` - Create new user
|
||||
|
||||
### Other
|
||||
- `GET /` - API information
|
||||
- `GET /health` - Health check
|
||||
- `GET /info` - Service information
|
||||
- `GET /stats` - API statistics
|
||||
|
||||
## Documentation
|
||||
|
||||
- Swagger UI: http://localhost:8000/docs
|
||||
- ReDoc: http://localhost:8000/redoc
|
||||
- OpenAPI JSON: http://localhost:8000/openapi.json
|
||||
|
||||
## Example Requests
|
||||
|
||||
### Create Item
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/items" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"id": 4,
|
||||
"name": "Monitor",
|
||||
"description": "4K Display",
|
||||
"price": 299.99,
|
||||
"in_stock": true
|
||||
}'
|
||||
```
|
||||
|
||||
### Get Items
|
||||
```bash
|
||||
curl "http://localhost:8000/items?skip=0&limit=10&in_stock=true"
|
||||
```
|
||||
|
||||
### Get Statistics
|
||||
```bash
|
||||
curl "http://localhost:8000/stats"
|
||||
```
|
||||
123
api/main.py
Normal file
123
api/main.py
Normal file
@@ -0,0 +1,123 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional
|
||||
import uvicorn
|
||||
from datetime import datetime
|
||||
|
||||
app = FastAPI(
|
||||
title="API Demo Application",
|
||||
description="Demo API with Swagger documentation",
|
||||
version="1.0.0"
|
||||
)
|
||||
|
||||
# Models
|
||||
class Item(BaseModel):
|
||||
id: Optional[int] = None
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
price: float
|
||||
in_stock: bool = True
|
||||
|
||||
class User(BaseModel):
|
||||
id: Optional[int] = None
|
||||
username: str
|
||||
email: str
|
||||
active: bool = True
|
||||
|
||||
# In-memory storage
|
||||
items_db = [
|
||||
{"id": 1, "name": "Laptop", "description": "High-performance laptop", "price": 999.99, "in_stock": True},
|
||||
{"id": 2, "name": "Mouse", "description": "Wireless mouse", "price": 29.99, "in_stock": True},
|
||||
{"id": 3, "name": "Keyboard", "description": "Mechanical keyboard", "price": 79.99, "in_stock": False},
|
||||
]
|
||||
|
||||
users_db = [
|
||||
{"id": 1, "username": "john_doe", "email": "john@example.com", "active": True},
|
||||
{"id": 2, "username": "jane_smith", "email": "jane@example.com", "active": True},
|
||||
]
|
||||
|
||||
# Root endpoint
|
||||
@app.get("/")
|
||||
async def root():
|
||||
"""Root endpoint with API information"""
|
||||
return {
|
||||
"message": "Welcome to API Demo",
|
||||
"version": "1.0.0",
|
||||
"docs": "/docs",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# Health check
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
"""Health check endpoint"""
|
||||
return {"status": "healthy", "service": "api", "timestamp": datetime.now().isoformat()}
|
||||
|
||||
# Items endpoints
|
||||
@app.get("/items", response_model=List[Item], tags=["Items"])
|
||||
async def get_items():
|
||||
"""Get all items"""
|
||||
return items_db
|
||||
|
||||
@app.get("/items/{item_id}", response_model=Item, tags=["Items"])
|
||||
async def get_item(item_id: int):
|
||||
"""Get a specific item by ID"""
|
||||
item = next((item for item in items_db if item["id"] == item_id), None)
|
||||
if item is None:
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
return item
|
||||
|
||||
@app.post("/items", response_model=Item, tags=["Items"])
|
||||
async def create_item(item: Item):
|
||||
"""Create a new item"""
|
||||
new_id = max([i["id"] for i in items_db]) + 1 if items_db else 1
|
||||
item_dict = item.dict()
|
||||
item_dict["id"] = new_id
|
||||
items_db.append(item_dict)
|
||||
return item_dict
|
||||
|
||||
@app.put("/items/{item_id}", response_model=Item, tags=["Items"])
|
||||
async def update_item(item_id: int, item: Item):
|
||||
"""Update an existing item"""
|
||||
for idx, existing_item in enumerate(items_db):
|
||||
if existing_item["id"] == item_id:
|
||||
item_dict = item.dict()
|
||||
item_dict["id"] = item_id
|
||||
items_db[idx] = item_dict
|
||||
return item_dict
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
|
||||
@app.delete("/items/{item_id}", tags=["Items"])
|
||||
async def delete_item(item_id: int):
|
||||
"""Delete an item"""
|
||||
for idx, item in enumerate(items_db):
|
||||
if item["id"] == item_id:
|
||||
items_db.pop(idx)
|
||||
return {"message": "Item deleted successfully"}
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
|
||||
# Users endpoints
|
||||
@app.get("/users", response_model=List[User], tags=["Users"])
|
||||
async def get_users():
|
||||
"""Get all users"""
|
||||
return users_db
|
||||
|
||||
@app.get("/users/{user_id}", response_model=User, tags=["Users"])
|
||||
async def get_user(user_id: int):
|
||||
"""Get a specific user by ID"""
|
||||
user = next((user for user in users_db if user["id"] == user_id), None)
|
||||
if user is None:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
return user
|
||||
|
||||
@app.post("/users", response_model=User, tags=["Users"])
|
||||
async def create_user(user: User):
|
||||
"""Create a new user"""
|
||||
new_id = max([u["id"] for u in users_db]) + 1 if users_db else 1
|
||||
user_dict = user.dict()
|
||||
user_dict["id"] = new_id
|
||||
users_db.append(user_dict)
|
||||
return user_dict
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="0.0.0.0", port=8001)
|
||||
3
api/requirements.txt
Normal file
3
api/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
pydantic==2.5.0
|
||||
Reference in New Issue
Block a user