TutuAwad commited on
Commit
b2966ed
·
verified ·
1 Parent(s): 4b262ed

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -0
app.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ HarmoniFind Gradio Backend
3
+ Deploy this to Hugging Face Spaces or run locally
4
+
5
+ To deploy to Hugging Face Spaces:
6
+ 1. Create account at https://huggingface.co
7
+ 2. Create new Space with Gradio SDK
8
+ 3. Upload this file as app.py
9
+ 4. Upload your embeddings and index files
10
+ 5. Copy the Space URL to your frontend config
11
+ """
12
+
13
+ import gradio as gr
14
+ import numpy as np
15
+ from sentence_transformers import SentenceTransformer
16
+ import json
17
+
18
+ # ============= CONFIGURATION =============
19
+ MODEL_NAME = 'all-mpnet-base-v2'
20
+ MIN_SIMILARITY_THRESHOLD = 0.5
21
+ TOP_K_RESULTS = 10
22
+
23
+ # ============= LOAD YOUR DATA HERE =============
24
+ # TODO: Replace these with your actual data loading
25
+ # Load your FAISS index, song metadata, and embeddings
26
+
27
+ # Example structure for your song metadata:
28
+ # songs_metadata = [
29
+ # {
30
+ # "title": "Song Title",
31
+ # "artist": "Artist Name",
32
+ # "lyrics": "Full lyrics text...",
33
+ # "spotify_url": "https://open.spotify.com/track/..."
34
+ # },
35
+ # ...
36
+ # ]
37
+
38
+ # For demo purposes, using mock data:
39
+ songs_metadata = [
40
+ {
41
+ "title": "Rise Up",
42
+ "artist": "Andra Day",
43
+ "lyrics": "You're broken down and tired, Of living life on a merry go round...",
44
+ "spotify_url": "https://open.spotify.com/track/4fSlpKIGm3xa5Q0h7r0qVL"
45
+ },
46
+ {
47
+ "title": "Stronger",
48
+ "artist": "Kelly Clarkson",
49
+ "lyrics": "What doesn't kill you makes you stronger...",
50
+ "spotify_url": "https://open.spotify.com/track/0WqIKmW4BTrj3eJFmnCKMv"
51
+ },
52
+ {
53
+ "title": "Fight Song",
54
+ "artist": "Rachel Platten",
55
+ "lyrics": "This is my fight song, Take back my life song...",
56
+ "spotify_url": "https://open.spotify.com/track/4PXLm6TfjCvQsn9PkW78eN"
57
+ }
58
+ ]
59
+
60
+ # ============= INITIALIZE MODEL =============
61
+ print("Loading sentence transformer model...")
62
+ model = SentenceTransformer(MODEL_NAME)
63
+
64
+ # TODO: Load your FAISS index
65
+ # import faiss
66
+ # index = faiss.read_index('path_to_your_index.faiss')
67
+
68
+ # TODO: Load your precomputed embeddings
69
+ # with open('song_embeddings.npy', 'rb') as f:
70
+ # song_embeddings = np.load(f)
71
+
72
+ # For demo: compute embeddings on the fly (replace with your pre-computed ones)
73
+ print("Computing embeddings for demo songs...")
74
+ demo_lyrics = [song['lyrics'] for song in songs_metadata]
75
+ song_embeddings = model.encode(demo_lyrics, convert_to_numpy=True)
76
+ song_embeddings = song_embeddings / np.linalg.norm(song_embeddings, axis=1, keepdims=True)
77
+
78
+ # ============= SEARCH FUNCTION =============
79
+ def search_songs(query: str) -> list:
80
+ """
81
+ Perform semantic search on song lyrics
82
+
83
+ Args:
84
+ query: Text description of desired song characteristics
85
+
86
+ Returns:
87
+ List of matching songs with similarity scores
88
+ """
89
+ if not query or not query.strip():
90
+ return []
91
+
92
+ try:
93
+ # Encode the query
94
+ query_embedding = model.encode([query], convert_to_numpy=True)
95
+ query_embedding = query_embedding / np.linalg.norm(query_embedding, axis=1, keepdims=True)
96
+
97
+ # Compute similarities (cosine similarity since embeddings are normalized)
98
+ similarities = np.dot(song_embeddings, query_embedding.T).flatten()
99
+
100
+ # Get top K indices sorted by similarity
101
+ top_indices = np.argsort(similarities)[::-1][:TOP_K_RESULTS]
102
+
103
+ # Format results and filter by threshold
104
+ results = []
105
+ for idx in top_indices:
106
+ similarity = float(similarities[idx])
107
+
108
+ # Only include results above threshold
109
+ if similarity >= MIN_SIMILARITY_THRESHOLD:
110
+ song = songs_metadata[idx]
111
+ results.append({
112
+ "title": song['title'],
113
+ "artist": song['artist'],
114
+ "similarity": similarity,
115
+ "spotifyUrl": song.get('spotify_url', '')
116
+ })
117
+
118
+ return results
119
+
120
+ except Exception as e:
121
+ print(f"Error during search: {str(e)}")
122
+ return []
123
+
124
+ # ============= GRADIO INTERFACE =============
125
+ def gradio_search(query: str) -> str:
126
+ """Wrapper function for Gradio that returns JSON string"""
127
+ results = search_songs(query)
128
+ return json.dumps(results, indent=2)
129
+
130
+ # Create Gradio interface
131
+ demo = gr.Interface(
132
+ fn=gradio_search,
133
+ inputs=gr.Textbox(
134
+ label="Search Query",
135
+ placeholder="Describe the song you're looking for...",
136
+ lines=3
137
+ ),
138
+ outputs=gr.JSON(label="Search Results"),
139
+ title="🎵 HarmoniFind Backend",
140
+ description=f"""
141
+ Semantic music search powered by {MODEL_NAME} embeddings.
142
+
143
+ **Current Settings:**
144
+ - Minimum Similarity: {MIN_SIMILARITY_THRESHOLD * 100}%
145
+ - Top Results: {TOP_K_RESULTS}
146
+ - Dataset: {len(songs_metadata)} songs
147
+
148
+ Enter a description of lyrical themes, emotions, or narratives to find matching songs.
149
+ """,
150
+ examples=[
151
+ ["Uplifting song about overcoming personal challenges"],
152
+ ["Melancholic love song with introspective narrative"],
153
+ ["Energetic anthem about friendship and loyalty"],
154
+ ["Reflective song about life transitions and growth"],
155
+ ],
156
+ api_name="predict" # This creates the /api/predict endpoint
157
+ )
158
+
159
+ # ============= LAUNCH =============
160
+ if __name__ == "__main__":
161
+ demo.launch(
162
+ server_name="0.0.0.0",
163
+ server_port=7860,
164
+ share=False # Set to True for temporary public link
165
+ )