1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
.. _http-server-api:
********************
HTTP server side API
********************
The :ref:`ext-http` extension comes with an HTTP server to host Mopidy's
:ref:`http-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 <https://www.tornadoweb.org/>`__ 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 :ref:`extensiondev`
guide.
.. _static-web-client:
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
:attr:`~mopidy.ext.Extension.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
:file:`mywebclient/__init__.py`, the files in the directory
:file:`mywebclient/static/` will be made available at ``/mywebclient/`` on
Mopidy's web server. For example, :file:`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 :ref:`ext-http` extension's web server is based on the `Tornado
<https://www.tornadoweb.org/>`__ web framework. Thus, it has first class support
for Tornado request handlers.
In the following example, we create a :class:`tornado.web.RequestHandler`
called :class:`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
:attr:`~mopidy.ext.Extension.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
:class:`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 <https://mopidy.com/ext/>`_.
|