Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Song recommendations #16

Merged
merged 7 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
SPOTIPY_CLIENT_ID=your_client_id_here
SPOTIPY_CLIENT_SECRET=your_client_secret_here
SPOTIPY_REDIRECT_URI=http://localhost:5000/callback
SPOTIPY_USER_NAME=your_user_name_here
SPOTIPY_USER_NAME=your_user_name_here
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_API_BASE_URL=your_openai_api_base_url
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ To set up the project, follow these steps:

1. Clone the repository:

````
```
git clone https://github.com/w3bdesign/spotify-import.git
cd spotify-playlist-creator
```
Expand Down
110 changes: 109 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from flask import Flask, render_template, request, redirect, url_for
import spotipy
import openai
from flask import request, redirect, url_for, session
from flask import Flask, request, jsonify
from dotenv import load_dotenv
from spotipy.oauth2 import SpotifyOAuth
import os
Expand All @@ -14,6 +16,13 @@
client_secret = os.getenv("SPOTIPY_CLIENT_SECRET")
redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI")
username = os.getenv("SPOTIPY_USER_NAME")
openai_api_key = os.getenv("OPENAI_API_KEY")
openai_api_base_url = os.getenv("OPENAI_API_BASE_URL")

# Set the OpenAI API key and base URL
openai.api_key = openai_api_key
openai.api_base = openai_api_base_url


# Create a Spotify OAuth object
sp_oauth = SpotifyOAuth(
Expand All @@ -24,7 +33,84 @@
username=username,
)

"""
Generate song suggestions based on a seed song.

:param seed_song: The seed song to generate suggestions from.
:type seed_song: str
:param num_suggestions: The number of song suggestions to generate, defaults to 10.
:type num_suggestions: int
:return: A list of song suggestions based on the seed song.
:rtype: List[str]
"""


def generate_song_suggestions(seed_song, num_suggestions=10):
prompt = f"Based on the song '{seed_song}', please suggest {num_suggestions} similar songs."

response = openai.ChatCompletion.create(
#model="gpt-4",
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": prompt},
],
)

return response


"""
Route that searches for a song given the song name passed as a query parameter.
If the song name is not provided, returns a JSON error message with status code 400.
If the song is found, returns the preview URL of the first matching track as a JSON response.
If the song is not found, returns a JSON error message with status code 404.
:return: A JSON response with the preview URL of the song or an error message.
"""
@app.route("/search_song", methods=["GET"])
def search_song():
song_name = request.args.get("song_name")
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
scope="playlist-modify-public",
username=username,
)
)
if not song_name:
return jsonify({"error": "No song name provided"}), 400

results = sp.search(q=song_name, type="track", limit=1)
if results and results["tracks"]["items"]:
track = results["tracks"]["items"][0]
song_url = track["preview_url"]
return jsonify({"song_url": song_url})
else:
return jsonify({"error": "Song not found"}), 404


"""
Defines a POST endpoint that generates song suggestions based on a given seed song.

Returns:
A JSON object containing a list of suggested songs based on the seed song.
"""
@app.route("/generate_suggestions", methods=["POST"])
def generate_suggestions():
data = request.get_json()
seed_song = data.get("song")
suggestions = generate_song_suggestions(seed_song)
return jsonify(suggestions)


"""
This function is the callback endpoint for the application's OAuth2 authentication flow.
It receives an authorization code from the user's grant, exchanges it for an access token, and stores the token in the user's session.
If successful, the user is redirected to the application's index page.
If the user does not provide a code or the token cannot be obtained, an error message is returned.
If successful, redirects the user to the application's index page. If unsuccessful, returns an error message string.
"""
@app.route("/callback")
def callback():
code = request.args.get("code")
Expand All @@ -36,8 +122,25 @@ def callback():
return "Error: No code provided or token not obtained."


@app.route("/", methods=["GET", "POST"])
@app.route("/", methods=["GET"])
def index():
return render_template(
"index.html",
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
)


"""
Defines the index route for the web application. Handles GET and POST requests.
On a POST request, creates a Spotify playlist based on user input and adds recommended songs.
Returns a redirect to the success page on a successful POST request.
On a GET request, renders the index.html template with the necessary Spotify credentials.
:return: A redirect to the success page on a successful POST request. Otherwise, renders the index.html template.
"""
@app.route("/generate_playlist", methods=["POST"])
def create_playlist():
if request.method == "POST":
playlist_name = request.form["playlist_name"]
playlist_description = request.form["playlist_description"]
Expand Down Expand Up @@ -76,10 +179,15 @@ def index():
redirect_uri=redirect_uri,
)


"""
Renders the success.html template with the playlist_name parameter if it exists in the current request arguments.
"""
@app.route("/success")
def success():
playlist_name = request.args.get("playlist_name", "")
return render_template("success.html", playlist_name=playlist_name)


if __name__ == "__main__":
app.run(debug=True)
Loading