Comments (5)
My name is Niko actually, but that's all right.
I don't think that the relevant part is included in your snippet, so that's why I straight up built a little example with FastAPI. You said that you're using it as a Backend, so the auth url will be returned as a simple JSON and not as a 307 Temporary Redirect
or similar. Check it out: https://github.com/dieser-niko/spotipy-fastapi-oauth
from spotipy.
It looks like you're on the right track.
The CORS has nothing to do with Spotify and has to be handled by FastAPI instead. You can read more about this here: https://fastapi.tiangolo.com/tutorial/cors/
Then the authentication process. I'd like you to take a look at this app.py example which shows how to get the authorise URL and how a callback from Spotify can be handled. This is a pretty good example, even though it is implemented in Flask. But there's not much difference to FastAPI in this case.
Admittedly, it's a bit tight, because the login process and the callback are implemented in the same function (and therefore the same endpoint).
But it's still possible to understand it. I'll explain it to you.
The function is divided into four parts.
First, the cache_handler
and auth_manager
are created. They are not passed to spotipy.Spotify
yet, and this is important, mainly because of the auth manager, as we don't want to trigger the internal authentication process.
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing playlist-modify-private',
cache_handler=cache_handler,
show_dialog=True)
As for the FlaskSessionCacheHandler
, I'm not sure if there is something similar for FastAPI. I've seen that you've created your own FastAPISessionCacheHandler
, and honestly, it's probably fine to start with. You just have to remember that the user can easily extract the token. They shouldn't be able to do much damage as the token is tied to their account anyway.
Then, in the second part, it checks if the incoming request is from a callback function by checking if "code" is one of the arguments used. The value of this argument is then checked for authenticity. If all is well, the user is logged in and the page is refreshed by redirecting to the same page.
if request.args.get("code"):
# Step 2. Being redirected from Spotify auth page
auth_manager.get_access_token(request.args.get("code"))
return redirect('/')
The third part is to check if the user isn't logged in. If that's the case, then an authorize url is generated and returned to the user as a link. Yes, I know the order of the parts is a bit confusing, but bear with me. There are also comments here and in part 2 to indicate that this step is the first to be run.
if not auth_manager.validate_token(cache_handler.get_cached_token()):
# Step 1. Display sign in link when no token
auth_url = auth_manager.get_authorize_url()
return f'<h2><a href="{auth_url}">Sign in</a></h2>'
And then the last part, where we finally get our spotipy.Spotify
object by passing our auth_manager
to it. Since we should already be logged in when we reach this part, there should be no prompt asking us to enter a link.
# Step 3. Signed in, display data
spotify = spotipy.Spotify(auth_manager=auth_manager)
return f'<h2>Hi {spotify.me()["display_name"]}, ' \
f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
f'<a href="/playlists">my playlists</a> | ' \
f'<a href="/currently_playing">currently playing</a> | ' \
f'<a href="/current_user">me</a>'
I'd recommend running this code on your machine, but be sure to read the comment at the top of the file. It contains some useful information.
I hope I was able to help you.
from spotipy.
Hi Dieser, I tried the the exact same approach you suggest but its not working, heres why:
in get_access_token
we have
payload = {
"redirect_uri": self.redirect_uri,
"code": code, or self.get_auth_response(),
"grant_type": "authorization_code",
}
So when user hit '/'
endpoint to my backend (which is running on different server from frontend) for very first time, this function gets called: self.get_auth_response()
and the nature of this function is to open new window in computer (server) orr interactive terminal by following the flow it calls: _get_auth_response_interactive
in which it actually execute the logic.
def get_auth_response(self, open_browser=None):
logger.info('User authentication requires interaction with your '
'web browser. Once you enter your credentials and '
'give authorization, you will be redirected to '
'a url. Paste that url you were directed to to '
'complete the authorization.')
redirect_info = urlparse(self.redirect_uri)
redirect_host, redirect_port = get_host_port(redirect_info.netloc)
if open_browser is None:
open_browser = self.open_browser
if (
open_browser
and redirect_host in ("127.0.0.1", "localhost")
and redirect_info.scheme == "http"
):
# Only start a local http server if a port is specified
if redirect_port:
return self._get_auth_response_local_server(redirect_port)
else:
logger.warning('Using `%s` as redirect URI without a port. '
'Specify a port (e.g. `%s:8080`) to allow '
'automatic retrieval of authentication code '
'instead of having to copy and paste '
'the URL your browser is redirected to.',
redirect_host, redirect_host)
return self._get_auth_response_interactive(open_browser=open_browser)
def _get_auth_response_interactive(self, open_browser=False):
if open_browser:
self._open_auth_url()
prompt = "Enter the URL you were redirected to: "
else:
url = self.get_authorize_url()
prompt = (
"Go to the following URL: {}\n"
"Enter the URL you were redirected to: ".format(url)
)
response = self._get_user_input(prompt)
state, code = SpotifyOAuth.parse_auth_response_url(response)
if self.state is not None and self.state != state:
raise SpotifyStateError(self.state, state)
return code
___________________________________________________________________________________
TERMINAL:
(venv) say@ubuntu-xyz:~/app/src$ uvicorn --host 0.0.0.0 main:app
INFO: 137.59.220.8:12607 - "GET /spotify/ HTTP/1.1" 200 OK
INFO: 137.59.220.8:12614 - "GET /spotify/callback?code=AQBoiQiqufrNiKvstckYhncSoyA4DHA HTTP/1.1" 307 Temporary Redirect
Enter the URL you were redirected to:
from spotipy.
Hey hey hey, ty Niko, it works. Although I've tried it manually which also working perfectly fine but I'll update my code with this approach so I don't fall under unexpected error in future.
from spotipy.
Glad to hear that. If you want to, you can change to an authorization header instead of cookies. Probably the only thing I regret about my code :D
from spotipy.
Related Issues (20)
- Enhance Spotipy with Language Information for Tracks HOT 1
- Issue with sp.track(track_id) function freezing code execution HOT 3
- How to delete playlists using spotipy HOT 7
- Get Artist's Albums now expects "include_groups" param instead of "album_type" HOT 1
- Documentation Section Suggestion: “A Quick Tutorial To Get Started” HOT 2
- Simple spelling error in documentation
- Improve 'util.py' with function docstrings HOT 4
- the playlist function stopped working between yesterday and today HOT 5
- API Reference Refers to Deprecated Methods HOT 2
- Update Directions In TUTORIAL.md
- Documentation for version 2.23.0 not available HOT 8
- Current 2.23.0 install from pip doesn't include latest code HOT 4
- Update Directions and Content of CONTRIBUTING.md HOT 1
- Adding a custom date range for users top tracks and top artist HOT 1
- Account Creation Timestamp field HOT 2
- Any way to play a playlist? Without premium if possible. HOT 1
- Podcast transcript HOT 1
- How spotipy have to be setted for deploying? HOT 1
- How do I start playback on the command line/headless? HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spotipy.