girishwangikar commited on
Commit
f3224d5
·
verified ·
1 Parent(s): d23df55

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +152 -0
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from neo4j import GraphDatabase
3
+ import gradio as gr
4
+ import pandas as pd
5
+ import plotly.express as px
6
+ from typing import List, Dict
7
+
8
+ class MovieAnalytics:
9
+ def __init__(self):
10
+ uri = os.getenv("NEO4J_URI")
11
+ user = os.getenv("NEO4J_USER")
12
+ password = os.getenv("NEO4J_PASSWORD")
13
+
14
+ self.driver = GraphDatabase.driver(uri, auth=(user, password))
15
+
16
+ def close(self):
17
+ self.driver.close()
18
+
19
+ def get_recommendations(self, genre: str, year: int, min_votes: int) -> pd.DataFrame:
20
+ with self.driver.session() as session:
21
+ query = """
22
+ MATCH (m:Movie)-[:HAS_GENRE]->(g:Genre {name: $genre})
23
+ MATCH (m)-[:RELEASED_IN]->(y:Year)
24
+ WHERE abs(toInteger(y.year) - $year) <= 2
25
+ MATCH (m)-[:HAS_VOTES]->(v:Votes)
26
+ WHERE toInteger(v.count) >= $min_votes
27
+ RETURN m.title as movie, y.year as year, v.count as votes
28
+ ORDER BY toInteger(v.count) DESC
29
+ LIMIT 10
30
+ """
31
+ result = session.run(query, genre=genre, year=year, min_votes=min_votes)
32
+ return pd.DataFrame([dict(record) for record in result])
33
+
34
+ def get_actor_genre_analysis(self, actor_name: str) -> pd.DataFrame:
35
+ with self.driver.session() as session:
36
+ query = """
37
+ MATCH (a:Actor {name: $actor_name})-[:ACTED_IN]->(m:Movie)
38
+ MATCH (m)-[:HAS_GENRE]->(g:Genre)
39
+ MATCH (m)-[:HAS_VOTES]->(v:Votes)
40
+ RETURN g.name as genre,
41
+ count(m) as movie_count,
42
+ avg(toInteger(v.count)) as avg_votes
43
+ ORDER BY movie_count DESC
44
+ """
45
+ result = session.run(query, actor_name=actor_name)
46
+ return pd.DataFrame([dict(record) for record in result])
47
+
48
+ def get_yearly_genre_trends(self) -> pd.DataFrame:
49
+ with self.driver.session() as session:
50
+ query = """
51
+ MATCH (m:Movie)-[:HAS_GENRE]->(g:Genre)
52
+ MATCH (m)-[:RELEASED_IN]->(y:Year)
53
+ MATCH (m)-[:HAS_VOTES]->(v:Votes)
54
+ RETURN y.year as year,
55
+ g.name as genre,
56
+ count(m) as movie_count,
57
+ avg(toInteger(v.count)) as avg_votes
58
+ ORDER BY y.year, g.name
59
+ """
60
+ result = session.run(query, )
61
+ return pd.DataFrame([dict(record) for record in result])
62
+
63
+ def create_interface():
64
+ analytics = MovieAnalytics()
65
+
66
+ def get_movie_recommendations(genre, year, min_votes):
67
+ try:
68
+ df = analytics.get_recommendations(genre, int(year), int(min_votes))
69
+ if df.empty:
70
+ return "No recommendations found.", None
71
+
72
+ fig = px.bar(df, x='movie', y='votes',
73
+ title=f'Top Movies in {genre} around {year}',
74
+ hover_data=['year'])
75
+ return df, fig
76
+ except Exception as e:
77
+ return f"Error: {str(e)}", None
78
+
79
+ def analyze_actor(actor_name):
80
+ try:
81
+ df = analytics.get_actor_genre_analysis(actor_name)
82
+ if df.empty:
83
+ return "No data found for this actor.", None
84
+
85
+ fig = px.bar(df, x='genre', y='movie_count',
86
+ title=f'Genre Distribution for {actor_name}',
87
+ hover_data=['avg_votes'])
88
+ return df, fig
89
+ except Exception as e:
90
+ return f"Error: {str(e)}", None
91
+
92
+ def show_trends():
93
+ try:
94
+ df = analytics.get_yearly_genre_trends()
95
+ if df.empty:
96
+ return "No trend data available.", None
97
+
98
+ fig = px.line(df, x='year', y='movie_count', color='genre',
99
+ title='Genre Trends Over Years')
100
+ return df, fig
101
+ except Exception as e:
102
+ return f"Error: {str(e)}", None
103
+
104
+ with gr.Blocks() as demo:
105
+ gr.Markdown("""
106
+ # Movie Analytics Dashboard
107
+ Explore movie recommendations and trends based on various factors.
108
+ """)
109
+
110
+ with gr.Tab("Movie Recommendations"):
111
+ with gr.Row():
112
+ genre_input = gr.Textbox(label="Genre")
113
+ year_input = gr.Number(label="Year", value=2020)
114
+ votes_input = gr.Number(label="Minimum Votes", value=1000)
115
+
116
+ recommend_btn = gr.Button("Get Recommendations")
117
+ rec_output = gr.DataFrame()
118
+ rec_plot = gr.Plot()
119
+
120
+ recommend_btn.click(
121
+ fn=get_movie_recommendations,
122
+ inputs=[genre_input, year_input, votes_input],
123
+ outputs=[rec_output, rec_plot]
124
+ )
125
+
126
+ with gr.Tab("Actor Analysis"):
127
+ actor_input = gr.Textbox(label="Actor Name")
128
+ actor_btn = gr.Button("Analyze Actor")
129
+ actor_output = gr.DataFrame()
130
+ actor_plot = gr.Plot()
131
+
132
+ actor_btn.click(
133
+ fn=analyze_actor,
134
+ inputs=actor_input,
135
+ outputs=[actor_output, actor_plot]
136
+ )
137
+
138
+ with gr.Tab("Genre Trends"):
139
+ trend_btn = gr.Button("Show Trends")
140
+ trend_output = gr.DataFrame()
141
+ trend_plot = gr.Plot()
142
+
143
+ trend_btn.click(
144
+ fn=show_trends,
145
+ outputs=[trend_output, trend_plot]
146
+ )
147
+
148
+ return demo
149
+
150
+ if __name__ == "__main__":
151
+ demo = create_interface()
152
+ demo.launch()