Skip to content

Commit 158cdbb

Browse files
authored
Merge pull request #26 from mongodb/python-backend-cleanup
feat: Clean up sample app and finalize endpoints
2 parents d21db80 + 07ca7f2 commit 158cdbb

File tree

2 files changed

+530
-557
lines changed

2 files changed

+530
-557
lines changed

server/python/main.py

Lines changed: 61 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,28 @@
1+
from contextlib import asynccontextmanager
12
from fastapi import FastAPI
23
from fastapi.middleware.cors import CORSMiddleware
34
from src.routers import movies
45
from src.utils.errorHandler import register_error_handlers
56
from src.database.mongo_client import db, get_collection
6-
import traceback
7+
78
import os
89
from dotenv import load_dotenv
910

1011
# Load environment variables from .env file
1112
load_dotenv()
1213

13-
app = FastAPI()
1414

15-
# Add CORS middleware
16-
cors_origins = os.getenv("CORS_ORIGINS", "http://localhost:3000,http://localhost:3001").split(",")
17-
app.add_middleware(
18-
CORSMiddleware,
19-
allow_origins=[origin.strip() for origin in cors_origins], # Load from environment variable
20-
allow_credentials=True,
21-
allow_methods=["*"],
22-
allow_headers=["*"],
23-
)
24-
25-
register_error_handlers(app)
26-
app.include_router(movies.router, prefix="/api/movies", tags=["movies"])
15+
@asynccontextmanager
16+
async def lifespan(app: FastAPI):
17+
# Startup: Create search indexes
18+
await ensure_search_index()
19+
await vector_search_index()
20+
yield
21+
# Shutdown: Clean up resources if needed
22+
# Add any cleanup code here
2723

2824

29-
@app.on_event("startup")
30-
async def initialize_database_indexes():
25+
async def ensure_search_index():
3126
try:
3227
movies_collection = db.get_collection("movies")
3328
comments_collection = db.get_collection("comments")
@@ -37,70 +32,43 @@ async def initialize_database_indexes():
3732
indexes = [idx async for idx in result]
3833
index_names = [index["name"] for index in indexes]
3934
if "movieSearchIndex" in index_names:
40-
print("MongoDB Search index already exists.")
41-
else:
42-
# Create a mapping if the movieSearchIndex does not exist
43-
index_definition = {
44-
"mappings": {
45-
"dynamic": False,
46-
"fields": {
47-
"plot": {"type": "string", "analyzer": "lucene.standard"},
48-
"fullplot": {"type": "string", "analyzer": "lucene.standard"},
49-
"directors": {"type": "string", "analyzer": "lucene.standard"},
50-
"writers": {"type": "string", "analyzer": "lucene.standard"},
51-
"cast": {"type": "string", "analyzer": "lucene.standard"}
52-
}
35+
return
36+
37+
# Create a mapping if the movieSearchIndex does not exist
38+
index_definition = {
39+
"mappings": {
40+
"dynamic": False,
41+
"fields": {
42+
"plot": {"type": "string", "analyzer": "lucene.standard"},
43+
"fullplot": {"type": "string", "analyzer": "lucene.standard"},
44+
"directors": {"type": "string", "analyzer": "lucene.standard"},
45+
"writers": {"type": "string", "analyzer": "lucene.standard"},
46+
"cast": {"type": "string", "analyzer": "lucene.standard"}
5347
}
5448
}
55-
# Creates movieSearchIndex on the movies collection
56-
await db.command({
57-
"createSearchIndexes": "movies",
58-
"indexes": [{
59-
"name": "movieSearchIndex",
60-
"definition": index_definition
61-
}]
62-
})
63-
print("MongoDB Search index created.")
64-
65-
# Check and create index on movie_id field in comments collection
66-
# This index will significantly improve $lookup performance in aggregations
67-
cursor = await comments_collection.list_indexes()
68-
existing_indexes = await cursor.to_list(length=None)
69-
movie_id_index_exists = any(
70-
"movie_id" in index.get("key", {}) for index in existing_indexes
71-
)
72-
73-
if not movie_id_index_exists:
74-
# Create index on movie_id field for better aggregation performance
75-
await comments_collection.create_index("movie_id")
76-
print("Index on 'movie_id' field in comments collection created.")
77-
else:
78-
print("Index on 'movie_id' field in comments collection already exists.")
79-
80-
# Also create a compound index on movie_id and date for even better performance
81-
# when sorting comments by date within each movie
82-
compound_index_exists = any(
83-
index.get("key", {}).get("movie_id") == 1 and index.get("key", {}).get("date") == -1
84-
for index in existing_indexes
85-
)
86-
87-
if not compound_index_exists:
88-
await comments_collection.create_index([("movie_id", 1), ("date", -1)])
89-
print("Compound index on 'movie_id' and 'date' fields in comments collection created.")
90-
else:
91-
print("Compound index on 'movie_id' and 'date' fields already exists.")
92-
49+
}
50+
# Creates movieSearchIndex on the movies collection
51+
await db.command({
52+
"createSearchIndexes": "movies",
53+
"indexes": [{
54+
"name": "movieSearchIndex",
55+
"definition": index_definition
56+
}]
57+
})
9358
except Exception as e:
94-
print(f"Error creating indexes: {e}")
59+
raise RuntimeError(
60+
f"Failed to create search index 'movieSearchIndex': {str(e)}. "
61+
f"Search functionality may not work properly. "
62+
f"Please check your MongoDB Atlas configuration and ensure the cluster supports search indexes."
63+
)
64+
9565

96-
@app.on_event("startup")
9766
async def vector_search_index():
9867
"""
9968
Creates vector search index on application startup if it doesn't already exist.
10069
This ensures the index is ready before any vector search requests are made.
10170
"""
10271
try:
103-
10472
embedded_movies_collection = get_collection("embedded_movies")
10573

10674
# Get list of existing indexes - convert AsyncCommandCursor to list
@@ -128,10 +96,29 @@ async def vector_search_index():
12896
}
12997

13098
# Create the index
131-
result = await embedded_movies_collection.create_search_index(index_definition)
132-
print("Vector search index 'vector_index' ready to query.")
99+
await embedded_movies_collection.create_search_index(index_definition)
133100

134101
except Exception as e:
135-
print(f"Error during vector search index setup: {str(e)}")
136-
print(f"Error type: {type(e).__name__}")
102+
raise RuntimeError(
103+
f"Failed to create vector search index 'vector_index': {str(e)}. "
104+
f"Vector search functionality will not be available. "
105+
f"Please check your MongoDB Atlas configuration, ensure the cluster supports vector search, "
106+
f"and verify the 'embedded_movies' collection exists with the required embedding field."
107+
)
108+
109+
110+
app = FastAPI(lifespan=lifespan)
111+
112+
# Add CORS middleware
113+
cors_origins = os.getenv("CORS_ORIGINS", "http://localhost:3000,http://localhost:3001").split(",")
114+
app.add_middleware(
115+
CORSMiddleware,
116+
allow_origins=[origin.strip() for origin in cors_origins], # Load from environment variable
117+
allow_credentials=True,
118+
allow_methods=["*"],
119+
allow_headers=["*"],
120+
)
121+
122+
register_error_handlers(app)
123+
app.include_router(movies.router, prefix="/api/movies", tags=["movies"])
137124

0 commit comments

Comments
 (0)