Pyjo.UserAgent.Transactor - User agent transactor

from Pyjo.UserAgent.Transactor import Transactor

# GET request with Accept header
t = Transactor()
print(t.tx('GET', 'http://example.com', {'Accept': '*/*'}).req.to_bytes())

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

import Pyjo.UserAgent.Transactor

# GET request with Accept header
t = Pyjo.UserAgent.Transactor.new()
print(t.tx('GET', 'http://example.com', {'Accept': '*/*'}).req.to_bytes())

# POST request with form-data
print(t.tx('POST', 'example.com', form={'a': 'b'}).req.to_bytes())

# PUT request with JSON data
print(t.tx('PUT', 'example.com', json={'a': 'b'}).req.to_bytes())

Pyjo.UserAgent.Transactor is the transaction building and manipulation framework used by Pyjo.UserAgent.

Generators

These content generators are available by default.

form

t.tx('POST', 'http://example.com', form={'a': 'b'})

Generate query string, application/x-www-form-urlencoded or multipart/form-data content. See tx() for more.

json

t.tx('PATCH', 'http://example.com', json={'a': 'b'})

Generate JSON content with Pyjo.JSON. See tx() for more.

multipart

t.tx('PUT', 'http://example.com', multipart=['Hello', 'World!'])

Generate multipart content. See tx() for more.

See also

Pyjoyment, https://mojolicious.org.

Ported from Mojo::UserAgent::Transactor of Mojolicious 9.49.

Classes

class Pyjo.UserAgent.Transactor.Pyjo_UserAgent_Transactor(*, compressed: bool | None = None, generators: dict[str, Generator] | None = None, name: str = 'Pyjoyment (Python)')[source]

Pyjo.UserAgent.Transactor inherits all methods from Pyjo.Base and implements the following new ones.

add_generator(name: str, cb: Generator) → Self[source]
t = t.add_generator('foo', lambda t, tx, *args, **options: ...)

Register a content generator.

def foo(t, tx, data, **options): ...

t.add_generator('foo', foo)
property compressed: bool[source]
boolean = t.compressed
t.compressed = boolean

Try to negotiate compression for the response content and decompress it automatically, defaults to the value of the PYJO_GZIP environment variable or true.

download(head: Pyjo_Transaction_HTTP, path: str | PathLike[str]) → Pyjo_Transaction_HTTP[source]
tx = t.download(Pyjo.Transaction.HTTP.new(), '/home/sri/test.tar.gz')

Build Pyjo.Transaction.HTTP resumable file download request as follow-up to a HEAD request. Note that this method is EXPERIMENTAL and might change without warning!

endpoint(tx: Pyjo_Transaction) → tuple[str, str | None, int][source]
proto, host, port = t.endpoint(Pyjo.Transaction.HTTP.new())

Actual endpoint for transaction.

generators: dict[str, Generator]
generators = t.generators
t.generators = {'foo': lambda t, tx, *args, **options: ...}

Registered content generators, by default only form, json and multipart are already defined.

name
name = t.name
t.name = 'Pyjoyment'

Value for User-Agent request header of generated transactions, defaults to Pyjoyment (Python).

peer(tx: Pyjo_Transaction) → tuple[str, str | None, int][source]
proto, host, port = t.peer(Pyjo.Transaction.HTTP.new())

Actual peer for transaction.

promisify(promise: Pyjo_Promise, tx: Pyjo_Transaction) → Pyjo_Promise[source]
t.promisify(Pyjo.Promise.new(), Pyjo.Transaction.HTTP.new())

Resolve or reject Pyjo.Promise object with Pyjo.Transaction.HTTP object.

proxy_connect(old: Pyjo_Transaction) → Pyjo_Transaction_HTTP | None[source]
tx = t.proxy_connect(Pyjo.Transaction.HTTP.new())

Build Pyjo.Transaction.HTTP proxy CONNECT request for transaction if possible.

redirect(old: Pyjo_Transaction_HTTP) → Pyjo_Transaction_HTTP | None[source]
tx = t.redirect(Pyjo.Transaction.HTTP.new())

Build Pyjo.Transaction.HTTP follow-up request for 301, 302, 303, 307 or 308 redirect response if possible. Since QUERY requests are safe and idempotent, they are never redirected as GET requests and keep their content, except for 303 responses.

tx(method: str, url: str | Pyjo_URL | SplitResult, *args: Mapping[str, Any] | bytes | str, **generator: Any) → Pyjo_Transaction_HTTP[source]
tx = t.tx('GET', 'example.com')
tx = t.tx('POST', 'http://example.com')
tx = t.tx('GET', 'http://example.com', {'Accept': '*/*'})
tx = t.tx('PUT', 'http://example.com', b'Content!')
tx = t.tx('PUT', 'http://example.com', form={'a': 'b'})
tx = t.tx('PUT', 'http://example.com', json={'a': 'b'})
tx = t.tx('PUT', 'https://example.com', multipart=['a', 'b'])
tx = t.tx('POST', 'example.com', {'Accept': '*/*'}, b'Content!')
tx = t.tx('PUT', 'example.com', {'Accept': '*/*'}, form={'a': 'b'})
tx = t.tx('PUT', 'example.com', {'Accept': '*/*'}, json={'a': 'b'})
tx = t.tx('PUT', 'example.com', {'Accept': '*/*'}, multipart=['a', 'b'])

Versatile general purpose Pyjo.Transaction.HTTP transaction builder for requests, with support for generators. The URL is also a urllib.parse.SplitResult of the standard library, and the content a str, which is encoded as UTF-8.

# Generate and inspect custom GET request with DNT header and content
print(t.tx('GET', 'example.com', {'DNT': 1}, b'Bye!').req.to_bytes())

# Stream response content to STDOUT
tx = t.tx('GET', 'http://example.com')
tx.res.content.unsubscribe('read').on('read', lambda content, chunk: print(chunk))

# PUT request with content streamed from file
tx = t.tx('PUT', 'http://example.com')
tx.req.content.asset = Pyjo.Asset.File.new(path='/foo.txt')

The json content generator uses Pyjo.JSON for encoding and sets the content type to application/json.

# POST request with "application/json" content
tx = t.tx('POST', 'http://example.com', json={'a': 'b', 'c': [1, 2, 3]})

The form content generator will automatically use query parameters for GET and HEAD requests.

# GET request with query parameters
tx = t.tx('GET', 'http://example.com', form={'a': 'b'})

For all other request methods the application/x-www-form-urlencoded content type is used.

# POST request with "application/x-www-form-urlencoded" content
tx = t.tx('POST', 'http://example.com', form={'a': 'b', 'c': 'd'})

Parameters may be encoded with the charset option.

# PUT request with Shift_JIS encoded form values
tx = t.tx('PUT', 'example.com', form={'a': 'b'}, charset='Shift_JIS')

A list can be used for multiple form values sharing the same name.

# POST request with form values sharing the same name
tx = t.tx('POST', 'http://example.com', form={'a': ['b', 'c', 'd']})

A dict with a content or file value can be used to switch to the multipart/form-data content type for file uploads.

# POST request with "multipart/form-data" content
tx = t.tx('POST', 'http://example.com', form={'mytext': {'content': 'lala'}})

# POST request with multiple files sharing the same name
tx = t.tx('POST', 'http://example.com', form={'mytext': [{'content': 'first'}, {'content': 'second'}]})

The file value should contain the path to the file you want to upload or an asset object, like Pyjo.Asset.File or Pyjo.Asset.Memory.

# POST request with upload streamed from file
tx = t.tx('POST', 'http://example.com', form={'mytext': {'file': '/foo.txt'}})

# POST request with upload streamed from asset
asset = Pyjo.Asset.Memory.new().add_chunk(b'lalala')
tx = t.tx('POST', 'http://example.com', form={'mytext': {'file': asset}})

A filename value will be generated automatically, but can also be set manually if necessary. All remaining values in the dict get merged into the multipart/form-data content as headers.

# POST request with form values and customized upload (filename and header)
tx = t.tx(
    'POST',
    'http://example.com',
    form={
        'a': 'b',
        'c': 'd',
        'mytext': {'content': 'lalala', 'filename': 'foo.txt', 'Content-Type': 'text/plain'},
    },
)

The multipart/form-data content type can also be enforced by setting the Content-Type header manually.

# Force "multipart/form-data"
headers = {'Content-Type': 'multipart/form-data'}
tx = t.tx('POST', 'example.com', headers, form={'a': 'b'})

The multipart content generator can be used to build custom multipart requests and does not set a content type.

# POST request with multipart content ("foo" and "bar")
tx = t.tx('POST', 'http://example.com', multipart=['foo', 'bar'])

Similar to the form content generator you can also pass dicts with content or file values, as well as headers.

# POST request with multipart content streamed from file
tx = t.tx('POST', 'http://example.com', multipart=[{'file': '/foo.txt'}])

# PUT request with multipart content streamed from asset
headers = {'Content-Type': 'multipart/custom'}
asset = Pyjo.Asset.Memory.new().add_chunk(b'lalala')
tx = t.tx('PUT', 'http://example.com', headers, multipart=[{'file': asset}])

# POST request with multipart content and custom headers
tx = t.tx(
    'POST',
    'http://example.com',
    multipart=[
        {'content': 'Hello', 'Content-Type': 'text/plain', 'Content-Language': 'en-US'},
        {'content': 'World!', 'Content-Type': 'text/plain', 'Content-Language': 'en-US'},
    ],
)

Values of the form and of the multipart content that are bytes are sent as they are, and a str is encoded with the charset, as UTF-8 without one.

upgrade(tx: Pyjo_Transaction_HTTP) → Pyjo_Transaction_WebSocket | None[source]
tx = t.upgrade(Pyjo.Transaction.HTTP.new())

Build Pyjo.Transaction.WebSocket follow-up transaction for WebSocket handshake if possible.

websocket(url: str | Pyjo_URL | SplitResult, *args: Mapping[str, Any] | Sequence[str]) → Pyjo_Transaction_HTTP[source]
tx = t.websocket('ws://example.com')
tx = t.websocket('ws://example.com', {'DNT': 1}, ['v1.proto'])

Versatile Pyjo.Transaction.HTTP transaction builder for WebSocket handshake requests.