HTTP server side API
The Mopidy-HTTP extension comes with an HTTP server to host Mopidy’s HTTP JSON-RPC API. This web server can also be used by other extensions that need to expose something over HTTP.
The HTTP server side API can be used to:
host static files for e.g. a Mopidy client written in pure JavaScript,
host a Tornado application, or
host a WSGI application, including e.g. Flask applications.
To host static files using the web server, an extension needs to register a
name and a file path in the extension registry under the http:static
key.
To extend the web server with a web application, an extension must register a
name and a factory function in the extension registry under the http:app
key.
For details on how to make a Mopidy extension, see the Extension development guide.
Static web client example
To serve static files, you just need to register an http:static
dictionary
in the extension registry. The dictionary must have two keys: name
and
path
. The name
is used to build the URL the static files will be
served on. By convention, it should be identical with the extension’s
ext_name
, like in the following example. The
path
tells Mopidy where on the disk the static files are located.
Assuming that the code below is located in the file
mywebclient/__init__.py
, the files in the directory
mywebclient/static/
will be made available at /mywebclient/
on
Mopidy’s web server. For example, mywebclient/static/foo.html
will be
available at http://localhost:6680/mywebclient/foo.html.
import os
from mopidy import ext
class MyWebClientExtension(ext.Extension):
ext_name = 'mywebclient'
def setup(self, registry):
registry.add('http:static', {
'name': self.ext_name,
'path': os.path.join(os.path.dirname(__file__), 'static'),
})
# See the Extension API for the full details on this class
Tornado application example
The Mopidy-HTTP extension’s web server is based on the Tornado web framework. Thus, it has first class support for Tornado request handlers.
In the following example, we create a tornado.web.RequestHandler
called MyRequestHandler
that responds to HTTP GET requests with the
string Hello, world! This is Mopidy $version
, where it gets the Mopidy
version from Mopidy’s core API.
To hook the request handler into Mopidy’s web server, we must register a
dictionary under the http:app
key in the extension registry. The
dictionary must have two keys: name
and factory
.
The name
is used to build the URL the app will be served on. By convention,
it should be identical with the extension’s
ext_name
, like in the following example.
The factory
must be a function that accepts two arguments, config
and
core
, respectively a dict structure of Mopidy’s config and a
pykka.ActorProxy
to the full Mopidy core API. The factory
function
must return a list of Tornado request handlers. The URL patterns of the request
handlers should not include the name
, as that will be prepended to the URL
patterns by the web server.
When the extension is installed, Mopidy will respond to requests to
http://localhost:6680/mywebclient/ with the string Hello, world! This is
Mopidy $version
.
import os
import tornado.web
from mopidy import ext
class MyRequestHandler(tornado.web.RequestHandler):
def initialize(self, core):
self.core = core
def get(self):
self.write(
'Hello, world! This is Mopidy %s' %
self.core.get_version().get())
def my_app_factory(config, core):
return [
('/', MyRequestHandler, {'core': core})
]
class MyWebClientExtension(ext.Extension):
ext_name = 'mywebclient'
def setup(self, registry):
registry.add('http:app', {
'name': self.ext_name,
'factory': my_app_factory,
})
# See the Extension API for the full details on this class
WSGI application example
WSGI applications are second-class citizens on Mopidy’s HTTP server. The WSGI applications are run inside Tornado, which is based on non-blocking I/O and a single event loop. In other words, your WSGI applications will only have a single thread to run on, and if your application is doing blocking I/O, it will block all other requests from being handled by the web server as well.
The example below shows how a WSGI application that returns the string
Hello, world! This is Mopidy $version
on all requests. The WSGI application
is wrapped as a Tornado application and mounted at
http://localhost:6680/mywebclient/.
import os
import tornado.web
import tornado.wsgi
from mopidy import ext
def my_app_factory(config, core):
def wsgi_app(environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return [
'Hello, world! This is Mopidy %s\n' %
self.core.get_version().get()
]
return [
('(.*)', tornado.web.FallbackHandler, {
'fallback': tornado.wsgi.WSGIContainer(wsgi_app),
}),
]
class MyWebClientExtension(ext.Extension):
ext_name = 'mywebclient'
def setup(self, registry):
registry.add('http:app', {
'name': self.ext_name,
'factory': my_app_factory,
})
# See the Extension API for the full details on this class
API implementors
See the extension registry.