Skip to content

Commit

Permalink
Merge pull request #16 from w3bdesign/develop
Browse files Browse the repository at this point in the history
Song recommendations
  • Loading branch information
w3bdesign authored May 31, 2023
2 parents c89ce85 + 0375150 commit 54c4086
Show file tree
Hide file tree
Showing 7 changed files with 585 additions and 150 deletions.
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

0 comments on commit 54c4086

Please sign in to comment.