mirror of
https://github.com/myronblair/epic-download
synced 2026-06-30 17:51:00 -05:00
auto-commit for 8a62051e-b038-4363-a62d-7047e3d6e102
This commit is contained in:
+224
-52
@@ -1,15 +1,15 @@
|
||||
from fastapi import FastAPI, APIRouter
|
||||
from fastapi import FastAPI
|
||||
from dotenv import load_dotenv
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from motor.motor_asyncio import AsyncIOMotorClient
|
||||
import os
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import List
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from auth import hash_password
|
||||
from datetime import datetime
|
||||
|
||||
# Import route modules
|
||||
from routes import auth_routes, destination_routes, special_routes, other_routes
|
||||
|
||||
ROOT_DIR = Path(__file__).parent
|
||||
load_dotenv(ROOT_DIR / '.env')
|
||||
@@ -19,60 +19,30 @@ mongo_url = os.environ['MONGO_URL']
|
||||
client = AsyncIOMotorClient(mongo_url)
|
||||
db = client[os.environ['DB_NAME']]
|
||||
|
||||
# Create the main app without a prefix
|
||||
app = FastAPI()
|
||||
# Inject database into route modules
|
||||
auth_routes.set_db(db)
|
||||
destination_routes.set_db(db)
|
||||
special_routes.set_db(db)
|
||||
other_routes.set_db(db)
|
||||
|
||||
# Create a router with the /api prefix
|
||||
api_router = APIRouter(prefix="/api")
|
||||
# Create the main app
|
||||
app = FastAPI(title="Epic Travel & Destinations API")
|
||||
|
||||
# Include routers
|
||||
app.include_router(auth_routes.router)
|
||||
app.include_router(destination_routes.router)
|
||||
app.include_router(special_routes.router)
|
||||
app.include_router(other_routes.router)
|
||||
|
||||
# Define Models
|
||||
class StatusCheck(BaseModel):
|
||||
model_config = ConfigDict(extra="ignore") # Ignore MongoDB's _id field
|
||||
|
||||
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
||||
client_name: str
|
||||
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
|
||||
class StatusCheckCreate(BaseModel):
|
||||
client_name: str
|
||||
|
||||
# Add your routes to the router instead of directly to app
|
||||
@api_router.get("/")
|
||||
# Health check endpoint
|
||||
@app.get("/api")
|
||||
async def root():
|
||||
return {"message": "Hello World"}
|
||||
|
||||
@api_router.post("/status", response_model=StatusCheck)
|
||||
async def create_status_check(input: StatusCheckCreate):
|
||||
status_dict = input.model_dump()
|
||||
status_obj = StatusCheck(**status_dict)
|
||||
|
||||
# Convert to dict and serialize datetime to ISO string for MongoDB
|
||||
doc = status_obj.model_dump()
|
||||
doc['timestamp'] = doc['timestamp'].isoformat()
|
||||
|
||||
_ = await db.status_checks.insert_one(doc)
|
||||
return status_obj
|
||||
|
||||
@api_router.get("/status", response_model=List[StatusCheck])
|
||||
async def get_status_checks():
|
||||
# Exclude MongoDB's _id field from the query results
|
||||
status_checks = await db.status_checks.find({}, {"_id": 0}).to_list(1000)
|
||||
|
||||
# Convert ISO string timestamps back to datetime objects
|
||||
for check in status_checks:
|
||||
if isinstance(check['timestamp'], str):
|
||||
check['timestamp'] = datetime.fromisoformat(check['timestamp'])
|
||||
|
||||
return status_checks
|
||||
|
||||
# Include the router in the main app
|
||||
app.include_router(api_router)
|
||||
return {"message": "Epic Travel API is running", "status": "healthy"}
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_credentials=True,
|
||||
allow_origins=os.environ.get('CORS_ORIGINS', '*').split(','),
|
||||
allow_origins=["*"],
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
@@ -84,6 +54,208 @@ logging.basicConfig(
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_db_client():
|
||||
"""Initialize database with seed data if empty"""
|
||||
try:
|
||||
# Check if admin user exists, if not create one
|
||||
admin_exists = await db.admin_users.find_one({"email": "admin@epictravel.com"})
|
||||
if not admin_exists:
|
||||
admin_data = {
|
||||
"id": "admin-1",
|
||||
"email": "admin@epictravel.com",
|
||||
"password_hash": hash_password("admin123"),
|
||||
"created_at": datetime.utcnow()
|
||||
}
|
||||
await db.admin_users.insert_one(admin_data)
|
||||
logger.info("Default admin user created")
|
||||
|
||||
# Check if destinations exist, if not seed initial data
|
||||
dest_count = await db.destinations.count_documents({})
|
||||
if dest_count == 0:
|
||||
# Seed initial destinations
|
||||
initial_destinations = [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Paris",
|
||||
"location": "France",
|
||||
"description": "Experience the romance and elegance of the City of Light. Visit iconic landmarks like the Eiffel Tower, Louvre Museum, and stroll along the Champs-Élysées.",
|
||||
"image": "https://images.unsplash.com/photo-1502602898657-3e91760cbb34?w=800&q=80",
|
||||
"category": "City",
|
||||
"rating": 4.9,
|
||||
"price": 1299,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Bali",
|
||||
"location": "Indonesia",
|
||||
"description": "Discover tropical paradise with stunning beaches, ancient temples, lush rice terraces, and vibrant culture in this Indonesian gem.",
|
||||
"image": "https://images.unsplash.com/photo-1537996194471-e657df975ab4?w=800&q=80",
|
||||
"category": "Beach",
|
||||
"rating": 4.8,
|
||||
"price": 899,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"name": "Tokyo",
|
||||
"location": "Japan",
|
||||
"description": "Immerse yourself in the perfect blend of ancient tradition and cutting-edge technology in Japan's bustling capital city.",
|
||||
"image": "https://images.unsplash.com/photo-1540959733332-eab4deabeeaf?w=800&q=80",
|
||||
"category": "City",
|
||||
"rating": 4.9,
|
||||
"price": 1499,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"name": "Santorini",
|
||||
"location": "Greece",
|
||||
"description": "Marvel at breathtaking sunsets, whitewashed buildings, and crystal-clear waters in this stunning Greek island paradise.",
|
||||
"image": "https://images.unsplash.com/photo-1613395877344-13d4a8e0d49e?w=800&q=80",
|
||||
"category": "Beach",
|
||||
"rating": 4.9,
|
||||
"price": 1199,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"name": "Iceland",
|
||||
"location": "Iceland",
|
||||
"description": "Witness the Northern Lights, explore glaciers, geysers, and volcanic landscapes in this land of fire and ice.",
|
||||
"image": "https://images.unsplash.com/photo-1504829857797-ddff29c27927?w=800&q=80",
|
||||
"category": "Adventure",
|
||||
"rating": 4.8,
|
||||
"price": 1699,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"name": "Dubai",
|
||||
"location": "UAE",
|
||||
"description": "Experience luxury and innovation in the desert with world-class shopping, stunning architecture, and endless entertainment.",
|
||||
"image": "https://images.unsplash.com/photo-1512453979798-5ea266f8880c?w=800&q=80",
|
||||
"category": "City",
|
||||
"rating": 4.7,
|
||||
"price": 1399,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"name": "Maldives",
|
||||
"location": "Maldives",
|
||||
"description": "Relax in overwater bungalows, dive in pristine coral reefs, and enjoy the ultimate tropical island getaway.",
|
||||
"image": "https://images.unsplash.com/photo-1514282401047-d79a71a590e8?w=800&q=80",
|
||||
"category": "Beach",
|
||||
"rating": 5.0,
|
||||
"price": 2199,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"name": "New York",
|
||||
"location": "USA",
|
||||
"description": "Explore the city that never sleeps with iconic landmarks, world-class museums, Broadway shows, and diverse neighborhoods.",
|
||||
"image": "https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?w=800&q=80",
|
||||
"category": "City",
|
||||
"rating": 4.8,
|
||||
"price": 1099,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"name": "Machu Picchu",
|
||||
"location": "Peru",
|
||||
"description": "Trek to the ancient Incan citadel nestled high in the Andes Mountains, one of the New Seven Wonders of the World.",
|
||||
"image": "https://images.unsplash.com/photo-1587595431973-160d0d94add1?w=800&q=80",
|
||||
"category": "Adventure",
|
||||
"rating": 4.9,
|
||||
"price": 1299,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"name": "Swiss Alps",
|
||||
"location": "Switzerland",
|
||||
"description": "Ski pristine slopes, hike mountain trails, and enjoy charming alpine villages with breathtaking mountain vistas.",
|
||||
"image": "https://images.unsplash.com/photo-1531366936337-7c912a4589a7?w=800&q=80",
|
||||
"category": "Adventure",
|
||||
"rating": 4.9,
|
||||
"price": 1799,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"name": "Venice",
|
||||
"location": "Italy",
|
||||
"description": "Glide through romantic canals, admire Renaissance architecture, and savor authentic Italian cuisine in this unique floating city.",
|
||||
"image": "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9?w=800&q=80",
|
||||
"category": "City",
|
||||
"rating": 4.8,
|
||||
"price": 1149,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"name": "Safari Kenya",
|
||||
"location": "Kenya",
|
||||
"description": "Witness the Great Migration, spot the Big Five, and experience the raw beauty of African wilderness.",
|
||||
"image": "https://images.unsplash.com/photo-1516426122078-c23e76319801?w=800&q=80",
|
||||
"category": "Adventure",
|
||||
"rating": 4.9,
|
||||
"price": 2499,
|
||||
"currency": "USD",
|
||||
"created_at": datetime.utcnow()
|
||||
}
|
||||
]
|
||||
await db.destinations.insert_many(initial_destinations)
|
||||
logger.info(f"Seeded {len(initial_destinations)} initial destinations")
|
||||
|
||||
# Seed initial specials
|
||||
initial_specials = [
|
||||
{
|
||||
"id": "special-1",
|
||||
"destination_id": "2",
|
||||
"discount": 25,
|
||||
"end_date": "2025-02-28",
|
||||
"highlights": ["Free spa treatment", "Complimentary airport transfer", "Sunset dinner cruise"],
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "special-2",
|
||||
"destination_id": "4",
|
||||
"discount": 30,
|
||||
"end_date": "2025-03-15",
|
||||
"highlights": ["Wine tasting tour", "Private yacht excursion", "Luxury accommodation upgrade"],
|
||||
"created_at": datetime.utcnow()
|
||||
},
|
||||
{
|
||||
"id": "special-3",
|
||||
"destination_id": "7",
|
||||
"discount": 20,
|
||||
"end_date": "2025-02-20",
|
||||
"highlights": ["Snorkeling adventure", "Couples massage", "Romantic beach dinner"],
|
||||
"created_at": datetime.utcnow()
|
||||
}
|
||||
]
|
||||
await db.specials.insert_many(initial_specials)
|
||||
logger.info(f"Seeded {len(initial_specials)} initial specials")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during startup: {str(e)}")
|
||||
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown_db_client():
|
||||
client.close()
|
||||
client.close()
|
||||
|
||||
Reference in New Issue
Block a user