1+ from fastapi import FastAPI , HTTPException , Depends , Header , Request
2+ from fastapi .middleware .cors import CORSMiddleware
3+ from fastapi .responses import JSONResponse
4+ from pymongo import MongoClient
5+ from contextlib import asynccontextmanager
6+ import os
7+ import stripe
8+ import logging
9+
10+ # --- Configuration ---
11+ MONGODB_URI = os .getenv ("MONGODB_URI" , "mongodb+srv://<topboybrooks1_db_user>:<6M6mdxRk7BYbyhIG>@apimicrosaas.kwtxluh.mongodb.net/?retryWrites=true&w=majority&appName=APImicrosaas" )
12+ STRIPE_API_KEY = os .getenv ("STRIPE_API_KEY" )
13+ stripe .api_key = STRIPE_API_KEY
14+
15+ # --- Lifespan Events ---
16+ @asynccontextmanager
17+ async def lifespan (app : FastAPI ):
18+ # Startup: Connect to DB
19+ app .mongodb_client = MongoClient (MONGODB_URI )
20+ app .database = app .mongodb_client .get_database ("devtools_conglomerate" )
21+ logging .info ("Connected to MongoDB" )
22+ yield
23+ # Shutdown: Close DB connection
24+ app .mongodb_client .close ()
25+ logging .info ("Disconnected from MongoDB" )
26+
27+ # --- FastAPI App Initialization ---
28+ app = FastAPI (lifespan = lifespan , title = "DevTools Conglomerate API Template" , version = "1.0.0" )
29+
30+ app .add_middleware (
31+ CORSMiddleware ,
32+ allow_origins = ["*" ],
33+ allow_methods = ["*" ],
34+ allow_headers = ["*" ],
35+ )
36+
37+ # --- Dependency: Get API Key from Header ---
38+ async def get_api_key (x_api_key : str = Header (None )):
39+ if not x_api_key :
40+ raise HTTPException (status_code = 401 , detail = "Missing API Key" )
41+ # Check if key exists and is active in MongoDB
42+ key_doc = app .database .api_keys .find_one ({"key" : x_api_key , "is_active" : True })
43+ if not key_doc :
44+ raise HTTPException (status_code = 401 , detail = "Invalid API Key" )
45+ return key_doc
46+
47+ # --- Generic Health Check Endpoint (for all APIs) ---
48+ @app .get ("/" , tags = ["TEST-DATA-API " ])
49+ async def root ():
50+ return {"message" : "DevTools Conglomerate API is operational" , "status" : "success" }
51+
52+ # --- Stripe Webhook Handler (for all APIs) ---
53+ @app .post ("/stripe-webhook" , tags = ["TEST-DATA-API " ])
54+ async def stripe_webhook (request : Request ):
55+ payload = await request .body ()
56+ sig_header = request .headers .get ('stripe-signature' )
57+ try :
58+ event = stripe .Webhook .construct_event (
59+ payload , sig_header , os .getenv ('STRIPE_WEBHOOK_SECRET' )
60+ )
61+ except ValueError as e :
62+ raise HTTPException (status_code = 400 , detail = "Invalid payload" )
63+ except stripe .error .SignatureVerificationError as e :
64+ raise HTTPException (status_code = 400 , detail = "Invalid signature" )
65+
66+ # Handle the event (e.g., subscription created, payment succeeded)
67+ # This will update the user's tier in MongoDB
68+ # Placeholder for logic
69+ return JSONResponse (status_code = 200 , content = {"status" : "success" })
70+
71+ # --- Test Data Fabricator API Logic ---
72+ from faker import Faker
73+ from pydantic import BaseModel
74+ from typing import List , Dict , Any , Optional
75+ import json
76+
77+ fake = Faker ()
78+
79+ class DataGenerationRequest (BaseModel ):
80+ schema_definition : Dict [str , Any ] # e.g., {"name": "first_name", "email": "email", "address": {"city": "city", "zipcode": "zipcode"}}
81+ n : int = 1 # number of records to generate
82+
83+ @app .post ("/generate" , tags = ["TEST-DATA-API " ])
84+ async def generate_test_data (request : DataGenerationRequest , api_key_info : dict = Depends (get_api_key )):
85+ """
86+ Generate realistic test data based on a user-provided schema.
87+ """
88+ def generate_item (schema ):
89+ item = {}
90+ for key , value_type in schema .items ():
91+ if isinstance (value_type , dict ):
92+ # Nested object
93+ item [key ] = generate_item (value_type )
94+ else :
95+ # Map the string to a Faker method
96+ try :
97+ # Get the Faker method (e.g., "first_name")
98+ method = getattr (fake , value_type )
99+ item [key ] = method ()
100+ except AttributeError :
101+ # If the method doesn't exist, just use the string itself
102+ item [key ] = f"Unknown type: { value_type } "
103+ return item
104+
105+ try :
106+ data = [generate_item (request .schema_definition ) for _ in range (request .n )]
107+ return {"status" : "success" , "data" : data , "generated" : request .n }
108+ except Exception as e :
109+ raise HTTPException (status_code = 500 , detail = f"Error generating data: { str (e )} " )
0 commit comments