File: server.rst

package info (click to toggle)
python-aiohttp 0.17.2-1~bpo8%2B1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 2,368 kB
  • sloc: python: 19,899; makefile: 205
file content (150 lines) | stat: -rw-r--r-- 4,195 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
.. _aiohttp-server:

Low-level HTTP Server
=====================

.. highlight:: python

.. currentmodule:: aiohttp.server

.. note::

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

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

 .. code-block:: python

      from urllib.parse import urlparse, parse_qsl

      import aiohttp
      import aiohttp.server
      from aiohttp.multidict import MultiDict


      import asyncio

      class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        @asyncio.coroutine
        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>')
            yield from 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.

 .. code-block:: python

    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.


 .. code-block:: python

    from urllib.parse import urlparse, parse_qsl

    from aiohttp.multidict import MultiDict

    class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        @asyncio.coroutine
        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)


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.

 .. code-block:: python

    from urllib.parse import urlparse, parse_qsl

    from aiohttp.multidict import MultiDict

    class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):

        @asyncio.coroutine
        def handle_request(self, message, payload):
            response = aiohttp.Response(
                self.writer, 200, http_version=message.version
            )
            data = yield from 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.BaseEventLoop.create_server` method of the loop.

 .. code-block:: python

    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::