import threading from contextlib import contextmanager import attr @attr.s(slots=True) class Settings: """ :param strict: boolean to indicate if the lxml should be parsed a 'strict'. If false then the recover mode is enabled which tries to parse invalid XML as best as it can. :type strict: boolean :param raw_response: boolean to skip the parsing of the XML response by zeep but instead returning the raw data :param forbid_dtd: disallow XML with a processing instruction :type forbid_dtd: bool :param forbid_entities: disallow XML with declarations inside the DTD :type forbid_entities: bool :param forbid_external: disallow any access to remote or local resources in external entities or DTD and raising an ExternalReferenceForbidden exception when a DTD or entity references an external resource. :type forbid_external: bool :param xml_huge_tree: disable lxml/libxml2 security restrictions and support very deep trees and very long text content :param force_https: Force all connections to HTTPS if the WSDL is also loaded from an HTTPS endpoint. (default: true) :type force_https: bool :param extra_http_headers: Additional HTTP headers to be sent to the transport. This can be used in combination with the context manager approach to add http headers for specific calls. :type extra_headers: list :param xsd_ignore_sequence_order: boolean to indicate whether to enforce sequence order when parsing complex types. This is a workaround for servers that don't respect sequence order. :type xsd_ignore_sequence_order: boolean """ strict = attr.ib(default=True) raw_response = attr.ib(default=False) # transport force_https = attr.ib(default=True) extra_http_headers = attr.ib(default=None) # lxml processing xml_huge_tree = attr.ib(default=False) forbid_dtd = attr.ib(default=False) forbid_entities = attr.ib(default=True) forbid_external = attr.ib(default=True) # xsd workarounds xsd_ignore_sequence_order = attr.ib(default=False) _tls = attr.ib(default=attr.Factory(threading.local)) @contextmanager def __call__(self, **options): current = {} for key, value in options.items(): current[key] = getattr(self, key) setattr(self._tls, key, value) try: yield finally: for key, value in current.items(): default = getattr(self, key) if value == default: delattr(self._tls, key) else: setattr(self._tls, key, value) def __getattribute__(self, key): _tls = object.__getattribute__(self, "_tls") if key != "_tls" and hasattr(_tls, key): return getattr(_tls, key) return object.__getattribute__(self, key)