FastApi-ISS/main.py
2025-08-11 23:35:16 +03:30

130 lines
4.0 KiB
Python

from fastapi import FastAPI, HTTPException, Depends, Header
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Optional
from sqlalchemy.orm import Session
import uvicorn
import os
from dotenv import load_dotenv
from database import get_db, create_tables, Item as ItemModel
from schemas import ScrapeRequest, ScrapedPost
from scraper import scrape_and_store
from admin_sync import router as admin_sync_router
# Load environment variables
load_dotenv()
# API Key for Django backend authentication
API_KEY = os.getenv("ENGINE_API_KEY")
app = FastAPI(
title=os.getenv("FASTAPI_TITLE", "FastAPI ISS Project"),
description=os.getenv("FASTAPI_DESCRIPTION", "A FastAPI project with Docker and PostgreSQL support"),
version=os.getenv("FASTAPI_VERSION", "1.0.0")
)
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=eval(os.getenv("ALLOWED_ORIGINS", '["*"]')),
allow_credentials=os.getenv("ALLOWED_CREDENTIALS", "true").lower() == "true",
allow_methods=eval(os.getenv("ALLOWED_METHODS", '["*"]')),
allow_headers=eval(os.getenv("ALLOWED_HEADERS", '["*"]')),
)
# Pydantic models for basic items
class ItemBase(BaseModel):
name: str
description: Optional[str] = None
price: float
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
class Config:
from_attributes = True
@app.on_event("startup")
async def startup_event():
create_tables()
@app.get("/")
async def root():
return {"message": "Welcome to FastAPI ISS Project!", "status": "running"}
@app.get("/health")
async def health_check():
return {"status": "healthy", "service": "FastAPI ISS"}
@app.get("/items", response_model=List[Item])
async def get_items(db: Session = Depends(get_db)):
items = db.query(ItemModel).all()
return items
@app.get("/items/{item_id}", response_model=Item)
async def get_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item
@app.post("/items", response_model=Item)
async def create_item(item: ItemCreate, db: Session = Depends(get_db)):
db_item = ItemModel(**item.dict())
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: int, item: ItemCreate, db: Session = Depends(get_db)):
db_item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
if db_item is None:
raise HTTPException(status_code=404, detail="Item not found")
for key, value in item.dict().items():
setattr(db_item, key, value)
db.commit()
db.refresh(db_item)
return db_item
@app.delete("/items/{item_id}")
async def delete_item(item_id: int, db: Session = Depends(get_db)):
db_item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
if db_item is None:
raise HTTPException(status_code=404, detail="Item not found")
db.delete(db_item)
db.commit()
return {"message": "Item deleted successfully"}
# Include admin router
app.include_router(admin_sync_router)
# ============================================================================
# Instagram Scraper Endpoint
# ============================================================================
@app.post("/scrape/", response_model=List[ScrapedPost])
async def scrape_posts(
request: ScrapeRequest,
x_api_key: str = Header(...),
db: Session = Depends(get_db)
):
"""Scrape Instagram posts for a given username"""
if x_api_key != API_KEY:
raise HTTPException(status_code=403, detail="Forbidden: Invalid API key")
try:
return scrape_and_store(db, request)
except Exception as e:
# Log the error for debugging
print(f"❌ Scraping error for {request.username}: {e}")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)