jsncmgs1 / spotify_ex Goto Github PK
View Code? Open in Web Editor NEWElixir wrapper for the Spotify Web API
License: Other
Elixir wrapper for the Spotify Web API
License: Other
Hi @jsncmgs1!
Thank you for your work!
I'm opening this issue to know if you're interested in extending this package to Web API endpoints (other than the authentication flow). I'm going to work a lot with spotify + elixir in the next months, and I'd like to contribute to this package more than creating a new one with another name (packages pollution is a problem nowadays :D ).
Let me know if you'd accept pull requests about api endpoints mapping and spotify entity abstractions (structs and stuff like that).
Thanks!
It looks like any function that makes a request to Spotify needs a Plug.Conn with a cookie inside that contains the auth tokens. This effectively limits this library to be used only in conjunction with a web application.
What about providing some way to store the auth data in a process instead so that one could use this library without a browser involved?
The Spotify.Track.audio_features function returns nil instead of an error.
An error occurs because there is a track without audio features. This is not intended as far as I know and an error on Spotify's side but it does exist. 1OegbevPjnz3BBlyzkBT4K
this is an id of a track that has no audio features.
It would be nice if the function would return :error. The nil return also means that if you query lost of IDs that you cant get the info of the tracks that didn't fail.
Can I follow the OAuth2 doc in the readme and use this as Strategy for logging in the user instead of using other libraries like uberauth?
Well hey there! I am using httpoison for my project and have it defined in my mix.exs deps for the current version, that being 1.0.0. When I went to add spotify_ex I got this:
Unchecked dependencies for environment dev:
* spotify_ex (Hex package)
the dependency is not available, run "mix deps.get"
** (Mix) Can't continue due to errors on dependencies
➜ lean git:(master) ✗ mix deps.get
Resolving Hex dependencies...
Failed to use "httpoison" (version 1.0.0) because
spotify_ex (version 2.0.7) requires ~> 0.13.0
mix.lock specifies 1.0.0
** (Mix) Hex dependency resolution failed, change the version requirements of your dependencies or unlock them (by using mix deps.update or mix deps.unlock). If you are unable to resolve the conflicts you can try overriding with {:dependency, "~> 1.0", override: true}
Everything seems to work when I add override: true to the httpoison entry, but its not ideal.
Thanks.
I'm trying to wrap Spotify
with a little module that automatically refreshes expired tokens like so
defmodule SpotifyAgent do
def call(conn, func) do
result = func.(conn)
case result do
{:ok, response} ->
result
{:error, e} ->
refresh(conn)
call(conn, func)
end
end
defp refresh(conn) do
Spotify.refresh(conn)
end
end
However, 401 Expired responses are coming through as :ok
. Is this expected? I'd think it'd be an :error
.
{:ok, %{"error" => %{"message" => "The access token expired", "status" => 401}}}
In explaining the uris
parameter of the Create Playlist API, The Spotify API docs state:
Note: it is likely that passing a large number of track URIs as a query parameter will exceed the maximum length of the request URI. When adding a large number of tracks it is recommended to pass them in the request body, see below.
It looks like the current implementation of add_tracks in spotify_ex's playlist.ex uses query parameters, but states:
You can also pass the URI param in the request body. Use `add_tracks/2`. See Spotify docs.
Spotify.Playlist.add_tracks("123", "456", uris: "spotify:track:4iV5W9uYEdYUVa79Axb7Rh")
# => {:ok, %{"snapshot_id" => "foo"}}
I may be missing something, but I don't see add_tracks/2
defined, and looking through the code I don't see a way to add tracks via the request body. Am I missing something obvious, or is adding support for adding tracks via the request body something that should be added?
Additionally: is there any reason to support adding tracks through a query parameter, or would it be better to just always add them through the request body?
When the client secret is configured incorrectly, attempting to authenticate should yield an error. Instead, Spotify.Authentication.authenticate
still returns {:ok, conn}
, but Spotify-related token cookies will be nil.
There's already some kind of check for this, in that AuthenticationClient
checks if the HTTPoison.post
succeeded or not. But it looks like HTTPoison.post
reports success even when the response code is 400.
You can see this yourself if you configure a client secret incorrectly and add a couple IO.inspect
calls:
def post(params) do
case AuthRequest.post(params) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} ->
with {:ok, response} <- Poison.decode(body) do
IO.inspect(code) # todo remove
IO.inspect(response) # todo remove
{:ok, Spotify.Credentials.get_tokens_from_response(response)}
else
_unmatched ->
raise(AuthenticationError, "Error parsing response from Spotify")
end
{:error, %HTTPoison.Error{reason: reason}} ->
{ :error, reason }
end
end
With an invalid client secret, I see
400
%{"error" => "invalid_client", "error_description" => "Invalid client secret"}
in my logs.
Hi there!
Currently, this library raises an error during the authentication phase when a user denies the library access to its resource. Is there a reason why the last clause of Spotify.Authentication.authenticate/2
raises an error(AuthenticationError
) instead of returning something like {:error, :denied_access}
?
This is to take into account the scenario of when a user denies an app access and by raising an error, this library forces the app to catch the error and I think goes against Elixir norm. And by returning {:error, :denied_access}
, you're giving the library user a chance to handle this specific scenario.
Test directory structure & naming conventions are not idiomatic Elixir, which makes it more difficult to find things if trying to follow the norm.
Actual test structure
lib/spotify/
are directly in test/
(no subfolder)Album
(in the case of testing Spotify.Album
)Expected test structure
lib/spotify/
to be in the directory test/spotify/
Spotify.AlbumTest
(in the case of testing Spotify.Album
)Thoughts on this @jsncmgs1 ?
When trying to call Spotify.Artists.artists_I_follow/2
it throws BadMapError
.
This is happening because the Spotify API /me/following
response uses pagination (it seems to be an update, that's why the lib crashes this way).
When trying to call Spotify.Player.get_recently_played/2 it throws BadMapError.
Working only if parameter 'limit' is assign to 1 like : Spotify.Player.get_recently_played(conn, limit: 1)
Error looks like @ lucasmedeirosleite issue at 22 Oct 2017.
Thx :)
There are a bunch of typos in the README that require no knowledge of this app to be corrected. I'm aware of them but would like a true first timer to submit a PR so they can get their feet wet with open source. If you are already comfortable with PR's and contributing, please leave this for the newcomers.
Hi Jason! I'm using this wrapper for a personal project, and I'm doing some work to add expiration date handling into this wrapper. Just started looking into it, but my current approach is to add spotify's 'expires_in' field to the Credentials struct and authentication flow. I'd be happy to make a PR if you're interested!
It looks like Spotify.Cookies.set_cookies
indirectly halts redirects because it explicitly sets the conn
's HTTP response status to 200. Which causes redirects to just be stuck in a page with a "You are being redirected" message instead of actually prompting the browser to redirect to a specific page.
Any reason why Spotify.Cookies.set_cookies
explicitly sets the status to 200? Is it safe to remove or move somewhere else? If so, I'd be glad to put a PR together for it.
(Another argument for removing the setting of the HTTP status in the there is that in a function named set_cookies
it's quite out of scope of its responsibilities to set the http status along with setting the cookies)
➜ spotify_ex git:(main) mix docs
** (ArgumentError) expected a keyword list, but an entry in the list is not a two-element tuple with an atom as its first element, got: {{:message, 1}, [{:type, 35, :fun, [{:type, 35, :product, [{:user_type, 35, :t, []}]}, {:remote_type, 35, [{:atom, 0, String}, {:atom, 0, :t}, []]}]}]}
(elixir 1.12.3) lib/keyword.ex:475: Keyword.keys/1
(ex_doc 0.19.3) lib/ex_doc/retriever.ex:379: anonymous fn/2 in ExDoc.Retriever.get_impls/1
(elixir 1.12.3) lib/enum.ex:2385: Enum."-reduce/3-lists^foldl/2-0-"/3
(ex_doc 0.19.3) lib/ex_doc/retriever.ex:378: ExDoc.Retriever.get_impls/1
(ex_doc 0.19.3) lib/ex_doc/retriever.ex:161: ExDoc.Retriever.get_module_data/2
(ex_doc 0.19.3) lib/ex_doc/retriever.ex:112: ExDoc.Retriever.generate_node/3
(elixir 1.12.3) lib/enum.ex:3900: Enum.flat_map_list/2
(elixir 1.12.3) lib/enum.ex:3901: Enum.flat_map_list/2
https://github.com/jsncmgs1/spotify_ex/blob/master/lib/spotify/playlist.ex#L284
def add_tracks(conn, user_id, playlist_id, params \\ []) do
url = add_tracks(user_id, playlist_id, params)
conn |> Client.put(url) |> handle_response
end
should be
def add_tracks(conn, user_id, playlist_id, params \\ []) do
url = add_tracks_url(user_id, playlist_id, params)
conn |> Client.put(url) |> handle_response
end
I will submit a PR for this presently.
I don't think any of the endpoints found in the library API are found in other modules (i.e. not duplicated).
Would be great to have a module for this section. I'd be happy to implement & contribute this feature.
In the README and the code I see this being used with Authorization Code. I can't seem to find how to get it working with Client Credentials Flow, just wondering if this is implemented and I'm just missing it or it currently only supports Authorization Code flow?
Hi there,
Just wondering if you could release 2.0.10 so we can get the deps update.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.