girishwangikar's picture
Create app.py
f3224d5 verified
raw
history blame
5.54 kB
import os
from neo4j import GraphDatabase
import gradio as gr
import pandas as pd
import plotly.express as px
from typing import List, Dict
class MovieAnalytics:
def __init__(self):
uri = os.getenv("NEO4J_URI")
user = os.getenv("NEO4J_USER")
password = os.getenv("NEO4J_PASSWORD")
self.driver = GraphDatabase.driver(uri, auth=(user, password))
def close(self):
self.driver.close()
def get_recommendations(self, genre: str, year: int, min_votes: int) -> pd.DataFrame:
with self.driver.session() as session:
query = """
MATCH (m:Movie)-[:HAS_GENRE]->(g:Genre {name: $genre})
MATCH (m)-[:RELEASED_IN]->(y:Year)
WHERE abs(toInteger(y.year) - $year) <= 2
MATCH (m)-[:HAS_VOTES]->(v:Votes)
WHERE toInteger(v.count) >= $min_votes
RETURN m.title as movie, y.year as year, v.count as votes
ORDER BY toInteger(v.count) DESC
LIMIT 10
"""
result = session.run(query, genre=genre, year=year, min_votes=min_votes)
return pd.DataFrame([dict(record) for record in result])
def get_actor_genre_analysis(self, actor_name: str) -> pd.DataFrame:
with self.driver.session() as session:
query = """
MATCH (a:Actor {name: $actor_name})-[:ACTED_IN]->(m:Movie)
MATCH (m)-[:HAS_GENRE]->(g:Genre)
MATCH (m)-[:HAS_VOTES]->(v:Votes)
RETURN g.name as genre,
count(m) as movie_count,
avg(toInteger(v.count)) as avg_votes
ORDER BY movie_count DESC
"""
result = session.run(query, actor_name=actor_name)
return pd.DataFrame([dict(record) for record in result])
def get_yearly_genre_trends(self) -> pd.DataFrame:
with self.driver.session() as session:
query = """
MATCH (m:Movie)-[:HAS_GENRE]->(g:Genre)
MATCH (m)-[:RELEASED_IN]->(y:Year)
MATCH (m)-[:HAS_VOTES]->(v:Votes)
RETURN y.year as year,
g.name as genre,
count(m) as movie_count,
avg(toInteger(v.count)) as avg_votes
ORDER BY y.year, g.name
"""
result = session.run(query, )
return pd.DataFrame([dict(record) for record in result])
def create_interface():
analytics = MovieAnalytics()
def get_movie_recommendations(genre, year, min_votes):
try:
df = analytics.get_recommendations(genre, int(year), int(min_votes))
if df.empty:
return "No recommendations found.", None
fig = px.bar(df, x='movie', y='votes',
title=f'Top Movies in {genre} around {year}',
hover_data=['year'])
return df, fig
except Exception as e:
return f"Error: {str(e)}", None
def analyze_actor(actor_name):
try:
df = analytics.get_actor_genre_analysis(actor_name)
if df.empty:
return "No data found for this actor.", None
fig = px.bar(df, x='genre', y='movie_count',
title=f'Genre Distribution for {actor_name}',
hover_data=['avg_votes'])
return df, fig
except Exception as e:
return f"Error: {str(e)}", None
def show_trends():
try:
df = analytics.get_yearly_genre_trends()
if df.empty:
return "No trend data available.", None
fig = px.line(df, x='year', y='movie_count', color='genre',
title='Genre Trends Over Years')
return df, fig
except Exception as e:
return f"Error: {str(e)}", None
with gr.Blocks() as demo:
gr.Markdown("""
# Movie Analytics Dashboard
Explore movie recommendations and trends based on various factors.
""")
with gr.Tab("Movie Recommendations"):
with gr.Row():
genre_input = gr.Textbox(label="Genre")
year_input = gr.Number(label="Year", value=2020)
votes_input = gr.Number(label="Minimum Votes", value=1000)
recommend_btn = gr.Button("Get Recommendations")
rec_output = gr.DataFrame()
rec_plot = gr.Plot()
recommend_btn.click(
fn=get_movie_recommendations,
inputs=[genre_input, year_input, votes_input],
outputs=[rec_output, rec_plot]
)
with gr.Tab("Actor Analysis"):
actor_input = gr.Textbox(label="Actor Name")
actor_btn = gr.Button("Analyze Actor")
actor_output = gr.DataFrame()
actor_plot = gr.Plot()
actor_btn.click(
fn=analyze_actor,
inputs=actor_input,
outputs=[actor_output, actor_plot]
)
with gr.Tab("Genre Trends"):
trend_btn = gr.Button("Show Trends")
trend_output = gr.DataFrame()
trend_plot = gr.Plot()
trend_btn.click(
fn=show_trends,
outputs=[trend_output, trend_plot]
)
return demo
if __name__ == "__main__":
demo = create_interface()
demo.launch()