DB_Backend / app.py
Ritesh1035's picture
Update app.py
bd5a0df verified
from fastapi import FastAPI, HTTPException
from typing import Optional, List
from pydantic import BaseModel
import pandas as pd
from datasets import Dataset, load_dataset
from huggingface_hub import upload_file
import os
# Configuration - MUST come first
DATASET_NAME = "Ritesh1035/Customer_Data" # Your HuggingFace dataset
HF_TOKEN = os.getenv("HF_TOKEN") # Set this in HF Space secrets
app = FastAPI(title="Customer API", description="Customer management API with HuggingFace Dataset storage")
@app.on_event("startup")
async def startup_event():
"""Test connectivity on startup"""
print(f"πŸš€ Starting Customer API...")
print(f"πŸ“Š Dataset: {DATASET_NAME}")
print(f"πŸ”‘ HF Token: {'βœ… Set' if HF_TOKEN else '❌ Not set'}")
# Test dataset connectivity
try:
customers = load_customers_from_dataset()
print(f"βœ… Successfully connected to dataset with {len(customers)} customers")
except Exception as e:
print(f"⚠️ Dataset connection warning: {e}")
print("πŸŽ‰ API is ready!")
@app.get("/")
def read_root():
hf_token_status = "βœ… Set" if HF_TOKEN else "❌ Not set"
return {
"message": "Customer API is running! Visit /docs for API documentation.",
"dataset": DATASET_NAME,
"hf_token_status": hf_token_status
}
@app.get("/health")
def health_check():
"""Health check endpoint"""
return {"status": "healthy", "service": "Customer API"}
# 1 Define blueprint
class Customer(BaseModel):
id:int
name: str
email: str
phone: Optional[str]=None
address: Optional[str]=None
# 2 HuggingFace Dataset Functions
def load_customers_from_dataset() -> List[Customer]:
"""Load customers from HF Dataset"""
try:
print(f"πŸ“Š Loading dataset: {DATASET_NAME}")
# Load dataset with minimal options
dataset = load_dataset(
DATASET_NAME,
split="train",
token=HF_TOKEN
)
print(f"βœ… Dataset loaded: {len(dataset)} rows")
customers = []
for row in dataset:
try:
customers.append(Customer(
id=int(row['id']),
name=str(row['name']),
email=str(row['email']),
phone=str(row.get('phone', '')) if row.get('phone') and row.get('phone') != '' else None,
address=str(row.get('address', '')) if row.get('address') and row.get('address') != '' else None
))
except Exception as row_error:
print(f"⚠️ Skipping invalid row: {row_error}")
continue
print(f"πŸ“‹ Loaded {len(customers)} customers")
return customers
except Exception as e:
print(f"⚠️ Load error: {e}")
return []
def save_customers_to_dataset(customers: List[Customer]):
"""Save customers to HF Dataset"""
try:
# Convert to pandas DataFrame
data = []
for customer in customers:
data.append({
'id': customer.id,
'name': customer.name,
'email': customer.email,
'phone': customer.phone or "",
'address': customer.address or ""
})
df = pd.DataFrame(data)
print(f"πŸ’Ύ Saving {len(customers)} customers to dataset...")
# Save locally first as backup
df.to_csv("customers.csv", index=False)
print("πŸ“ Local backup saved")
# Upload to HF Dataset if token is available
if HF_TOKEN:
try:
upload_file(
path_or_fileobj="customers.csv",
path_in_repo="customers.csv",
repo_id=DATASET_NAME,
repo_type="dataset",
token=HF_TOKEN
)
print(f"βœ… Successfully saved {len(customers)} customers to dataset")
# Small delay for sync
import time
time.sleep(1)
except Exception as e:
print(f"⚠️ Upload error: {e}")
# Don't fail the operation, just log the error
else:
print("⚠️ HF_TOKEN not set - data saved locally only")
except Exception as e:
print(f"❌ Error in save_customers_to_dataset: {e}")
# Don't raise exception to avoid breaking the API
# Create
@app.post("/Customer", response_model=Customer)
def create_customer(customer: Customer):
print(f"βž• Creating customer ID: {customer.id}")
customers = load_customers_from_dataset()
print(f"πŸ“Š Current customers: {len(customers)}")
# Check for unique ID
existing_ids = [c.id for c in customers]
if customer.id in existing_ids:
print(f"❌ ID {customer.id} already exists")
raise HTTPException(
status_code=400,
detail=f"Customer ID {customer.id} already exists"
)
customers.append(customer)
save_customers_to_dataset(customers)
print(f"βœ… Created customer {customer.id}")
return customer
# Read
@app.get("/Customer", response_model=List[Customer])
def get_customer():
print("πŸ“‹ Getting all customers")
customers = load_customers_from_dataset()
print(f"πŸ“Š Found {len(customers)} customers")
return customers
# Update
@app.put("/Customer/{id}", response_model=Customer)
def update_customer(id: int, customer: Customer):
customers = load_customers_from_dataset()
for i, existing_customer in enumerate(customers):
if existing_customer.id == id:
customers[i] = customer
save_customers_to_dataset(customers)
return customer
raise HTTPException(status_code=404, detail="customer not found")
# Delete
@app.delete("/Customer/{id}", response_model=Customer)
def delete_customer(id: int):
customers = load_customers_from_dataset()
for i, customer_obj in enumerate(customers):
if customer_obj.id == id:
deleted_customer = customers.pop(i)
save_customers_to_dataset(customers)
return deleted_customer
raise HTTPException(status_code=404, detail="customer not found")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)