diff --git a/docs/usage/session.rst b/docs/usage/session.rst index 1a731ac4..6dd1b151 100644 --- a/docs/usage/session.rst +++ b/docs/usage/session.rst @@ -338,6 +338,18 @@ To define a different session config for a given URL pattern, install .. autofunction:: scrapy_zyte_api.session_config +If in a session config implementation or in any other Scrapy component you need +to tell whether a request is a :ref:`session initialization request +` or not, use :func:`~scrapy_zyte_api.is_session_init_request`: + +.. autofunction:: scrapy_zyte_api.is_session_init_request + +Classes decorated with :func:`~scrapy_zyte_api.session_config` are registered +into :data:`~scrapy_zyte_api.session_config_registry`: + +.. autodata:: scrapy_zyte_api.session_config_registry + :annotation: + .. _session-cookies: Cookie handling diff --git a/scrapy_zyte_api/__init__.py b/scrapy_zyte_api/__init__.py index 8767d177..de1ff8e1 100644 --- a/scrapy_zyte_api/__init__.py +++ b/scrapy_zyte_api/__init__.py @@ -19,8 +19,10 @@ from ._session import ( ScrapyZyteAPISessionDownloaderMiddleware, SessionConfig, + is_session_init_request, session_config, ) +from ._session import session_config_registry as _session_config_registry from .addon import Addon from .handler import ScrapyZyteAPIDownloadHandler @@ -37,3 +39,7 @@ #: .. note:: When using python-zyte-api 0.5.2 or lower, this is the same as #: :data:`~scrapy_zyte_api.SESSION_DEFAULT_RETRY_POLICY`. SESSION_AGGRESSIVE_RETRY_POLICY = _SESSION_AGGRESSIVE_RETRY_POLICY + +#: Instance of :class:`web_poet.rules.RulesRegistry` that holds :ref:`session +#: configs `. +session_config_registry = _session_config_registry diff --git a/scrapy_zyte_api/_session.py b/scrapy_zyte_api/_session.py index 5245ac8a..90123fbd 100644 --- a/scrapy_zyte_api/_session.py +++ b/scrapy_zyte_api/_session.py @@ -37,6 +37,12 @@ ZYTE_API_META_KEYS = ("zyte_api", "zyte_api_automap", "zyte_api_provider") +def is_session_init_request(request): + """Return ``True`` if the request is a :ref:`session initialization request + ` or ``False`` otherwise.""" + return request.meta.get(SESSION_INIT_META_KEY, False) is True + + class SessionRetryFactory(RetryFactory): temporary_download_error_stop = stop_after_attempt(1) @@ -338,6 +344,10 @@ def params(self, request: Request) -> Dict[str, Any]: "url": "https://example.com/new-session", "httpResponseBody": True, } + + The returned parameters do not need to include :http:`request:url`. If + missing, it is picked from the request :ref:`triggering a session + initialization request `. """ if location := self.location(request): return { @@ -358,6 +368,10 @@ def check(self, response: Response, request: Request) -> bool: The default implementation checks the outcome of the ``setLocation`` action if a location was defined, as described in :ref:`session-check`. + + If you need to tell whether *request* is a :ref:`session initialization + request ` or not, use + :func:`~scrapy_zyte_api.is_session_init_request`. """ if self._checker: return self._checker.check(response, request) diff --git a/tests/test_sessions.py b/tests/test_sessions.py index f4d5a6e6..d7baa0c9 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -17,6 +17,7 @@ SESSION_AGGRESSIVE_RETRY_POLICY, SESSION_DEFAULT_RETRY_POLICY, SessionConfig, + is_session_init_request, session_config, ) from scrapy_zyte_api._session import SESSION_INIT_META_KEY, session_config_registry @@ -2649,3 +2650,16 @@ def parse(self, response): } if reason is not None: assert reason in caplog.text + + +@pytest.mark.parametrize( + ("meta", "expected"), + ( + ({}, False), + ({SESSION_INIT_META_KEY: False}, False), + ({SESSION_INIT_META_KEY: True}, True), + ), +) +def test_is_session_init_request(meta, expected): + actual = is_session_init_request(Request("https://example.com", meta=meta)) + assert expected == actual