Pyjo.Content - HTTP content base class¶
from Pyjo.Content import Content
class MyContent(Content):
def body_contains(self, chunk): ...
@property
def body_size(self): ...
def get_body_chunk(self, offset): ...
# Or import the module, as in Google Python Style Guide
import Pyjo.Content
class MyContent(Pyjo.Content.object):
def body_contains(self, chunk): ...
@property
def body_size(self): ...
def get_body_chunk(self, offset): ...
Pyjo.Content is an abstract base class for HTTP content containers,
based on RFC 7230 and
RFC 7231, like
Pyjo.Content.MultiPart and Pyjo.Content.Single.
Events¶
Pyjo.Content inherits all events from Pyjo.EventEmitter and can
emit the following new ones.
body¶
content.on('body', lambda content: ...)
Emitted once all headers have been parsed and the body starts.
@content.on('body')
def body(content):
if content.headers.header('X-No-MultiPart'):
content.auto_upgrade = False
drain¶
content.on('drain', lambda content, offset: ...)
Emitted once all data has been written.
content.on('drain', lambda content, offset: content.write_chunk(str(time.time()).encode()))
read¶
content.on('read', lambda content, chunk: ...)
Emitted when a new chunk of content arrives.
content.on('read', lambda content, chunk: print(f'Streaming: {chunk}'))
sse¶
content.on('sse', lambda content, event: ...)
Emitted when a new Server-Sent Event (SSE) connection has been established,
with None for the event, and for each new event that arrives. Note that
this event is EXPERIMENTAL and may change without warning!
@content.on('sse')
def sse(content, event):
if event:
print(f'Type: {event["type"]}, Data: {event["text"]}')
else:
print('SSE connection established')
See also¶
Pyjoyment, https://mojolicious.org.
Ported from Mojo::Content of Mojolicious 9.49.
- class Pyjo.Content.Pyjo_Content(*, auto_decompress: bool | None = None, auto_relax: bool | None = None, headers: Pyjo_Headers | None = None, max_buffer_size: int | None = None, max_leftover_size: int | None = None, relaxed: bool | None = None, skip_body: bool | None = None)[source]¶
Pyjo.Contentinherits all methods fromPyjo.EventEmitterand implements the following new ones.- __init__(*, auto_decompress: bool | None = None, auto_relax: bool | None = None, headers: Pyjo_Headers | None = None, max_buffer_size: int | None = None, max_leftover_size: int | None = None, relaxed: bool | None = None, skip_body: bool | None = None) None[source]¶
content = Pyjo.Content.Single.new() content = Pyjo.Content.Single.new(headers=Pyjo.Headers.new())
Construct a new content object.
- auto_decompress¶
boolean = content.auto_decompress content.auto_decompress = boolean
Decompress content automatically if
is_compressedis true.
- auto_relax¶
boolean = content.auto_relax content.auto_relax = boolean
Try to detect when relaxed parsing is necessary.
- body_contains(chunk: bytes) bool[source]¶
boolean = content.body_contains(b'foo bar baz')
Check if content contains a specific string. Meant to be overloaded in a subclass.
- property body_size: int[source]¶
size = content.body_size
Content size in bytes. Meant to be overloaded in a subclass.
- property boundary: str | None[source]¶
boundary = content.boundary
Extract multipart boundary from
Content-Typeheader.
- property charset: str | None[source]¶
charset = content.charset
Extract charset from
Content-Typeheader.
- clone() Self | None[source]¶
clone = content.clone()
Return a new content object cloned from this content if possible, otherwise return
None.
- generate_body_chunk(offset: int) bytes | None[source]¶
chunk = content.generate_body_chunk(0)
Generate dynamic content.
- get_body_chunk(offset: int) bytes | None[source]¶
chunk = content.get_body_chunk(0)
Get a chunk of content starting from a specific position. Meant to be overloaded in a subclass.
- get_header_chunk(offset: int) bytes[source]¶
chunk = content.get_header_chunk(13)
Get a chunk of the headers starting from a specific position. Note that this method finalizes the content.
- property header_size: int[source]¶
size = content.header_size
Size of headers in bytes. Note that this method finalizes the content.
- property headers: Pyjo_Headers[source]¶
headers = content.headers content.headers = Pyjo.Headers.new()
Content headers, defaults to a
Pyjo.Headersobject.
- headers_contain(chunk: bytes) bool[source]¶
boolean = content.headers_contain(b'foo bar baz')
Check if headers contain a specific string. Note that this method finalizes the content.
- property is_chunked: bool[source]¶
boolean = content.is_chunked
Check if
Transfer-Encodingheader indicates chunked transfer encoding.
- property is_compressed: bool[source]¶
boolean = content.is_compressed
Check
Content-Encodingheader forgzipvalue.
- property is_dynamic: bool[source]¶
boolean = content.is_dynamic
Check if content will be dynamically generated, which prevents
clone()from working.
- property is_limit_exceeded: bool[source]¶
boolean = content.is_limit_exceeded
Check if buffer has exceeded
max_buffer_size.
- property is_multipart: bool[source]¶
boolean = content.is_multipart
False, this is not a
Pyjo.Content.MultiPartobject.
- property is_parsing_body: bool[source]¶
boolean = content.is_parsing_body
Check if body parsing started yet.
- property is_sse: bool[source]¶
boolean = content.is_sse
Check if
Content-Typeheader indicates Server-Sent Events (SSE). Note that this method is EXPERIMENTAL and may change without warning!
- property max_buffer_size: int[source]¶
size = content.max_buffer_size content.max_buffer_size = 1024
Maximum size in bytes of buffer for content parser, defaults to the value of the
PYJO_MAX_BUFFER_SIZEenvironment variable or262144(256KiB).
- property max_leftover_size: int[source]¶
size = content.max_leftover_size content.max_leftover_size = 1024
Maximum size in bytes of buffer for pipelined HTTP requests, defaults to the value of the
PYJO_MAX_LEFTOVER_SIZEenvironment variable or262144(256KiB).
- parse(chunk: bytes | None = None) Pyjo_Content[source]¶
content = content.parse(b'Content-Length: 12\x0d\x0a\x0d\x0aHello World!')
Parse content chunk.
- parse_body(chunk: bytes | None = None) Pyjo_Content[source]¶
content = content.parse_body(b'Hi!')
Parse body chunk and skip headers.
- property progress: int[source]¶
size = content.progress
Size of content already received from message in bytes.
- relaxed¶
boolean = content.relaxed content.relaxed = boolean
Activate relaxed parsing for responses that are terminated with a connection close.
- skip_body¶
boolean = content.skip_body content.skip_body = boolean
Skip body parsing and finish after headers.
- write(chunk: bytes | None = None, cb: DrainCallback | None = None) Self[source]¶
content = content.write() content = content.write(b'') content = content.write(chunk) content = content.write(chunk, lambda content, offset: ...)
Write dynamic content non-blocking, the optional drain callback will be executed once all data has been written. Calling this method without a chunk of data will finalize the
headersand allow for dynamic content to be written later. You can write an empty chunk of data at any time to end the stream.# Make sure previous chunk of data has been written before continuing content.write( b'He', lambda content, offset: content.write(b'llo!', lambda content, offset: content.write(b'')), )
- write_chunk(chunk: bytes | None = None, cb: DrainCallback | None = None) Self[source]¶
content = content.write_chunk() content = content.write_chunk(b'') content = content.write_chunk(chunk) content = content.write_chunk(chunk, lambda content, offset: ...)
Write dynamic content non-blocking with chunked transfer encoding, the optional drain callback will be executed once all data has been written. Calling this method without a chunk of data will finalize the
headersand allow for dynamic content to be written later. You can write an empty chunk of data at any time to end the stream.# Make sure previous chunk of data has been written before continuing content.write_chunk( b'He', lambda content, offset: content.write_chunk(b'llo!', lambda content, offset: content.write_chunk(b'')), )
- write_sse(event: Mapping[str, Any] | None = None, cb: DrainCallback | None = None) Self[source]¶
content = content.write_sse() content = content.write_sse(event) content = content.write_sse(event, lambda content, offset: ...)
Write Server-Sent Event (SSE) non-blocking, the optional drain callback will be executed once all data has been written. Calling this method without an event will finalize the response headers and allow for events to be written later. Note that this method is EXPERIMENTAL and may change without warning!