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

Design and prototype new HTTP API #736

Open
sampsyo opened this issue Apr 30, 2014 · 5 comments
Open

Design and prototype new HTTP API #736

sampsyo opened this issue Apr 30, 2014 · 5 comments
Labels

Comments

@sampsyo
Copy link
Member

@sampsyo sampsyo commented Apr 30, 2014

This is a subtask of the next-generation web interface effort (#718).

We should start designing the new JSON/REST API. We can start with code or documentation first (whichever's easiest). But here's how I propose we go about it:

  • To avoid bikeshedding, let's follow the JSON API template.
  • Implement the prototype as a new beets plugin called serve (i.e., beetsplug/serve.py). We will probably eventually roll this into beets core, but a plugin is a good place to play for now. The API should be documented in docs/plugins/serve.rst.
  • We should place an emphasis on generality. Where reasonable, the API should be useful for non-beets tools. In spirit, the API could serve as a better (and better-documented!) alternative to DAAP, DLNA, or Subsonic for music browsing and streaming.
  • No need for backwards compatibility with the old API.
  • The prototype plugin should not have an HTML frontend. It should only expose the machine-readable API.

Here are some proposed requirements for the new API design:

  • Look up and query tracks, albums, and maybe artists (just like the current API).
  • Stream music files (again, like the current API).
  • Optional authentication. Options include HTTP basic with token acquisition, OAuth, etc.
  • Provide extension points for other functionality not listed here. I'm not sure what form this should come in, but the extensibility should at least afford an REST API to the importer. Other extensions to be kept in mind include:
    • Server-side playback control.
    • Server-side transcoding for browser playback.
  • A mechanism for mounting browser frontends. This is important because, without some support, the single-origin policy will prevent HTML frontends hosted elsewhere from accessing the HTTP API. We can do this either by serving up user-specified HTML pages on the server itself or by using CORS to permit access. (Note that this is more a part of the prototype implementation than the API itself.)

Anything else to add?

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Apr 30, 2014

You didn't specify, but the API should probably support generic beets queries (like beets ls), just like the old API.

Also, there should be a way to get a list unique field values (combined with the queries). The query could take a return format and group by that format (like beet ls -f but returning only unique results). Some exemples of what would then be possible:

  1. Get all composers
  2. Get all albums where composer:Beethoven
  3. Get all tracks where composer:Beethoven AND album:XYZ
  4. Get all tracks where bpm>130
@sampsyo

This comment has been minimized.

Copy link
Member Author

@sampsyo sampsyo commented May 1, 2014

Indeed, using queries will be a great strength.

Server-side uniqueing is interesting. If we do that, we'll first need a SELECT-like projection operator—not sure what that would look like.

@sampsyo sampsyo mentioned this issue May 1, 2014
0 of 3 tasks complete
@PierreRust

This comment has been minimized.

Copy link
Collaborator

@PierreRust PierreRust commented May 3, 2014

I totally agree with following the JSONAPI template when possible to avoid reinventing the wheel.
I've also found this article which list many best practices for REST api. It seems to be generally compatible with the JSONAPI but it might be sometime easier to read and more pragmatic.

Concerning CORS, I would suggest simply adding the relevant Access-Control-Allow-XXX headers (very simple with flask) to avoid any problem with this. I think a beets server would always run in a LAN anyway and that Cross scripting should not really be a problem.

For the implementation we could stick with flask and maybe use flask-restful to make things easier.

@PierreRust

This comment has been minimized.

Copy link
Collaborator

@PierreRust PierreRust commented May 5, 2014

I've started a prototype implementation (in my github fork) with flask and marshmallow (from my tests, flask-restful did not seem really useful in our case). I'm also considering hyp to implement the JSON-API format ; the project is very young but we might end-up writing something similar anyway to implement json-api.

Some more thoughts :

  • for sorting support in the HTTP API , we probably need to add support for sorting directly into the query system inside the core (currently, sort order is hardcoded library#albums and library#items). To keep track of this, I may be useful to create a separate issue (I can create it if you agree)
  • the same might applies for pagination : we can code it in the serve plugin but it will then be a the naive pagination implementation. I think I'll do that in my prototype but it would be great if pagination was built into the core (and it could be use by the CLI )
@sampsyo

This comment has been minimized.

Copy link
Member Author

@sampsyo sampsyo commented May 5, 2014

Nice! I'm glad this is going well—the direction seems great already. Brief notes:

  • Hyp does seem useful. If we can be helpful and contribute back there, all the better. Yay for open source.
  • Yes, it does seem like it's time to add sorting to dbcore. Let's track that with a separate issue. (As an aside, it would be nice if users could easily type sorting options as part of queries, even on the command line.)
  • The same with pagination. A clean and simple API does belong in dbcore. There has been plenty of discussion above about how to do this efficiently.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.