Files
ds_task_marketing_assistant_ai/backend/main.py
T
2025-07-10 19:00:01 +01:00

191 lines
5.6 KiB
Python

from fastapi import FastAPI, HTTPException, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional, List
import json
from datetime import datetime
from pathlib import Path
from .vector_store import VectorStore
from .brand_style import BrandStyle
from .config import Config
import openai
import os
# Initialize OpenAI
openai.api_key = Config.OPENAI_API_KEY
# Initialize
app = FastAPI(title="Marketing Assistant AI", version="0.1.0")
vector_store = VectorStore()
brand_style = BrandStyle()
# Create user_queries directory
user_queries_path = Path("data/user_queries")
user_queries_path.mkdir(parents=True, exist_ok=True)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# Models
class CampaignRequest(BaseModel):
prompt: str
content_type: str = "general"
tone: Optional[str] = None
class Campaign(BaseModel):
content: str
content_type: str
metadata: dict = {}
class UserFeedback(BaseModel):
query_id: str
rating: int # 1-5 scale
comments: Optional[str] = None
used_output: bool = False
modifications_made: Optional[str] = None
# Helper function to log user queries
def log_user_query(request: CampaignRequest, generated_copy: str = None, success: bool = None):
"""Log user query to data/user_queries/"""
query_id = f"query_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"
query_log = {
"query_id": query_id,
"timestamp": datetime.now().isoformat(),
"user_input": {
"prompt": request.prompt,
"content_type": request.content_type,
"tone": request.tone
},
"status": "completed" if success else "failed" if success is False else "processing",
"generated_output": generated_copy,
"success": success
}
# Save to user_queries folder
query_file = user_queries_path / f"{query_id}.json"
with open(query_file, 'w') as f:
json.dump(query_log, f, indent=2)
return query_id
# Routes
@app.post("/generate")
async def generate_copy(request: CampaignRequest):
"""Generate marketing copy based on prompt and brand guidelines"""
query_id = None
try:
# Log the initial query
query_id = log_user_query(request)
# Get similar content from vector store
similar = vector_store.search(request.prompt, request.content_type)
# Format similar content for context
similar_content = ""
if similar:
similar_content = "\n\nSimilar past campaigns for reference:\n"
for i, campaign in enumerate(similar[:3], 1):
similar_content += f"{i}. {campaign.get('content', '')}\n"
# Generate with OpenAI
system_prompt = brand_style.get_prompt(request)
user_prompt = f"Create marketing copy for: {request.prompt}{similar_content}"
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.7,
max_tokens=500
)
generated_copy = response.choices[0].message.content
# Update query log with success
log_user_query(request, generated_copy, True)
# Store the generated copy for future reference
new_campaign = {
"content": generated_copy,
"content_type": request.content_type,
"metadata": {
"prompt": request.prompt,
"tone": request.tone,
"generated_at": datetime.now().isoformat(),
"query_id": query_id
}
}
# Add to vector store for future similarity searches
vector_store.add_campaign(new_campaign)
return {
"result": generated_copy,
"query_id": query_id
}
except Exception as e:
# Log the error
if query_id:
log_user_query(request, str(e), False)
print(f"Error in generate_copy: {str(e)}") # For debugging
raise HTTPException(status_code=500, detail=str(e))
@app.post("/add-campaign")
async def add_campaign(campaign: Campaign):
"""Add a new campaign to the vector store"""
try:
# Add timestamp to metadata
campaign_data = campaign.dict()
campaign_data["metadata"]["added_at"] = datetime.now().isoformat()
vector_store.add_campaign(campaign_data)
return {"status": "success"}
except Exception as e:
print(f"Error in add_campaign: {str(e)}") # For debugging
raise HTTPException(status_code=500, detail=str(e))
@app.get("/search")
async def search_campaigns(query: str, limit: int = 5):
"""Search for similar campaigns"""
try:
results = vector_store.search(query, k=limit)
return {"results": results}
except Exception as e:
print(f"Error in search_campaigns: {str(e)}") # For debugging
raise HTTPException(status_code=500, detail=str(e))
@app.get("/")
async def root():
"""Health check endpoint"""
return {"message": "Marketing Assistant AI is running", "version": "0.1.0"}
@app.get("/health")
async def health_check():
"""Detailed health check"""
return {
"status": "healthy",
"vector_store_size": len(vector_store.campaigns),
"timestamp": datetime.now().isoformat()
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)