Pyjo.Message.Request - HTTP request

from Pyjo.Message.Request import Request

# Parse
req = Request()
req.parse(b'GET /foo HTTP/1.0\x0d\x0a')
req.parse(b'Content-Length: 12\x0d\x0a')
req.parse(b'Content-Type: text/plain\x0d\x0a\x0d\x0a')
req.parse(b'Hello World!')
print(req.method)
print(req.headers.content_type)
print(req.body)

# Or import the module, as in Google Python Style Guide

import Pyjo.Message.Request

# Parse
req = Pyjo.Message.Request.new()
req.parse(b'GET /foo HTTP/1.0\x0d\x0a')
req.parse(b'Content-Length: 12\x0d\x0a')
req.parse(b'Content-Type: text/plain\x0d\x0a\x0d\x0a')
req.parse(b'Hello World!')
print(req.method)
print(req.headers.content_type)
print(req.body)

# Build
req = Pyjo.Message.Request.new()
req.url.parse('http://127.0.0.1/foo/bar')
req.method = 'GET'
print(req.to_bytes())

Pyjo.Message.Request is a container for HTTP requests, based on RFC 7230, RFC 7231, RFC 7235 and RFC 2817.

Events

Pyjo.Message.Request inherits all events from Pyjo.Message.

See also

Pyjoyment, https://mojolicious.org.

Ported from Mojo::Message::Request of Mojolicious 9.49.

class Pyjo.Message.Request.Pyjo_Message_Request(request: urllib.request.Request | http.server.BaseHTTPRequestHandler | None = None, /, *, env: Mapping[str, Any] | None = None, method: str = 'GET', proxy: Pyjo_URL | None = None, request_id: str | None = None, reverse_proxy: bool | None = None, trusted_proxies: list[str] | None = None, url: Pyjo_URL | None = None, via_proxy: bool = True, **kwargs: Any)[source]

Pyjo.Message.Request inherits all methods from Pyjo.Message and implements the following new ones.

__init__(request: urllib.request.Request | http.server.BaseHTTPRequestHandler | None = None, /, *, env: Mapping[str, Any] | None = None, method: str = 'GET', proxy: Pyjo_URL | None = None, request_id: str | None = None, reverse_proxy: bool | None = None, trusted_proxies: list[str] | None = None, url: Pyjo_URL | None = None, via_proxy: bool = True, **kwargs: Any) → None[source]
req = Pyjo.Message.Request.new()
req = Pyjo.Message.Request.new(method='POST', url=Pyjo.URL.new('http://127.0.0.1/'))
req = Pyjo.Message.Request.new(urllib.request.Request('http://127.0.0.1/', data=b'Hi!'))
req = Pyjo.Message.Request.new(handler)

Construct a new Pyjo.Message.Request object, from a request of the standard library if it is given: the method, URL, headers and data of a urllib.request.Request, or the request that a http.server.BaseHTTPRequestHandler has parsed, which is parsed again, as parse() does, with the body that it reads from the rfile of the handler, of the Content-Length or chunked, and not further.

# A request in a handler of http.server
class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        req = Pyjo.Message.Request.new(self)
        res = Pyjo.Message.Response.new(code=200).set(body=bytes(req.url.path))
        self.wfile.write(res.to_bytes())
clone() → Self | None[source]
clone = req.clone()

Return a new Pyjo.Message.Request object cloned from this request if possible, otherwise return None.

cookies() → list[Pyjo_Cookie_Request][source]
cookies(cookie: Pyjo_Cookie | Mapping[str, Any], /, *cookies: Anything) → Self
cookies = req.cookies()
req = req.cookies(Pyjo.Cookie.Request.new())
req = req.cookies({'name': 'foo', 'value': 'bar'})

Access request cookies, usually Pyjo.Cookie.Request objects.

# Names of all cookies
for cookie in req.cookies():
    print(cookie.name)
env: Mapping[str, Any]
env = req.env
req.env = {'PATH_INFO': '/'}

Direct access to the CGI or WSGI environment dict if available.

# Check CGI version
version = req.env['GATEWAY_INTERFACE']

# Check WSGI version
version = req.env['wsgi.version']
every_param(name: str) → list[str][source]
values = req.every_param('foo')

Similar to param(), but returns all values sharing the same name as a list.

# Get first value
print(req.every_param('foo')[0])
extract_start_line(buffer: bytearray) → bool | None[source]
boolean = req.extract_start_line(buffer)

Extract request-line from a bytearray, which loses it.

fix_headers() → Self[source]
req = req.fix_headers()

Make sure request has all required headers.

get_start_line_chunk(offset: int) → bytes[source]
data = req.get_start_line_chunk(offset)

Get a chunk of request-line data starting from a specific position. Note that this method finalizes the request.

property is_handshake: bool[source]
boolean = req.is_handshake

Check Upgrade header for websocket value.

property is_secure: bool[source]
boolean = req.is_secure

Check if connection is secure.

property is_xhr: bool[source]
boolean = req.is_xhr

Check X-Requested-With header for XMLHttpRequest value.

method
method = req.method
req.method = 'POST'

HTTP request method, defaults to GET.

param(name: str, /) → str | None[source]
param(name: str, value: Anything, /, *values: Anything) → Pyjo_Parameters
value = req.param('foo')

Access GET and POST parameters extracted from the query string and application/x-www-form-urlencoded or multipart/form-data message body. If there are multiple values sharing the same name, and you want to access more than just the last one, you can use every_param(). Note that this method caches all data, so it should not be called before the entire request body has been received. Parts of the request body need to be loaded into memory to parse POST parameters, so you have to make sure it is not excessively large. There’s a 16MiB limit for requests by default.

property params: Pyjo_Parameters[source]
params = req.params

All GET and POST parameters extracted from the query string and application/x-www-form-urlencoded or multipart/form-data message body, usually a Pyjo.Parameters object. Note that this method caches all data, so it should not be called before the entire request body has been received. Parts of the request body need to be loaded into memory to parse POST parameters, so you have to make sure it is not excessively large. There’s a 16MiB limit for requests by default.

# Get parameter names and values
params = req.params.to_dict()
parse(chunk: bytes | Mapping[str, Any]) → Self[source]
req = req.parse(b'GET /foo/bar HTTP/1.1')
req = req.parse({'PATH_INFO': '/'})

Parse HTTP request chunks or environment dict.

proxy
url = req.proxy
req.proxy = Pyjo.URL.new('http://127.0.0.1:3000')

Proxy URL for request.

property query_params: Pyjo_Parameters[source]
params = req.query_params

All GET parameters, usually a Pyjo.Parameters object.

# Turn GET parameters to dict and extract value
print(req.query_params.to_dict()['foo'])
property request_id: str[source]
request_id = req.request_id
req.request_id = 'aee7d5d8'

Request ID, defaults to a reasonably unique value.

reverse_proxy
boolean = req.reverse_proxy
req.reverse_proxy = boolean

Request has been performed through a reverse proxy.

property start_line_size: int[source]
size = req.start_line_size

Size of the request-line in bytes. Note that this method finalizes the request.

to_urllib() → Request[source]
request = req.to_urllib()

Turn request into a urllib.request.Request, with the absolute url, the headers, the body and the proxy. urllib takes no userinfo in a URL, so the userinfo of url and proxy becomes the Authorization and Proxy-Authorization headers, as fix_headers() does.

# Send the request with urllib
with urllib.request.urlopen(req.to_urllib()) as response:
    res = Pyjo.Message.Response.new(response)
trusted_proxies: list[str]
proxies = req.trusted_proxies
req.trusted_proxies = ['10.0.0.0/8', '127.0.0.1', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']

Trusted reverse proxies, addresses or networks in CIDR form.

property url: Pyjo_URL[source]
url = req.url
req.url = Pyjo.URL.new()

HTTP request URL, defaults to a Pyjo.URL object.

# Get request information
info = req.url.to_abs().userinfo
host = req.url.to_abs().host
path = req.url.to_abs().path
via_proxy
boolean = req.via_proxy
req.via_proxy = boolean

Request can be performed through a proxy server.