API Reference¶
Generated from the source docstrings of every name exported by the top-level
soapbar package — the frozen public surface
covered by the stability policy. Deeper module paths (soapbar.core.*,
soapbar.contrib.*) are importable but only the names below are guaranteed
by SemVer.
soapbar — Python SOAP toolkit.
__version__
module-attribute
¶
__version__: str = _version('soapbar')
The installed soapbar version, from package metadata.
WSA_ANONYMOUS
module-attribute
¶
WSA_ANONYMOUS = (
"http://www.w3.org/2005/08/addressing/anonymous"
)
WS-Addressing anonymous address: reply on the transport back-channel.
WSA_NONE
module-attribute
¶
WSA_NONE = 'http://www.w3.org/2005/08/addressing/none'
WS-Addressing none address: the message must not be routed anywhere.
NS
module-attribute
¶
NS = _Namespaces()
Singleton with every SOAP/WSDL/WS-* namespace URI constant (see _Namespaces).
xsd
module-attribute
¶
xsd = _TypeRegistry()
Global registry of the built-in XSD simple types, e.g. xsd.resolve("int").
SoapClient ¶
SoapClient(
wsdl_url: str | None = None,
*,
transport: HttpTransport | None = None,
use_wsa: bool = False,
wss_credential: Any = None,
use_mtom: bool = False,
)
WSDL-driven SOAP client.
Three ways to construct one: SoapClient(wsdl_url) fetches and
parses the WSDL (binding style, SOAP version, operations and endpoint
are configured automatically); from_wsdl_string does the same
from an in-memory document; manual skips WSDL entirely for
endpoints where you register operations by hand.
Invoke operations with call / call_async, or through
the service attribute proxy (client.service.Add(a=1, b=2)).
Optional behaviours: WS-Addressing headers (use_wsa), a WS-Security
UsernameToken on every call (wss_credential), and MTOM attachments
(use_mtom + add_attachment).
from_file
classmethod
¶
from_file(
path: str | Path,
*,
use_wsa: bool = False,
transport: HttpTransport | None = None,
endpoint: str | None = None,
) -> SoapClient
Build a client from a WSDL file on disk.
Args:
path: Path to the WSDL document.
use_wsa: Enable WS-Addressing request headers.
transport: Custom HttpTransport (e.g. for timeouts, mTLS,
or a stubbed transport in tests). Defaults to a plain one.
endpoint: Override the service address parsed from the WSDL — handy
when the WSDL lists a legacy/HTTP URL but you want HTTPS.
register_operation ¶
register_operation(sig: OperationSignature) -> None
Register an operation signature by hand (for manual clients
or to override a signature parsed from the WSDL).
close ¶
close() -> None
Close the underlying transport's pooled HTTP client, if any.
Safe to call multiple times. Since 0.6.1 HttpTransport
maintains a long-lived httpx.Client for connection reuse;
calling close() releases that client and the connections it
owns. Not required for correctness (the transport tolerates
garbage-collection), but recommended in long-running processes
that create many short-lived SoapClient instances.
add_attachment ¶
add_attachment(
data: bytes,
content_type: str,
content_id: str | None = None,
) -> str
Queue a binary attachment to be sent with the next MTOM call.
Returns the Content-ID (without angle brackets) that can be used in
an <xop:Include href="cid:…"/> element inside the SOAP body.
Only meaningful when use_mtom=True.
call ¶
call(operation: str, **kwargs: Any) -> Any
Invoke operation with keyword arguments and return the parsed result.
The return shape depends on how many output parameters the operation declares — this arity-based contract is stable:
- No output (or an empty body) →
None. - Exactly one output parameter → that value, unwrapped (e.g. an
int,str,Decimal, or a parsed complex/AnyXmlTypevalue) — not wrapped in a dict. - Two or more output parameters → a
dictkeyed by parameter name.
A SOAP fault in the response is raised as SoapFault.
(The single-output unwrapping is a deliberate ergonomic choice; callers
that want a uniform mapping can read the operation's output parameter
names from its OperationSignature.)
call_async
async
¶
call_async(operation: str, **kwargs: Any) -> Any
Async counterpart of call; same arity-based return contract.
Requires httpx. WS-Security and WS-Addressing headers are applied
exactly as in call.
HttpTransport ¶
HttpTransport(
*,
timeout: float = 30.0,
verify_ssl: bool = True,
client_cert: ClientCert = None,
ca_bundle: str | None = None,
persist_cookies: bool = True,
)
HTTP transport used by SoapClient.
Prefers httpx (sync and async, pooled connections) and falls back to
stdlib urllib when httpx is not installed — the fallback supports
neither client certificates nor a custom CA bundle nor async.
Construction knobs: timeout; verify_ssl (default True — the
opt-out exists for test endpoints only); client_cert for mutual TLS
(see load_pkcs12 for .pfx bundles); ca_bundle to pin a
private/government PKI root (takes precedence over verify_ssl); and
persist_cookies to keep session cookies across calls (stateful
services). Use as a context manager or call close()/aclose()
to release pooled connections.
cookies
property
¶
cookies: Any
The live httpx.Cookies jar this transport carries across calls.
Read a session cookie after a call (transport.cookies.get("JSESSIONID"))
or inject one before (transport.cookies.set("sid", "...", domain=...)).
Backed by the pooled sync client, so it persists for the session.
Requires httpx.
close ¶
close() -> None
Close the long-lived sync httpx.Client, if any. Safe to call multiple times; no-op when httpx is not installed or the client has never been created.
send ¶
send(
url: str, body: bytes, headers: dict[str, str]
) -> tuple[int, str, bytes]
Send SOAP request. Returns (status, content_type, body).
send_async
async
¶
send_async(
url: str, body: bytes, headers: dict[str, str]
) -> tuple[int, str, bytes]
Send async SOAP request. Requires httpx.
BindingStyle ¶
Bases: Enum
is_wsi_conformant
property
¶
is_wsi_conformant: bool
Return False for styles that violate WS-I Basic Profile 1.1 R2706.
RPC_ENCODED and DOCUMENT_ENCODED use SOAP Section 5 encoding,
which WS-I BP 1.1 R2706 prohibits. Use them only for WITSML or other
legacy protocols that explicitly require Section 5 encoding.
OperationParameter
dataclass
¶
OperationParameter(
name: str,
xsd_type: XsdType,
required: bool = True,
namespace: str | None = None,
)
An operation's input/output parameter descriptor (an immutable value object).
OperationSignature
dataclass
¶
OperationSignature(
name: str,
input_params: list[OperationParameter] = list(),
output_params: list[OperationParameter] = list(),
soap_action: str = "",
input_namespace: str | None = None,
output_namespace: str | None = None,
one_way: bool = False,
emit_rpc_result: bool = False,
)
Full description of one SOAP operation: name, input/output parameters,
soapAction, and per-operation flags (one-way, rpc:result).
SoapEnvelope
dataclass
¶
SoapEnvelope(
version: SoapVersion = SOAP_11,
header_blocks: list[SoapHeaderBlock] | None = None,
body_elements: list[_Element] | None = None,
ws_addressing: WsaHeaders | None = None,
ws_security_element: _Element | None = None,
header_elements: list[_Element] | None = None,
)
add_header ¶
add_header(elem: _Element | SoapHeaderBlock) -> None
Append a header block; a bare element is wrapped in a plain
SoapHeaderBlock (no mustUnderstand/role attributes).
add_body_content ¶
add_body_content(elem: _Element) -> None
Append elem as a child of the SOAP Body.
build ¶
build() -> _Element
Build and return the Envelope element tree.
The Header element is emitted only when header blocks are
present; the Body is always present.
to_string ¶
to_string(pretty_print: bool = False) -> str
Build the envelope and serialize it to str (no XML declaration).
to_bytes ¶
to_bytes(pretty_print: bool = False) -> bytes
Build the envelope and serialize it to UTF-8 bytes, the wire form.
SoapHeaderBlock
dataclass
¶
SoapHeaderBlock(
element: _Element,
must_understand: bool = False,
relay: bool = False,
role: str | None = None,
)
A single SOAP header block with parsed attributes (an immutable value object).
relay is parsed from the SOAP 1.2 env:relay attribute ([SOAP12-P1] §5.2.4)
and exposed for inspection by intermediary implementations. soapbar acts as an
ultimate receiver and does not forward envelopes, so relay is intentionally
not enforced here — forwarding behaviour is the responsibility of a SOAP intermediary
layer that wraps this library.
SoapVersion ¶
Bases: Enum
SOAP protocol version (1.1 or 1.2), with per-version namespace, content type, and prefix properties.
WsaEndpointReference
dataclass
¶
WsaEndpointReference(
address: str,
reference_parameters: tuple[_Element, ...] = (),
)
WS-Addressing endpoint reference (an immutable value object).
reference_parameters is a tuple (not a list) so the reference is
hashable and immutable.
WsaHeaders
dataclass
¶
WsaHeaders(
message_id: str | None = None,
to: str | None = None,
action: str | None = None,
from_: WsaEndpointReference | None = None,
reply_to: WsaEndpointReference | None = None,
fault_to: WsaEndpointReference | None = None,
relates_to: str | None = None,
relates_to_relationship: str = "http://www.w3.org/2005/08/addressing/reply",
)
Parsed WS-Addressing headers from a SOAP envelope.
Intentionally mutable (not frozen): the header parser fills these fields in
incrementally as it walks the SOAP header blocks (see parse_wsa_headers).
SoapbarError ¶
Bases: Exception
Base class for every error soapbar raises deliberately.
Catch this to handle any soapbar-originated failure uniformly. Note it does
not encompass errors raised by the standard library or third-party
dependencies (e.g. an lxml parse error on malformed XML, or an httpx
connection error) — only failures soapbar itself signals.
SoapFault ¶
SoapFault(
faultcode: str,
faultstring: str,
*,
faultactor: str | None = None,
detail: str | _Element | None = None,
subcodes: list[tuple[str, str]] | None = None,
)
Bases: SoapbarError
to_soap11_envelope ¶
to_soap11_envelope(
header_blocks: list[_Element] | None = None,
) -> _Element
Render this fault as a complete SOAP 1.1 Envelope element,
optionally carrying header_blocks in the Header.
to_soap12_element ¶
to_soap12_element() -> _Element
Render this fault as a SOAP 1.2 Fault element.
SOAP 1.1 fault codes are translated to their 1.2 equivalents
(e.g. Client → Sender) and subcodes are emitted as
namespace-qualified QNames.
to_soap12_envelope ¶
to_soap12_envelope(
header_blocks: list[_Element] | None = None,
) -> _Element
Render this fault as a complete SOAP 1.2 Envelope element,
optionally carrying header_blocks in the Header.
MtomAttachment
dataclass
¶
MtomAttachment(
content_id: str, content_type: str, data: bytes
)
A single MIME part / XOP attachment (an immutable value object).
MtomMessage
dataclass
¶
MtomMessage(
soap_xml: bytes,
attachments: tuple[MtomAttachment, ...] = (),
)
Parsed MTOM multipart message (an immutable value object).
attachments is a tuple (not a list) so the message is hashable and
cannot be mutated in place after parsing.
AnyXmlType ¶
Bases: XsdType
Passthrough for an xsd:any wildcard body.
The value is a string (or bytes) of XML serialized verbatim as child
element(s) of the carrier, and read back as the inner-XML string. This is
what document/literal bare bodies need — e.g. SEFAZ NF-e's
<nfeDadosMsg> carries a raw <consStatServ> / <enviNFe> message.
The actual element insertion/extraction is handled by the binding
serializer; to_xml/from_xml are identity for string content.
ArrayXsdType ¶
ArrayXsdType(
name: str,
element_type: XsdType,
element_tag: str = "item",
inline: bool = False,
target_namespace: str = "",
qualified: bool = False,
)
Bases: XsdType
XSD array type: a wrapper element containing repeated child elements.
to_element ¶
to_element(
tag: str,
value: Any,
ns: str = "",
soap_encoding: str | None = None,
) -> Any
Serialize the list value as a wrapper element named tag.
When soap_encoding names a SOAP encoding namespace, the wrapper
carries the mandated array attributes (SOAP-ENC:arrayType for
1.1, enc:itemType/enc:arraySize for 1.2).
from_element ¶
from_element(elem: Any) -> list[Any]
Deserialize the wrapper elem's children into a list of items.
ChoiceXsdType ¶
ChoiceXsdType(
name: str,
options: list[tuple[str, XsdType]],
target_namespace: str = "",
qualified: bool = False,
)
Bases: XsdType
XSD choice type: exactly one of the named options is present.
to_element ¶
to_element(
tag: str,
value: Any,
ns: str = "",
soap_encoding: str | None = None,
) -> Any
Serialize value — a dict with exactly one option key set — as an element named tag containing that single option child.
from_element ¶
from_element(elem: Any) -> dict[str, Any]
Deserialize elem into {option_name: value} for the option
present; an empty dict if no known option matches.
ComplexXsdType ¶
ComplexXsdType(
name: str,
fields: list[tuple[str, XsdType | str]],
target_namespace: str = "",
qualified: bool = False,
registry: _TypeRegistry | None = None,
)
Bases: XsdType
XSD complexType with a sequence of named sub-elements.
Fields may be XsdType instances or string names to be lazily resolved via xsd.resolve() (for forward/recursive references).
qualified mirrors the owning schema's elementFormDefault: when True,
the type's local child elements are emitted in target_namespace (what
a conformant peer — zeep/.NET/Java — expects). Reading is always namespace
tolerant (children are matched by local name), so soapbar accepts both
qualified and unqualified input regardless of this flag.
from_xml ¶
from_xml(s: str) -> Any
Unsupported: complex values have no text form — use from_element.
to_element ¶
to_element(
tag: str,
value: dict[str, Any],
ns: str = "",
soap_encoding: str | None = None,
) -> Any
Serialize the field dict value as an element named tag.
Child elements follow the field order; None fields of non-string
types are omitted. ns qualifies the outer element; child
qualification follows the type's qualified flag.
from_element ¶
from_element(elem: Any) -> dict[str, Any]
Deserialize elem's children into a field dict.
Children are matched by local name (namespace tolerant); missing or
xsi:nil fields come back as None, repeated (maxOccurs>1)
fields as lists.
XsdType ¶
Bases: ABC
WsdlBinding
dataclass
¶
WsdlBinding(
name: str,
port_type: str,
soap_ns: str = "",
style: str = "document",
transport: str = "",
operations: list[WsdlBindingOperation] = list(),
)
binding_style_for ¶
binding_style_for(operation_name: str) -> BindingStyle
Determine BindingStyle for a specific operation.
WsdlBindingOperation
dataclass
¶
WsdlBindingOperation(
name: str,
soap_action: str = "",
style: str | None = None,
use: str | None = None,
output_use: str | None = None,
input_namespace: str | None = None,
output_namespace: str | None = None,
)
Per-operation SOAP binding details: soapAction, style and use
overrides, and input/output body namespaces.
WsdlDefinition
dataclass
¶
WsdlDefinition(
name: str = "",
target_namespace: str = "",
messages: dict[str, WsdlMessage] = dict(),
port_types: dict[str, WsdlPortType] = dict(),
bindings: dict[str, WsdlBinding] = dict(),
services: dict[str, WsdlService] = dict(),
schema_elements: list[Any] = list(),
complex_types: dict[str, XsdType] = dict(),
type_registry: Any = None,
global_elements: list[Any] = list(),
)
In-memory model of a complete WSDL 1.1 document.
Produced by parse_wsdl / parse_wsdl_file and consumed by
build_wsdl; messages, port types, bindings, and services are keyed
by local name, with parsed schema types in complex_types.
WsdlMessage
dataclass
¶
WsdlMessage(name: str, parts: list[WsdlPart] = list())
A wsdl:message: a named list of WsdlPart entries.
WsdlOperation
dataclass
¶
WsdlOperation(
name: str,
documentation: str = "",
input: WsdlOperationMessage | None = None,
output: WsdlOperationMessage | None = None,
faults: list[WsdlOperationMessage] = list(),
)
A wsdl:operation in a port type: name, documentation, and its
input/output/fault message references.
WsdlOperationMessage
dataclass
¶
WsdlOperationMessage(message: str, name: str | None = None)
An operation's input/output/fault slot referencing a message by QName.
WsdlPart
dataclass
¶
WsdlPart(
name: str,
element: str | None = None,
type: str | None = None,
element_ns: str | None = None,
)
A wsdl:part of a message: a named reference to an element or type.
WsdlPort
dataclass
¶
WsdlPort(name: str, binding: str, address: str = '')
A wsdl:port: a binding bound to a concrete endpoint address.
WsdlPortType
dataclass
¶
WsdlPortType(
name: str, operations: list[WsdlOperation] = list()
)
A wsdl:portType: the abstract interface, a named set of operations.
WsdlService
dataclass
¶
WsdlService(name: str, ports: list[WsdlPort] = list())
A wsdl:service: a named collection of WsdlPort entries.
SecurityValidationError ¶
Bases: SoapbarError
Raised by UsernameTokenValidator when authentication fails.
UsernameTokenCredential
dataclass
¶
UsernameTokenCredential(
username: str,
password: str,
use_digest: bool = False,
nonce: bytes | None = None,
created: str | None = None,
)
Holds the username and password for a WS-Security UsernameToken.
Args: username: The username to embed. password: The plain-text password. use_digest: If True, the password is hashed via PasswordDigest (SHA-1 based, per WSS 1.0 §3.2.1). If False (default), PasswordText is used. nonce: Override the random nonce bytes (mainly for testing). created: Override the creation timestamp string (mainly for testing).
UsernameTokenValidator ¶
UsernameTokenValidator()
Bases: ABC
Abstract base class for server-side UsernameToken validation.
Subclass and implement get_password to look up the expected
password for a given username. The base class handles digest verification,
wsu:Timestamp expiry checking (N05), and nonce replay prevention (N07).
Subclasses that define their own __init__ MUST call super().__init__()
to initialise the nonce replay cache.
get_password
abstractmethod
¶
get_password(username: str) -> str | None
Return the plain-text password for username, or None if unknown.
validate ¶
validate(security_element: _Element) -> str
Validate a wsse:Security element and return the authenticated username.
Performs, in order:
1. wsu:Timestamp expiry check when present (N05).
2. wsse:UsernameToken credential verification.
3. Nonce replay check for PasswordDigest tokens (N07).
Raises: SecurityValidationError: if any check fails.
XmlSecurityError ¶
Bases: SoapbarError
Raised when XML Signature verification or XML Encryption fails.
BodyTooLargeError ¶
Bases: SoapbarError, ValueError
Raised when a request body (or a decoded/expanded form of it) exceeds the configured size limit.
Subclasses both SoapbarError (so
except SoapbarError catches it like any other soapbar error) and
ValueError (so existing except (ValueError, TypeError) handlers
still treat it as a client error). The distinct type lets the ingress
adapters recognise a size-limit breach specifically (as opposed to a
malformed-input ValueError) and translate it into the standard
oversized-request fault rather than a generic 500.
SoapApplication ¶
SoapApplication(
custom_wsdl: bytes | None = None,
service_url: str = "http://localhost:8000/soap",
*,
max_body_size: int = 10 * 1024 * 1024,
security_validator: Any = None,
validate_body_schema: bool = False,
allow_plaintext_credentials: bool = False,
wsdl_access: Literal[
"public", "authenticated", "disabled"
] = "public",
wsdl_auth_hook: Callable[[dict[str, str]], bool]
| None = None,
enable_gzip: bool = False,
)
Framework-agnostic SOAP dispatcher: routes envelopes to services.
Register SoapService instances with
register, then expose the application over HTTP through
AsgiSoapApp or
WsgiSoapApp (or call
handle_request from a custom adapter). Serves the
auto-generated (or custom_wsdl) WSDL on ?wsdl requests, subject
to wsdl_access.
Hardening knobs: max_body_size (default 10 MB), request nesting-depth limits, optional WS-Security validation (security_validator), opt-in body schema validation (validate_body_schema), and opt-in HTTP gzip (enable_gzip). Construction warns when service_url is plain HTTP.
max_body_size
property
¶
max_body_size: int
The configured maximum request-body size in bytes (G01).
Exposed so the WSGI/ASGI adapters can enforce the same limit before
they decompress or MTOM-decode a body — stages that run ahead of
handle_request and can amplify a small body into a huge one.
register ¶
register(service: SoapService) -> None
Register service, adding its operations to the dispatch table.
SOAPAction values are indexed both quoted and unquoted so requests from either convention dispatch correctly.
get_wsdl ¶
get_wsdl() -> bytes
Return the WSDL document as bytes — the custom_wsdl passed at construction, or one generated from the registered services.
check_wsdl_access ¶
check_wsdl_access(headers: dict[str, str]) -> bool
Return True if the WSDL may be served for the given request headers.
Controlled by the wsdl_access constructor parameter:
"public"(default) — always allowed."disabled"— always denied (returns 403)."authenticated"— delegates to wsdl_auth_hook; denied if no hook is configured.
handle_request ¶
handle_request(
body: bytes,
soap_action: str = "",
content_type: str = "text/xml",
accept_header: str = "",
_force_oversize: bool = False,
) -> tuple[int, str, bytes]
Returns (http_status, content_type, response_body).
_force_oversize lets an adapter report an oversized request through the normal fault path when the breach was detected upstream (a raw body over the limit, a gzip bomb, or MTOM/XOP amplification) without having to materialise the offending bytes here.
AsgiSoapApp ¶
AsgiSoapApp(soap_app: SoapApplication)
ASGI 3 application wrapping a SoapApplication.
Run it directly under any ASGI server (uvicorn app:app) or mount it
inside an ASGI framework (FastAPI, Starlette). GET ?wsdl serves the
WSDL; POST dispatches SOAP envelopes, decoding inbound MTOM
automatically. Lifespan events are acknowledged as no-ops.
SoapMethod ¶
Bases: Protocol
The type of a method decorated with soap_operation.
A callable carrying the __soap_operation__ signature attribute. This is
the value type of SoapService.get_operations; it is part of the
public API so callers can annotate against it.
SoapService ¶
Base class for SOAP services.
Subclass it, set the __service_name__ and __tns__ class
attributes, and decorate handler methods with soap_operation;
parameter and return XSD types are introspected from type hints.
Register instances on a SoapApplication
to serve them.
Class attributes: __service_name__ (service element name),
__tns__ (target namespace), __binding_style__,
__soap_version__, __port_name__, and __service_url__.
get_operations ¶
get_operations() -> dict[str, SoapMethod]
Return {operation_name: method} for all @soap_operation methods.
get_operation_signatures ¶
get_operation_signatures() -> dict[str, OperationSignature]
Return {operation_name: OperationSignature} for all operations.
WsgiSoapApp ¶
WsgiSoapApp(soap_app: SoapApplication)
WSGI application wrapping a SoapApplication.
The synchronous counterpart of AsgiSoapApp
for WSGI servers and frameworks (gunicorn, Flask/Werkzeug mounts).
GET ?wsdl serves the WSDL; POST dispatches SOAP envelopes,
decoding inbound MTOM automatically.
load_pkcs12 ¶
load_pkcs12(
path: str, password: str | None = None
) -> tuple[bytes, bytes]
Load a PKCS#12 (.pfx / .p12) bundle into PEM bytes.
Returns (cert_pem, key_pem) where cert_pem is the full certificate
chain (end-entity certificate first, followed by any bundled intermediates)
and key_pem is the unencrypted PKCS#8 private key. Both are held in
memory only — the key is never written to disk or logged. Feed the result
straight to HttpTransport::
cert_pem, key_pem = load_pkcs12("cert.pfx", "password")
transport = HttpTransport(client_cert=(cert_pem, key_pem), ca_bundle="ca.pem")
Typical use is an ICP-Brasil A1 certificate for SEFAZ NF-e. A3 (hardware
token) certificates are out of scope. Requires the cryptography package
(install soapbar[security]).
get_serializer ¶
get_serializer(
style: BindingStyle, soap_version: Any = None
) -> BindingSerializer
Return a serializer for style.
For encoded styles (G05), pass soap_version (a SoapVersion enum value)
so the serializer can emit the correct array attributes for SOAP 1.1 vs 1.2.
build_fault ¶
build_fault(
version: SoapVersion,
faultcode: str,
faultstring: str,
*,
faultactor: str | None = None,
detail: str | _Element | None = None,
) -> _Element
Build a complete fault Envelope element for version.
faultcode uses SOAP 1.1 vocabulary (Client, Server, …) and is
translated to the SOAP 1.2 equivalent automatically when needed.
build_request ¶
build_request(
version: SoapVersion,
body_elements: list[_Element],
header_elements: list[_Element] | None = None,
) -> _Element
Build a request Envelope element with the given body and headers.
build_response ¶
build_response(
version: SoapVersion,
body_elements: list[_Element],
header_elements: list[_Element] | None = None,
) -> _Element
Build a response Envelope element; structurally identical to
build_request (SOAP responses differ only in body content).
build_wsa_response_headers ¶
build_wsa_response_headers(
request_wsa: WsaHeaders, action: str | None = None
) -> list[_Element]
Build WS-Addressing 1.0 response header elements.
Per WS-Addressing 1.0 Core [W3C Rec 2006] §3.4:
wsa:MessageID— a new UUID URN identifying this response messagewsa:RelatesTo— thewsa:MessageIDof the request (if present), withRelationshipTypeimplicitlywsa:Replywsa:Action— the response action URI (if action is provided)
The caller is responsible for deriving the action string. A common
convention is to append "Response" to the request action URI.
http_headers ¶
http_headers(
version: SoapVersion, soap_action: str = ""
) -> dict[str, str]
Return the HTTP headers for a SOAP request in version.
SOAP 1.1 carries the action in a quoted SOAPAction header; SOAP 1.2
carries it as the action parameter of the Content-Type.
build_mtom ¶
build_mtom(
soap_xml: bytes,
attachments: list[MtomAttachment],
soap_version_content_type: str = "application/soap+xml",
soap_action: str = "",
) -> tuple[bytes, str]
Package a SOAP envelope and binary attachments as an MTOM multipart message.
For each attachment a <xop:Include> element is NOT automatically inserted —
callers are expected to have already placed <xop:Include href="cid:…"/> elements
inside the SOAP body where they want binary data substituted. This function simply
assembles the MIME package.
Args:
soap_xml: The SOAP XML bytes (may already contain xop:Include references).
attachments: List of binary attachments to include as MIME parts.
soap_version_content_type: text/xml (SOAP 1.1) or
application/soap+xml (SOAP 1.2).
soap_action: Optional SOAPAction / action URI for the start-info parameter.
Returns:
A (body_bytes, content_type_header) tuple ready for use as an HTTP body.
extract_xop_elements ¶
extract_xop_elements(
xml_bytes: bytes,
) -> list[tuple[str, Any]]
Return a list of (parent_tag, xop_include_element) tuples found in
xml_bytes. Useful for inspecting which elements contain XOP references
before resolving them.
parse_mtom ¶
parse_mtom(
raw: bytes,
content_type: str,
max_resolved_size: int | None = None,
) -> MtomMessage
Parse a multipart/related MTOM message.
The first MIME part is expected to be the SOAP envelope (application/xop+xml).
Subsequent parts are binary attachments. All <xop:Include> elements in the
envelope are resolved inline so that the returned soap_xml is a plain XML
document that the rest of the stack can handle without special cases.
Args:
raw: The raw HTTP response/request body (all MIME parts concatenated).
content_type: The value of the Content-Type header for the whole body.
max_resolved_size: If given, cap the size of the XOP-resolved envelope.
A message with many <xop:Include> references to a large
attachment can inflate to far more than the raw body (XOP
amplification); exceeding this bound raises
BodyTooLargeError instead of expanding it
in memory.
Returns:
An MtomMessage with resolved XML and the tuple of attachments.
Raises: ValueError: If the message cannot be parsed as a valid MTOM envelope. BodyTooLargeError: If the resolved envelope exceeds max_resolved_size.
build_wsdl ¶
build_wsdl(defn: WsdlDefinition, address: str) -> _Element
Build a WSDL 1.1 document element from defn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
defn
|
WsdlDefinition
|
The definition to serialize (as built from service classes or parsed from another WSDL). |
required |
address
|
str
|
The service endpoint URL, emitted in |
required |
Returns:
| Type | Description |
|---|---|
_Element
|
The |
build_wsdl_bytes ¶
build_wsdl_bytes(
defn: WsdlDefinition, address: str
) -> bytes
Build the WSDL for defn and serialize it to UTF-8 bytes (see build_wsdl).
build_wsdl_string ¶
build_wsdl_string(
defn: WsdlDefinition, address: str
) -> str
Build the WSDL for defn and serialize it to str (see build_wsdl).
parse_wsdl ¶
parse_wsdl(
source: str | bytes | Path | _Element,
base_url: str | None = None,
_visited: set[str] | None = None,
allow_remote_imports: bool = False,
allow_local_imports: bool = False,
strict: bool = True,
_registry: _TypeRegistry | None = None,
) -> WsdlDefinition
Parse a WSDL document from source.
allow_remote_imports controls whether wsdl:import /
xsd:import elements whose resolved location starts with http:// or
https:// are fetched. It defaults to False to prevent Server-Side
Request Forgery (SSRF) when parsing WSDLs from untrusted sources. Set it to
True only when the WSDL originates from a trusted location and remote
imports are expected.
allow_local_imports controls whether imports that resolve to a local
file (file:// or a filesystem path) are read. It defaults to False
so that a hostile <import location="file:///etc/passwd"> in an in-memory
or remote WSDL cannot exfiltrate local files. parse_wsdl_file
enables it, since a trusted on-disk WSDL legitimately references sibling
documents; pass it explicitly only for equally trusted local content.
strict (default True) controls error handling for import resolution
failures. When False, a failed wsdl:import emits a
UserWarning and is skipped rather than raising an exception. This is
useful for parsing real-world WSDLs from SAP, Oracle, or government
services that reference unavailable or locally absent import targets.
Note: the SSRF guard (blocking remote imports) is always enforced
regardless of this flag.
parse_wsdl_file ¶
parse_wsdl_file(
path: str | Path, strict: bool = True
) -> WsdlDefinition
Parse a WSDL document from a local file.
Unlike parse_wsdl on in-memory or remote content, imports that
resolve to local files are allowed: a WSDL on disk is trusted to
reference its sibling documents. Remote (http(s)://) imports remain
blocked. With strict=False, unresolvable imports are skipped
instead of raising.
build_binary_security_token ¶
build_binary_security_token(
certificate: Any, *, token_id: str = "X509Token-1"
) -> _Element
Build a wsse:BinarySecurityToken from an X.509 certificate.
The certificate is DER-encoded then Base64-encoded per WS-I BSP 1.1
R3029 (ValueType) and R3031 (EncodingType). The wsu:Id
attribute is set so that a wsse:SecurityTokenReference can reference
this element by URI fragment.
Args:
certificate: A cryptography X.509 certificate object.
token_id: Value for the wsu:Id attribute (default "X509Token-1").
Returns:
A wsse:BinarySecurityToken lxml element.
Raises:
ImportError: If cryptography is not installed.
build_security_header ¶
build_security_header(
credential: UsernameTokenCredential,
*,
soap_ns: str | None = None,
timestamp_ttl: int | None = None,
) -> _Element
Build a wsse:Security header element for credential.
Returns a wsse:Security element ready to be added as a SOAP header.
Per WS-Security 1.0 §6.1, the Security header MUST carry
{soap_ns}mustUnderstand="1" so intermediaries know to process it.
Pass soap_ns as the SOAP envelope namespace URI to enable this attribute.
Args:
credential: The UsernameToken credential to embed.
soap_ns: SOAP envelope namespace URI; when set, adds mustUnderstand="1".
timestamp_ttl: If given, prepend a wsu:Timestamp with wsu:Created
and wsu:Expires (set to now + timestamp_ttl seconds).
Enables replay-window enforcement on the receiver side (N05).
decrypt_body ¶
decrypt_body(
envelope_bytes: bytes,
private_key: Any,
*,
allow_unauthenticated_cbc: bool = False,
) -> bytes
Decrypt the SOAP Body content encrypted by encrypt_body.
The body cipher is read from the xenc:EncryptionMethod algorithm.
AES-256-GCM (the default produced by encrypt_body) is
authenticated: a tampered ciphertext fails the tag check and is rejected.
Legacy AES-256-CBC is unauthenticated — it is malleable and, because
a distinguishable unpadding error is a padding oracle, unsafe to decrypt
for an attacker who can observe outcomes. It is therefore refused by
default; pass allow_unauthenticated_cbc=True only to interoperate with
a peer that still emits CBC and only when you accept that risk.
Args:
envelope_bytes: The SOAP envelope with an encrypted Body as bytes.
private_key: The recipient's cryptography RSA private key.
allow_unauthenticated_cbc: Permit decrypting legacy AES-256-CBC.
Returns: The envelope with the decrypted Body content as bytes.
Raises:
ImportError: If cryptography is not installed.
XmlSecurityError: If decryption fails, the ciphertext is tampered, or an
unauthenticated CBC body is refused.
encrypt_body ¶
encrypt_body(
envelope_bytes: bytes, recipient_public_key: Any
) -> bytes
Encrypt the SOAP Body content using XML Encryption (AES-256-GCM + RSA-OAEP).
The Body's child elements are replaced with an xenc:EncryptedData
element. The AES-256 session key is wrapped with RSA-OAEP (SHA-256)
using recipient_public_key.
The body cipher is AES-256-GCM (XML-Enc 1.1), an authenticated mode: the 16-byte GCM tag lets the recipient detect any tampering of the ciphertext. The previous AES-256-CBC output was unauthenticated, which exposed both ciphertext malleability and a padding oracle; GCM closes both.
Args:
envelope_bytes: The SOAP envelope XML as bytes.
recipient_public_key: A cryptography RSA public key object.
Returns: The envelope with an encrypted Body as bytes.
Raises:
ImportError: If cryptography is not installed.
XmlSecurityError: If encryption fails.
extract_certificate_from_security ¶
extract_certificate_from_security(
security_element: _Element,
) -> Any
Extract the X.509 certificate from a wsse:BinarySecurityToken.
Args:
security_element: The wsse:Security element from the SOAP header.
Returns:
A cryptography X.509 certificate object.
Raises:
ImportError: If cryptography is not installed.
XmlSecurityError: If no BST is found or the certificate cannot be decoded.
sign_element_by_id ¶
sign_element_by_id(
doc_bytes: bytes,
id_value: str,
private_key: Any,
certificate: Any,
*,
id_attr: str = "Id",
signature_method: str = "rsa-sha256",
digest_method: str = "sha256",
c14n: str = "exclusive",
end_cert_only: bool = True,
) -> bytes
Sign one internal element of a document, selected by its Id.
Unlike sign_envelope (which covers the whole SOAP envelope), this
produces an enveloped ds:Signature with a single ds:Reference whose
URI is #<id_value> — the standard XML-DSIG pattern for signing an inner
element. The ds:Signature is appended to the document root, so for a
<NFe><infNFe Id="NFe…">…</infNFe></NFe> document the signature becomes a
sibling of <infNFe>.
The defaults (RSA-SHA256 / SHA-256 / Exclusive C14N) suit modern services.
SEFAZ NF-e mandates the legacy set — pass signature_method="rsa-sha1",
digest_method="sha1", c14n="inclusive" (the
REC-xml-c14n-20010315 algorithm) and keep end_cert_only=True (only
the end-entity certificate in KeyInfo/X509Data, no KeyValue).
Args:
doc_bytes: The XML document containing the target element.
id_value: The value of the target element's id attribute (e.g. the
NFe + 44-char access key for NF-e).
private_key: A cryptography private key (or PEM bytes).
certificate: The signing X.509 certificate (object or PEM bytes).
id_attr: Name of the attribute that holds the id. Default "Id".
signature_method: "rsa-sha256" (default) or "rsa-sha1".
digest_method: "sha256" (default) or "sha1".
c14n: "exclusive" (default) or "inclusive" (C14N 1.0,
http://www.w3.org/TR/2001/REC-xml-c14n-20010315).
end_cert_only: When True (default) KeyInfo carries only the
end-entity certificate and no KeyValue.
Returns: The signed document as bytes.
Raises:
ImportError: If signxml is not installed.
ValueError: If an algorithm option is unsupported.
XmlSecurityError: If signing fails.
sign_envelope ¶
sign_envelope(
envelope_bytes: bytes,
private_key: Any,
certificate: Any,
) -> bytes
Sign a SOAP envelope with an XML Digital Signature (XML-DSIG).
The ds:Signature element is inserted into the envelope using the
enveloped-signature transform (W3C XML-DSIG §8.1). RSA-SHA256 with
SHA-256 digest is used by default.
Args:
envelope_bytes: The SOAP envelope XML as bytes.
private_key: A cryptography RSA/EC private key object.
certificate: A cryptography X.509 certificate object
(or a PEM bytes string) whose public key corresponds to
private_key.
Returns: The signed envelope as bytes.
Raises:
ImportError: If signxml is not installed.
XmlSecurityError: If signing fails.
sign_envelope_bsp ¶
sign_envelope_bsp(
envelope_bytes: bytes,
private_key: Any,
certificate: Any,
*,
token_id: str = "X509Token-1",
) -> bytes
Sign a SOAP envelope using the WS-I BSP 1.1 X.509 token profile.
Inserts a wsse:BinarySecurityToken (DER-encoded X.509 certificate)
into the wsse:Security SOAP header, then applies an enveloped
XML-DSIG signature. The ds:Signature/ds:KeyInfo is rewritten to
use a wsse:SecurityTokenReference/wsse:Reference that points to the
token via wsu:Id, as required by WS-I BSP 1.1.
Args:
envelope_bytes: The SOAP envelope XML as bytes.
private_key: A cryptography RSA/EC private key.
certificate: The corresponding cryptography X.509 certificate.
token_id: The wsu:Id value assigned to the BST and referenced
from the signature (default "X509Token-1").
Returns: The signed envelope bytes with BSP-conformant key reference.
Raises:
ImportError: If signxml or cryptography is not installed.
XmlSecurityError: If signing fails.
verify_envelope ¶
verify_envelope(
envelope_bytes: bytes,
certificate: Any,
*,
expected_references: int | None = None,
require_signed_body: bool = True,
) -> bytes
Verify the XML Digital Signature on a SOAP envelope.
Not wired into SoapApplication.handle_request automatically —
callers integrating XML Signature verification MUST invoke this
function explicitly. For production use, also pass expected_references
matching the number of ds:Reference elements the signer pinned
(e.g. 2 for Body + Timestamp); this prevents an attacker from
dropping references and still getting a successful verify.
By default (require_signed_body=True) the function fails closed unless
the signature actually covers the SOAP Body. Without this, a signature over
only, say, the Timestamp verifies successfully and a caller could then trust
an unsigned Body — the classic reference-stripping / partial-coverage
weakness.
Envelopes carrying duplicate wsu:Id values are rejected before
verification as a signature-wrapping countermeasure (WSS 1.0 §4.3;
masterprompt §18.5).
Args:
envelope_bytes: The signed SOAP envelope as bytes.
certificate: The expected signer's cryptography X.509 certificate
or PEM bytes used to verify the signature.
expected_references: If set, the number of ds:Reference elements
the verifier must see inside ds:SignedInfo. Mismatch fails
verification. Default None preserves pre-0.5.5 behavior.
require_signed_body: If True (default), reject a signature that does not
cover the SOAP Body. Set False only when a partial-coverage
signature is deliberately expected.
Returns:
The verified (signed) content as bytes — the subtree the signature
actually covers. Callers MUST act on this returned value, not on the
original envelope_bytes, so that only signed data is trusted.
Raises:
ImportError: If signxml is not installed.
XmlSecurityError: If signature verification fails, the signature does
not cover the Body (when required), or the envelope contains
duplicate wsu:Id values.
verify_envelope_bsp ¶
verify_envelope_bsp(
envelope_bytes: bytes,
*,
expected_references: int | None = None,
require_signed_body: bool = True,
trusted_certs: Any = None,
ca_certs: Any = None,
verify_cert_trust: bool = True,
) -> bytes
Verify a SOAP envelope signed with the WS-I BSP 1.1 X.509 token profile.
Extracts the wsse:BinarySecurityToken certificate from the
wsse:Security header and uses it to verify the enveloped
ds:Signature.
Trust anchor (GHSA-859w-52fx-hcm6). The certificate is carried in the
message, so on its own it proves only that the envelope was signed by
whoever supplied it — not by a trusted party. Verifying the signature
against that certificate without establishing trust is a signature-forgery /
authentication bypass. This function therefore fails closed: you must
anchor trust with trusted_certs (pin the expected signer certificate(s))
and/or ca_certs (accept certificates issued by trusted CA(s)). Only pass
verify_cert_trust=False to deliberately accept the embedded certificate
unconditionally (INSECURE — e.g. tests).
Not wired into SoapApplication.handle_request automatically —
callers integrating BSP verification MUST invoke this function
explicitly. For production use, also pass expected_references matching
the number of ds:Reference elements the signer pinned (e.g. 2
for Body + Timestamp); this prevents an attacker from dropping
references and still getting a successful verify.
Like verify_envelope, by default (require_signed_body=True) it
fails closed unless the signature covers the SOAP Body, defeating
reference-stripping / partial-coverage signatures.
Envelopes carrying duplicate wsu:Id values are rejected before
verification as a signature-wrapping countermeasure (WSS 1.0 §4.3;
masterprompt §18.5).
Args:
envelope_bytes: The signed SOAP envelope as bytes.
expected_references: If set, the number of ds:Reference
elements the verifier must see inside ds:SignedInfo.
Mismatch fails verification. Default None preserves
pre-0.5.5 behavior.
require_signed_body: If True (default), reject a signature that does not
cover the SOAP Body. Set False only when a partial-coverage
signature is deliberately expected.
trusted_certs: Iterable of pinned signer certificates (cryptography
X.509 objects or PEM/DER bytes); the embedded certificate must equal
one of them.
ca_certs: Iterable of trusted issuer CA certificates; the embedded
certificate must be directly issued by one of them.
verify_cert_trust: If True (default), enforce the trust anchor above.
Set False to accept the embedded certificate unconditionally
(INSECURE).
Returns:
The verified (signed) content as bytes — the subtree the signature
actually covers. Callers MUST act on this returned value, not on the
original envelope_bytes.
Raises:
ImportError: If signxml or cryptography is not installed.
XmlSecurityError: If signature verification fails, the signature does
not cover the Body (when required), no token is found, or the
envelope contains duplicate wsu:Id values.
local_name ¶
local_name(elem: _Element) -> str
Return the tag name of elem without its namespace ({ns}local → local).
namespace_uri ¶
namespace_uri(elem: _Element) -> str | None
Return the namespace URI of elem's tag, or None if it has none.
parse_xml ¶
parse_xml(data: str | bytes) -> _Element
Parse an XML document from a string or bytes with the hardened parser.
The parser refuses entity expansion, DTDs, and network access (XXE/SSRF protection) and strips comments and processing instructions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
str | bytes
|
The XML document; |
required |
Returns:
| Type | Description |
|---|---|
_Element
|
The document's root element. |
Raises:
| Type | Description |
|---|---|
lxml.etree.XMLSyntaxError
|
if data is not well-formed XML. |
parse_xml_document ¶
parse_xml_document(
source: str | bytes | Path | _Element,
) -> _Element
Return the root element for source, whatever its form.
Accepts a raw XML string or bytes, a filesystem Path,
or an already-parsed element (returned unchanged). String and file input
go through the hardened parser (see parse_xml).
to_bytes ¶
to_bytes(
elem: _Element,
pretty_print: bool = False,
xml_declaration: bool = True,
) -> bytes
Serialize elem to UTF-8 bytes, by default with an XML declaration.
This is the form to put on the wire; use to_string for logging
or embedding in text.
to_string ¶
to_string(
elem: _Element, pretty_print: bool = False
) -> str
Serialize elem to a str, without an XML declaration.
soap_operation ¶
soap_operation(
*,
name: str | None = None,
input_params: list[OperationParameter] | None = None,
output_params: list[OperationParameter] | None = None,
soap_action: str | None = None,
documentation: str = "",
one_way: bool = False,
emit_rpc_result: bool = False,
) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Decorator that marks a method as a SOAP operation.