mokr.network ============ .. py:module:: mokr.network Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/mokr/network/event/index /autoapi/mokr/network/fetch/index /autoapi/mokr/network/http/index /autoapi/mokr/network/manager/index /autoapi/mokr/network/request/index /autoapi/mokr/network/response/index /autoapi/mokr/network/security/index Classes ------- .. autoapisummary:: mokr.network.NetworkEventManager mokr.network.FetchDomain mokr.network.HttpDomain mokr.network.NetworkManager mokr.network.ChromeNetworkManager mokr.network.FirefoxNetworkManager mokr.network.Request mokr.network.Response mokr.network.SecurityDetails Package Contents ---------------- .. py:class:: NetworkEventManager This class manages a collection of dictionaries used by `mokr.network.NetworkManager` to track active event status as events can be received in multiple different orders. See `mokr.network.NetworkManager` for more information. .. py:attribute:: request_will_be_sent_map .. py:attribute:: request_paused_map .. py:attribute:: http_requests_map .. py:attribute:: response_received_extra_info_map .. py:attribute:: queued_redirect_info_map .. py:attribute:: queued_event_group_map .. py:method:: forget(network_id: str) -> None Remove data for the given `network_id` from all mappings. :param network_id: Request network identifier. :type network_id: str .. py:method:: response_extra_info(network_id: str) -> list[dict] Get stored response extraInfo for given `network_id`. :param network_id: Request network identifier. :type network_id: str :returns: List of extraInfo events as dictionaries. :rtype: list[dict] .. py:method:: queued_redirect_info(fetch_id: str) -> list[dict] Get stored redirect info for given `fetch_id`. :param fetch_id: Request fetch identifier. :type fetch_id: str :returns: List of redirect info as dictionaries. :rtype: list[dict] .. py:method:: queue_redirect_info(fetch_id: str, redirect_info: list[dict]) -> None Store redirect info under a given `fetch_id`. :param fetch_id: Request fetch identifier. :type fetch_id: str :param redirect_info: Redirect info data. :type redirect_info: list[dict] .. py:method:: take_queued_redirect_info(fetch_id: str) -> list[dict] Remove and return redirect info stored under given `fetch_id`. :param fetch_id: Request fetch identifier. :type fetch_id: str :returns: Redirect info data. :rtype: list[dict] .. py:method:: get_in_flight_requests_count() -> int Get the number of active requests (not resolved). :returns: Number of active requests. :rtype: int .. py:method:: store_request_will_be_sent(network_id: str, event: dict) -> None Store a requestWillBeSent event under given `network_id`. :param network_id: Request network identifier. :type network_id: str :param event: The requestWillBeSent event received. :type event: dict .. py:method:: get_request_will_be_sent(network_id: str) -> dict Get requestWillBeSent event stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str :returns: The stored requestWillBeSent under given `network_id`. :rtype: dict .. py:method:: forget_request_will_be_sent(network_id: str) -> None Remove requestWillBeSent stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str .. py:method:: get_request_paused(network_id: str) -> dict Get requestPaused event stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str :returns: The stored requestPaused under given `network_id`. :rtype: dict .. py:method:: forget_request_paused(network_id: str) -> None Remove requestPaused stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str .. py:method:: store_request_paused(network_id: str, event: dict) -> None Store a requestPaused event under given `network_id`. :param network_id: Request network identifier. :type network_id: str :param event: The requestPaused event received. :type event: dict .. py:method:: get_request(network_id: str) -> mokr.network.request.Request Get `mokr.network.Request` stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str :returns: The stored `mokr.network.Request` under given `network_id`. :rtype: dict .. py:method:: store_request(network_id: str, request: mokr.network.request.Request) -> None Store a `mokr.network.Request` under given `network_id`. :param network_id: Request network identifier. :type network_id: str :param request: The `mokr.network.Request` received. :type request: Request .. py:method:: forget_request(network_id: str) -> None Remove `mokr.network.Request` stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str .. py:method:: get_queued_event_group(network_id: str) -> dict Get responseReceivedEvent event stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str :returns: The stored responseReceivedEvent event under given `network_id`. :rtype: dict .. py:method:: queue_event_group(network_id: str, event: dict) -> None Store a responseReceivedEvent event under given `network_id`. :param network_id: Request network identifier. :type network_id: str :param event: The responseReceivedEvent received. :type event: dict .. py:method:: forget_queued_event_group(network_id: str) -> None Remove responseReceivedEvent event stored under given `network_id`. :param network_id: Request network identifier. :type network_id: str .. py:class:: FetchDomain(page: mokr.browser.page.Page) Bases: :py:obj:`pyee.EventEmitter` Client to handle sending manual fetch requests. Note that sending fetch requests from this class will temporarily enable request interception globally. However, these fetch requests won't be caught by the request interception chain, however "response" and "requestfinished" events will still be caught. For Firefox this is not applicable. Fetch requests in Firefox are built manually from the response data. Unlike standard Firefox request responses, the response body is available for `FetchDomain` responses. Chrome requests take advantage of the existing fetch system in its `mokr.network.NetworkManager` while Firefox cannot; Chrome could do the same as Firefox does here and build the objects directly but some features would be lost like redirect chain. :param page: Parent `mokr.browser.Page` this was spawned from. :type page: Page .. py:method:: fetch(url: str | None = None, timeout: int = None, request: mokr.network.request.Request | None = None, body: str | None = None, browsing_topics: bool | None = None, cache: mokr.constants.HTTP_CACHE_TYPES | None = None, credentials: Literal['omit', 'same-origin', 'include'] | None = None, headers: dict | None = None, method: mokr.constants.HTTP_METHODS = 'GET', mode: Literal['cors', 'no-cors', 'same-origin'] = None, priority: Literal['high', 'low', 'auto'] | None = None, redirect: Literal['follow', 'error', 'manual'] | None = None, referrer: str | None = None, referrer_policy: mokr.constants.REFERRER_POLICIES | None = None) -> mokr.network.response.Response :async: Send a fetch request. Note that fetch is sensitive to the current site's CORS settings. Additionally, trying to send a fetch request before the DOM loads can hang forever. :param url: The url to request. Ignored if `request` is given. Defaults to None. :type url: str | None, optional :param timeout: Time in milliseconds to wait. Defaults to None. :type timeout: int, optional :param request: A request object to pull `url`, `method`, and `headers` from. Defaults to None. :type request: Request | None, optional :param body: Body to add to the request. Defaults to None. :type body: str | None, optional :param browsing_topics: If True, selected topics will be sent in a Sec-Browsing-Topics header with the associated request. Defaults to None. :type browsing_topics: bool | None, optional :param cache: How the request should interact with the HTTP cache. One of: "default", "no-store", "reload", "no-cache", "force-cache", or "only-if-cache". Defaults to None. :type cache: HTTP_CACHE_TYPES :param credentials: How to handle credentials. One of "omit", "same-origin", or "include". Defaults to None. :type credentials: Literal[str] | None, optional :param headers: Headers to pass with the request. Defaults to None. :type headers: dict | None, optional :param method: HTTP method. Defaults to "GET". :type method: HTTP_METHODS, optional :param mode: CORS mode to use. Defaults to None. :type mode: Literal["cors", "no-cors", "same-origin"], optional :param priority: Priority of request relative to others. Defaults to None. :type priority: Literal["high", "low", "auto"] | None, optional :param redirect: How to handle redirects. Defaults to None ("follow"). :type redirect: Literal["follow", "error", "manual"] | None, optional :param referrer: Request referrer. Defaults to None. :type referrer: str | None, optional :param referrer_policy: The referrer policy to use. One of "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", or "unsafe-url". Defaults to None ("strict-origin-when-cross-origin"). :type referrer_policy: REFERRER_POLICIES :raises ValueError: Raised if neither `url` nor `request` given. :raises NetworkError: Raised if no response found when request resolves. :returns: Last response recieved after all redirects, if any. :rtype: Response .. py:class:: HttpDomain(page: mokr.browser.page.Page, sync_cookies: Literal['both', 'http', 'page', 'none'] = 'both', **httpx_client_kwargs) Client to handle sending requests outside of the browser, while syncing state between itself and the parent `mokr.browser.Page`. This client uses `httpx` so requests can be made with HTTP2. :param page: Parent `mokr.browser.Page` that this will sync with. :type page: Page :param sync_cookies: Whether to sync cookies between this client and the parent `mokr.browser.Page` before/after each request and response. Defaults to "both". :type sync_cookies: Literal["both", "http", "page", "none"], optional .. py:method:: send(url: str, method: mokr.constants.HTTP_METHODS = 'GET', params: dict | None = None, headers: dict | None = None, data: dict | None = None, json: dict | None = None, **httpx_request_kwargs) -> mokr.network.response.Response :async: Send an HTTP request. :param url: The url to request. :type url: str :param method: HTTP method. Defaults to "GET". :type method: Literal[str], optional :param params: Parameters to encode in the URL before sending. Defaults to None (omitted). :type params: dict | None, optional :param headers: Additional headers to send with this request beyond what was set when the client was created. Defaults to None (omitted). :type headers: dict | None, optional :param data: Data payload to deliver with request (form-encoded data). Only for "PUT", "POST", and "PATCH". Defaults to None (omitted). :type data: dict | None, optional :param json: Data payload to deliver with request (JSON-encoded data). Only for "PUT", "POST", and "PATCH". Defaults to None (omitted). :type json: dict | None, optional :raises ValueError: Raised if invalid HTTP method given or `data` or `json` arguments given with incompatible methods. :returns: A `mokr.network.Response` created from the `httpx.Response`. All redirects will also be created, and original requests and responses will be accessible from the `mokr.network` objects. :rtype: Response .. py:class:: NetworkManager(page: mokr.browser.page.Page, client: mokr.connection.DevtoolsConnection, frame_manager: mokr.frame.FrameManager, interception_callback_chain: list[Callable]) Bases: :py:obj:`pyee.EventEmitter` The base event emitter class. All other event emitters inherit from this class. Most events are registered with an emitter via the `on` and `once` methods, and fired with the `emit` method. However, pyee event emitters have two *special* events: - `new_listener`: Fires whenever a new listener is created. Listeners for this event do not fire upon their own creation. - `error`: When emitted raises an Exception by default, behavior can be overridden by attaching callback to the event. For example: ```py @ee.on('error') def on_error(message): logging.err(message) ee.emit('error', Exception('something blew up')) ``` All callbacks are handled in a synchronous, blocking manner. As in node.js, raised exceptions are not automatically handled for you---you must catch your own exceptions, and treat them accordingly. .. py:attribute:: credentials .. py:attribute:: user_agent :value: '' .. py:attribute:: user_agent_metadata :value: '' .. py:method:: create(page: mokr.browser.page.Page, client: mokr.connection.DevtoolsConnection, frame_manager: mokr.frame.FrameManager, ignore_https_errors: bool, interception_callback_chain: list[Callable]) -> NetworkManager :classmethod: :async: Async constructor for this class. Necessary to run some asyncronous post-initialisation tasks. :param page: Parent `mokr.browser.Page`. :type page: Page :param client: A `mokr.connection.DevtoolsConnection` spawned by the parent `mokr.browser.Page`. :type client: DevtoolsConnection :param frame_manager: A `mokr.frame.FrameManager` spawned by the parent `mokr.browser.Page`. :type frame_manager: FrameManager :param ignore_https_errors: Ignore site security errors. Inherited from parent `mokr.browser.Page`. :type ignore_https_errors: bool :param interception_callback_chain: A list of callables for use with "request" event interception. This list is shared by the parent `mokr.browser.Page` and all newly created `mokr.network.Request` objects in this manager. :type interception_callback_chain: list[Callable] :returns: New `NetworkManager` with applied configurations. :rtype: NetworkManager .. py:method:: set_extra_http_headers() -> None :abstractmethod: :async: .. py:method:: set_request_interception() -> None :abstractmethod: :async: .. py:method:: set_credentials() -> None :abstractmethod: :async: .. py:method:: emulate_network_conditions(latency: int | None = 0, download: int | None = -1, upload: int | None = -1) -> None :async: Emulate the given network conditions. If network conditions unset, will set them to the default (disable all throttling and no latency). :param latency: Minimum latency in milliseconds from request sent to response headers received. Defaults to None (0). :type latency: int, optional :param download: Maximum download throughput (bytes/sec). Defaults to None (-1, disabled). :type download: int, optional :param upload: Minimum download throughput (bytes/sec). Defaults to None (-1, disabled). :type upload: int, optional .. py:method:: set_offline_mode(choice: bool) -> None :async: Enable or diable offline mode. Disabled by default. :param enabled: False to disable, True to enable. :type enabled: bool .. py:method:: set_request_cache(enabled: bool) -> None :async: Enable or disable request caching. Request caching caches requests in the browser, not `mokr.network.Request` objects. Does not check if request caching was enabled already by parent `mokr.browser.Page`. :param enabled: True to enable, False to disable. Defaults to True. :type enabled: bool, optional .. py:method:: set_user_agent(user_agent: str, user_agent_metadata: str | None = None) -> None :async: Update the user agent to be sent with every request. :param user_agent: User agent string. :type user_agent: str :param user_agent_metadata: Experimental, used to specify user agent client hints to emulate. :type user_agent_metadata: str | None, optional .. py:class:: ChromeNetworkManager(page: mokr.browser.page.Page, client: mokr.connection.DevtoolsConnection, frame_manager: mokr.frame.FrameManager, interception_callback_chain: list[Callable]) Bases: :py:obj:`mokr.network.manager.base.NetworkManager` Class to handle requests in a given `mokr.browser.Page`. This class relies on network events to be emitted, and stores events and even requests to handle the various possible chains of events. The `interception_callback_chain` this class receives from the parent `mokr.browser.Page` is shared with spawned `mokr.network.Request` objects. While the request interception callback chain is run from the `Request` object, it is initiated during select events from this class. There are four possible orders that requests will be triggered and thus handled by `NetworkManager`: - `_on_request_will_be_sent`. - `_on_request_will_be_sent`, `_on_request_paused`. - `_on_request_paused`, `_on_request_will_be_sent`. - `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_paused` (see crbug.com/1196004). There are a few different ways requests need to be handled due to this: - For `_on_request` we need the event from `_on_request_will_be_sent` and optionally the `fetch_request_id` (event["requestId"] also known as "interceptionId") from `_on_request_paused`. - If request interception is disabled, call `_on_request` once per call to `_on_request_will_be_sent`. - If request interception is enabled, call `_on_request` once per call to `_on_request_paused` (once per `fetch_request_id`). - Events are stored via the `mokr.network.NetworkEventManager` to allow for subsequent events to call `_on_request`. - Chains of redirect requests have the same `requestId` as the original request. This means events can be received in multiple orders for different requests in the same redirect chain such as: - `_on_request_will_be_sent`, `_on_request_will_be_sent`, ... - `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, ... - `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_paused`, `_on_request_will_be_sent`, ... - `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_will_be_sent`, `_on_request_paused`, `_on_request_paused`, ... (see crbug.com/1196004) :param page: Parent `mokr.browser.Page`. :type page: Page :param client: A `mokr.connection.DevtoolsConnection` spawned by the parent `mokr.browser.Page`. :type client: DevtoolsConnection :param frame_manager: The `mokr.frame.FrameManager` from the `mokr.browser.Page` that spawned this element. :type frame_manager: FrameManager :param interception_callback_chain: A list of callbacks to be passed into new `mokr.network.Request`s that will be run during "request" event interception, by that object. Inherited from the parent `mokr.browser.Page`. :type interception_callback_chain: list[Callable] .. py:property:: extra_http_headers :type: dict[str, str] Any extra HTTP headers assigned to this class. These are sent with every request this manager handles. .. py:method:: forget_request(request: mokr.network.request.Request, events: bool) -> None Drop a request from the `mokr.network.NetworkEventManager` and remove from attempted authentications listing, if relevant. Optionally forget all events tied to the remote request networkID, too. :param request: `mokr.request.Request` to forget. :type request: Request :param events: If True, drop all events stored for the request, too. :type events: bool .. py:method:: get_in_flight_requests_count() -> int Get the number of active requests (not resolved). Wraps `mokr.network.NetworkEventManager.get_in_flight_requests_count`. :returns: Number of active requests. :rtype: int .. py:method:: set_credentials(credentials: dict[Literal['username', 'password'], str]) -> None :async: Set the credentials to use for HTTP authentication. :param credentials: A dictionary with credentials, keyed as "username" and "password". :type credentials: dict[str, str] .. py:method:: set_extra_http_headers(extra_http_headers: dict[str, str]) -> None :async: Set extra headers to be sent with every request. :param extra_http_headers: A dictionary of headers. :type extra_http_headers: dict[str, str] :raises ValueError: Raised if any header value is not string. .. py:method:: set_request_interception(choice: bool) -> None :async: Disable or enabled request interception (enabled by default). See `mokr.browser.Page.on` for details on using the request interception callback chain. :param choice: False to disable, True to enable. :type choice: bool .. py:class:: FirefoxNetworkManager(page: mokr.browser.page.Page, client: mokr.connection.DevtoolsConnection, frame_manager: mokr.frame.FrameManager, interception_callback_chain: list[Callable]) Bases: :py:obj:`mokr.network.manager.base.NetworkManager` Class to handle requests in a given `mokr.browser.Page`. Note that functionality of this class is severely limited compared to it's Chrome counterpart, `mokr.network.ChromeNetworkManager`. Request interception does not block requests and can only be used to observe partial request and response data. The `interception_callback_chain` this class receives from the parent `mokr.browser.Page` is shared with spawned `mokr.network.Request` objects. While the request interception callback chain is run from the `Request` object, it is initiated during select events from this class. :param page: Parent `mokr.browser.Page`. :type page: Page :param client: A `mokr.connection.DevtoolsConnection` spawned by the parent `mokr.browser.Page`. :type client: DevtoolsConnection :param frame_manager: The `mokr.frame.FrameManager` from the `mokr.browser.Page` that spawned this element. :type frame_manager: FrameManager :param interception_callback_chain: A list of callbacks to be passed into new `mokr.network.Request`s that will be run during "request" event interception, by that object. Inherited from the parent `mokr.browser.Page`. :type interception_callback_chain: list[Callable] .. py:property:: extra_http_headers :type: dict[str, str] For parity; Firefox doesn't support sending extra headers via CDP. .. py:method:: set_request_interception(*args, **kwargs) -> None :async: Not supported by Firefox. :raises FirefoxNotImplementedError: When Firefox unsupported errors are on. .. py:method:: set_extra_http_headers(*args, **kwargs) -> None :async: Not supported by Firefox. :raises FirefoxNotImplementedError: When Firefox unsupported errors are on. .. py:class:: Request(page: mokr.browser.page.Page, client: mokr.connection.DevtoolsConnection, request_id: str | None, interception_id: str | None, is_navigation_request: bool, allow_interception: bool, url: str, resource_type: str, payload: dict, frame: mokr.frame.Frame | None, redirect_chain: list[Request], interception_callback_chain: list[Callable], httpx_request: httpx.Request | None = None) Representative of a remote network request, this object is created by a `mokr.network.NetworkManager`. The creation of a `Request` does not signify the request has been sent, or that a request response has been received. :param page: Parent `mokr.browser.Page`. :type page: Page :param client: A `mokr.connection.DevtoolsConnection` spawned by the parent `mokr.network.NetworkManager`. :type client: DevtoolsConnection :param request_id: The network request identifier, from the remote request event's requestId. :type request_id: str | None :param interception_id: The fetch request identifier, from the remote request event's interceptionId. This can be confusing as the fetch domain refers to this as the requestId. :type interception_id: str | None :param is_navigation_request: Whether or not this request will affect remote frame navigation. :type is_navigation_request: bool :param allow_interception: Whether or not to allow "request" event interception. :type allow_interception: bool :param url: The remote request URL. :type url: str :param resource_type: Resource type as it was perceived by the rendering engine. See `Request.resource_type` for more. :type resource_type: str :param payload: Request data and metadata. :type payload: dict :param frame: The `mokr.frame.Frame` this request originated from. :type frame: Frame | None :param redirect_chain: A list of `Request` objects that were redirects and lead to this request. :type redirect_chain: list[Request] :param interception_callback_chain: A list of callbacks shared with the parent `mokr.network.NetworkManager` and its parent `mokr.browser.Page`. These callbacks wil run sequentially during "request" event interception. See `mokr.browser.Page` for more information. :type interception_callback_chain: list[Callable] :param httpx_request: (httpx.Request | None, optional): If created by a `mokr.network.HttpDomain`, the original `httpx.Request` that this will be built from. .. py:property:: url :type: str URL from the remote request. .. py:property:: resource_type :type: str Resource type as it was perceived by the rendering engine. One of "Document", "Stylesheet", "Image", "Media", "Font", "Script", "TextTrack", "XHR", "Fetch", "Prefetch", "EventSource", "WebSocket", "Manifest", "SignedExchange", "Ping", "CSPViolationReport", "Preflight", or "Other". .. py:property:: method :type: str | None HTTP request method from remote request, such as "GET", "POST", "PATCH". .. py:property:: post_data :type: str | None Data from this `Request`'s `payload["postData"]`, if any. .. py:property:: headers :type: dict All headers for the target request with keys lowered. .. py:property:: response :type: mokr.network.response.Response | None The `mokr.network.Response` object created from the remote response bound to the remote request, or None if not yet received. .. py:property:: frame :type: mokr.frame.Frame | None The corresponding `mokr.frame.Frame`, if any. .. py:property:: redirect_chain :type: list[Request] Return the chain of `Request` objects if the first remote request was a redirect. The chain will be shared will all subsequent `Request` objects initiated from the redirect, and the final `Request` in the chain will not be a redirect. .. py:property:: httpx_request :type: bool If created by a `mokr.network.HttpDomain`, this will hold the original `httpx.Request` object this was populated from. Otherwise, None. .. py:method:: is_navigation_request() -> bool Whether or not this request will affect remote frame navigation. :returns: True if navigating the frame, otherwise False. :rtype: bool .. py:method:: failure_text() -> str | None Return error text from failed requests. For successful requests, this will return None. :returns: Error text if request failed, otherwise None. :rtype: str | None .. py:method:: release(url: str = None, method: str = None, post_data: str = None, headers: dict = None) -> None :async: Release an intercepted request, optionally altering select parameters. Stops execution of the rest of the interception chain. :param url: The URL to overwrite the request with, if any. Defaults to None (use initiated `Request.url`). :type url: str, optional :param method: The HTTP request method (e.g. "GET", "POST") to overwrite the request with, if any. Defaults to None (use initiated `Request.url`). :type method: str, optional :param post_data: The post data (payload["postData"]) to overwrite the request with, if any. Defaults to None (use initiated `Request.post_data`). :type post_data: str, optional :param headers: Headers, will completely replace existing headers. Defaults to None (use `Request.headers`). :type headers: dict, optional .. py:method:: fulfill(response: mokr.network.response.Response | None = None, status: int = 200, headers: dict | None = None, body: str | bytes | None = None) -> None :async: Respond to a request with the given response data. Prevents the remote request from being actually sent. Cannot be used with data urls. Stops execution of the rest of the interception chain. :param response: A completed `mokr.network.Reponse` object to extract data from. Passing this will ignore all other kwargs passed. Defaults to None. :type response: Response | None, optional :param status: HTTP status code. Defaults to 200. :type status: int, optional :param headers: Response headers. Defaults to None (empty headers). :type headers: dict | None, optional :param body: Response body. Defaults to None (empty body). :type body: str | bytes | None, optional .. py:method:: abort(error_reason: str = 'failed') -> None :async: Abort the remote request. This will prevent the request from being sent, which can cause a `mokr.exceptions.PageError` to raise later if `Request.is_navigation_request` is True. Stops execution of the rest of the interception chain. :param error_reason: The error reason to give when aborting the request. One of "Failed", "Aborted", "TimedOut", "AccessDenied", "ConnectionClosed", "ConnectionReset", "ConnectionRefused", "ConnectionAborted", "ConnectionFailed", "NameNotResolved", "InternetDisconnected", "AddressUnreachable", "BlockedByClient", or "BlockedByResponse". Defaults to "failed". :type error_reason: str, optional :raises NetworkError: Raised if unknown error reason is given. .. py:class:: Response(client: mokr.connection.DevtoolsConnection, request: mokr.network.request.Request, status: int, headers: dict[str, str], from_disk_cache: bool, from_service_worker: bool, from_firefox: bool, security_details: dict = None, extra_info: dict = None, httpx_response: httpx.Response | None = None) Reprentation of a remote response to a network request. `Response` objects are created by the `mokr.network.NetworkManager` when a response or redirect response is received. Pseudo `Response` objects are also made from `httpx.Response` objects by a `mokr.network.HttpDomain`. :param client: A `mokr.connection.DevtoolsConnection` spawned by the parent `mokr.network.NetworkManager`. :type client: DevtoolsConnection :param request: The `mokr.request.Request` that this `Response` is bound to. Importantly, the `Request` does not spawn this. :type request: Request :param status: Status code for the response. :type status: int :param headers: Response headers as dictionary. :type headers: dict[str, str] :param from_disk_cache: Whether the remote response was served from the cache or not. :type from_disk_cache: bool :param from_service_worker: Whether the remote response was served by a service worker or not. :type from_service_worker: bool :param security_details: Security information for a given response. Defaults to None. :type security_details: dict, optional :param extra_info: Any extra info associated with the remote response. Defaults to None. :type extra_info: dict, optional :param httpx_response: (httpx.Response | None, optional): If created by a `mokr.network.HttpDomain`, the original `httpx.Response` that this will be built from. .. py:property:: url :type: str URL from the remote response. .. py:property:: ok :type: bool Whether the response failed or not (status code between 399 and 600). .. py:property:: status :type: int The HTTP status code for the remote response. .. py:property:: extra_status_info :type: str | None Additional status information from an event's "extraInfo" or None. .. py:property:: reason :type: str The HTTP reason text for the remote response. .. py:property:: headers :type: dict All headers for the target response with keys lowered. .. py:property:: security_details :type: mokr.network.security.SecurityDetails | None Initialised `mokr.network.SecurityDetails` if the remote response was securely received, otherwise None. .. py:property:: request :type: mokr.network.request.Request The `mokr.network.Request` object bound to this `Response`. .. py:property:: from_cache :type: bool Whether the remote response was served from the disk or memory caches. .. py:property:: from_service_worker :type: bool Whether the remote response was served by a service worker or not. .. py:property:: httpx_response :type: bool If created by a `mokr.network.HttpDomain`, this will hold the original `httpx.Response` object this was populated from. Otherwise, None. .. py:method:: buffer(force: bool = False) -> Awaitable[bytes] Return buffer awaitable which queries remote response object's body, if not already loaded in this `Response`. Can force querying with the `force` option. :param force: Whether to bypass checking if the body has been cached here. Useful for `mokr.network.FetchDomain` requests or other requests where the body may resolve slower. Defaults to False. :type force: bool, optional :returns: Awaitable that yields response body as bytes. :rtype: Awaitable[bytes] .. py:method:: content() -> str | bytes :async: Get body of the remote response object. If content is empty, tries to rerun query for the remote response object's body via `Response.buffer(force=True)`. :returns: Content of response. :rtype: str | bytes .. py:method:: json() -> dict :async: Load the body via `json.loads`. :raises JSONDecodeError: Raised from `json.loads` if body is not JSON text. :returns: Loaded body as dictionary. :rtype: dict .. py:method:: to_dict() -> dict :async: Return a dictionary representation of the `Response` including the `Response.status`, `Response.headers`, and the response body via `Response.content`. :returns: _description_ :rtype: dict .. py:class:: SecurityDetails(subject_name: str, issuer: str, valid_from: int, valid_to: int, protocol: str) A simple representation of remote response security details. :param subject_name: Subject to which the certificate was issued to. :type subject_name: str :param issuer: Name of issuer of the certificate. :type issuer: str :param valid_from: Unix time string of start of certificate validity. :type valid_from: int :param valid_to: Unix time string of end of certificate validity. :type valid_to: int :param protocol: Security protocol (e.g. "TLS1.2", "TLS1.3"). :type protocol: str .. py:property:: subject_name :type: str Subject to which the certificate was issued to. .. py:property:: issuer :type: str Name of issuer of the certificate. .. py:property:: valid_from :type: int Unix time string of start of certificate validity. .. py:property:: valid_to :type: int Unix time string of end of certificate validity. .. py:property:: protocol :type: str Security protocol (e.g. "TLS1.2", "TLS1.3").