File: server.rst

package info (click to toggle)
python-aiohttp 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,288 kB
  • ctags: 4,380
  • sloc: python: 27,221; makefile: 236
file content (155 lines) | stat: -rw-r--r-- 4,613 bytes parent folder | download
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
.. _aiohttp-server:

Deprecated Low-level Server
===========================

.. currentmodule:: aiohttp.server

.. note::

   This topic describes the low-level HTTP support. For high-level
   interface please take a look on :mod:`aiohttp.web`.

.. deprecated:: 1.2

   The module has been deprecated and will be eventually removed.  Use
   :ref:`aiohttp-web-lowlevel` instead.

   The new solution provides much more user friendly API.

Run a basic server
------------------

Start implementing the basic server by inheriting the
:class:`ServerHttpProtocol` object. Your class should
implement the only method :meth:`ServerHttpProtocol.handle_request`
which must be a coroutine to handle requests asynchronously::

      from urllib.parse import urlparse, parse_qsl

      import aiohttp
      import aiohttp.server
      from aiohttp import MultiDict


      import asyncio

      class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        async def handle_request(self, message, payload):
            response = aiohttp.Response(
                self.writer, 200, http_version=message.version
            )
            response.add_header('Content-Type', 'text/html')
            response.add_header('Content-Length', '18')
            response.send_headers()
            response.write(b'<h1>It Works!</h1>')
            await response.write_eof()

The next step is to create a loop and register your handler within a server.
:exc:`KeyboardInterrupt` exception handling is necessary so you can stop
your server with Ctrl+C at any time::

    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        f = loop.create_server(
            lambda: HttpRequestHandler(debug=True, keep_alive=75),
            '0.0.0.0', '8080')
        srv = loop.run_until_complete(f)
        print('serving on', srv.sockets[0].getsockname())
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass

Headers
-------

Data is passed to the handler in the ``message``, while request body is
passed in ``payload`` param.  HTTP headers are accessed through
``headers`` member of the message.  To check what the current method of
the request is use the ``method`` member of the ``message``. It should be one
of ``GET``, ``POST``, ``PUT`` or ``DELETE`` strings.

Handling GET params
-------------------

Currently aiohttp does not provide automatic parsing of incoming GET
params.  However aiohttp does provide a nice
:class:`MulitiDict` wrapper for already parsed params::

    from urllib.parse import urlparse, parse_qsl

    from aiohttp import MultiDict

    class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        async def handle_request(self, message, payload):
            response = aiohttp.Response(
                self.writer, 200, http_version=message.version
            )
            get_params = MultiDict(parse_qsl(urlparse(message.path).query))
            print("Passed in GET", get_params)


Sending pre-compressed data
---------------------------

To include data in the response that is already compressed, do not call
`enable_compression`.  Instead, set the `Content-Encoding` header explicitly::

    @asyncio.coroutine
    def handler(request):
        headers = {'Content-Encoding': 'gzip'}
        deflated_data = zlib.compress(b'mydata')
        return web.Response(body=deflated_data, headers=headers)


Handling POST data
------------------

POST data is accessed through the ``payload.read()`` generator method.
If you have form data in the request body, you can parse it in the same way as
GET params::

    from urllib.parse import urlparse, parse_qsl

    from aiohttp import MultiDict

    class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        async def handle_request(self, message, payload):
            response = aiohttp.Response(
                self.writer, 200, http_version=message.version
            )
            data = await payload.read()
            post_params = MultiDict(parse_qsl(data))
            print("Passed in POST", post_params)

SSL
---

To use asyncio's SSL support, just pass an SSLContext object to the
:meth:`asyncio.AbstractEventLoop.create_server` method of the loop::

    import ssl

    sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    sslcontext.load_cert_chain('sample.crt', 'sample.key')

    loop = asyncio.get_event_loop()
    loop.create_server(lambda: handler, "0.0.0.0", "8080", ssl=sslcontext)



Reference
---------

.. automodule:: aiohttp.server
    :members:
    :undoc-members:
    :show-inheritance:


.. disqus::
  :title: aiohttp low-level server