Spaces:
Sleeping
Sleeping
| 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") | |
| 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!") | |
| 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 | |
| } | |
| 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 | |
| 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 | |
| def get_customer(): | |
| print("π Getting all customers") | |
| customers = load_customers_from_dataset() | |
| print(f"π Found {len(customers)} customers") | |
| return customers | |
| # Update | |
| 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 | |
| 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) |