apify 2.7.1b3__tar.gz → 2.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of apify might be problematic. Click here for more details.
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/pre_release.yaml +4 -4
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/release.yaml +4 -4
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/run_code_checks.yaml +4 -4
- {apify-2.7.1b3 → apify-2.7.2}/CHANGELOG.md +14 -5
- {apify-2.7.1b3 → apify-2.7.2}/CONTRIBUTING.md +1 -1
- {apify-2.7.1b3 → apify-2.7.2}/PKG-INFO +5 -4
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/02_running_actors_locally.mdx +1 -1
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/10_logging.mdx +0 -30
- {apify-2.7.1b3 → apify-2.7.2}/pyproject.toml +10 -9
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_actor.py +6 -42
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_charging.py +9 -15
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_configuration.py +1 -1
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_crypto.py +6 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_models.py +7 -7
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_platform_event_manager.py +36 -20
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_proxy_configuration.py +5 -2
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_utils.py +2 -17
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_apify_storage_client.py +1 -1
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/log.py +2 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/storages/_request_list.py +3 -3
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/conftest.py +2 -2
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_api_helpers.py +2 -2
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_events.py +1 -3
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_lifecycle.py +1 -3
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/conftest.py +22 -3
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/test_platform_event_manager.py +1 -4
- {apify-2.7.1b3 → apify-2.7.2}/uv.lock +427 -145
- apify-2.7.2/website/docusaurus.config.js +145 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/package-lock.json +1042 -631
- {apify-2.7.1b3 → apify-2.7.2}/website/package.json +1 -1
- {apify-2.7.1b3 → apify-2.7.2}/website/src/pages/index.module.css +1 -1
- apify-2.7.1b3/docs/03_concepts/code/10_redirect_log.py +0 -15
- apify-2.7.1b3/docs/03_concepts/code/10_redirect_log_existing_run.py +0 -24
- apify-2.7.1b3/website/docusaurus.config.js +0 -264
- apify-2.7.1b3/website/static/img/guides/redirected_logs_example.webp +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.editorconfig +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.github/CODEOWNERS +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/build_and_deploy_docs.yaml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/check_pr_title.yaml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.github/workflows/update_new_issue.yaml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.gitignore +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.markdownlint.yaml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/.pre-commit-config.yaml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/LICENSE +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/Makefile +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/README.md +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/01_introduction.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/03_actor_structure.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/code/01_introduction.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/code/actor_structure/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/code/actor_structure/__main__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/code/actor_structure/main.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/01_overview/code/actor_structure/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/01_beautifulsoup_httpx.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/02_crawlee.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/03_playwright.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/04_selenium.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/05_scrapy.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/01_beautifulsoup_httpx.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/02_crawlee_beautifulsoup.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/02_crawlee_playwright.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/03_playwright.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/04_selenium.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/__main__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/items.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/main.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/settings.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/spiders/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/spiders/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/02_guides/code/scrapy_project/src/spiders/title.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/01_actor_lifecycle.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/02_actor_input.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/03_storages.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/04_actor_events.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/05_proxy_management.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/06_interacting_with_other_actors.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/07_webhooks.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/08_access_apify_api.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/09_running_webserver.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/11_configuration.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/12_pay_per_event.mdx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/01_context_manager.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/01_init_exit.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/01_reboot.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/01_status_message.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/02_input.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_dataset_exports.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_dataset_read_write.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_deleting_storages.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_kvs_iterating.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_kvs_public_url.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_kvs_read_write.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_opening_storages.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/03_rq.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/04_actor_events.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_apify_proxy.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_apify_proxy_config.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_custom_proxy.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_custom_proxy_function.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_proxy_actor_input.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_proxy_httpx.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/05_proxy_rotation.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/06_interacting_call.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/06_interacting_call_task.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/06_interacting_metamorph.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/06_interacting_start.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/07_webhook.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/07_webhook_preventing.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/08_actor_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/08_actor_new_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/09_webserver.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/10_log_config.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/10_logger_usage.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/11_config.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/actor_charge.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/03_concepts/code/conditional_actor_charge.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/04_upgrading/upgrading_to_v2.md +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/docs/pyproject.toml +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/renovate.json +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/_consts.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_dataset_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_dataset_collection_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_key_value_store_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_key_value_store_collection_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_request_queue_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/_request_queue_collection_client.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/apify_storage_client/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/_actor_runner.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/_async_thread.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/_logging_config.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/extensions/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/extensions/_httpcache.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/middlewares/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/middlewares/apify_proxy.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/middlewares/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/pipelines/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/pipelines/actor_dataset_push.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/pipelines/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/requests.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/scheduler.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/scrapy/utils.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/storages/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/src/apify/storages/py.typed +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/README.md +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/_utils.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/actor_source_base/Dockerfile +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/actor_source_base/requirements.txt +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/actor_source_base/src/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/actor_source_base/src/__main__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/actor_source_base/src/main.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_call_timeouts.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_charge.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_create_proxy_configuration.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_dataset.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_key_value_store.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_lifecycle.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_log.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_request_queue.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_actor_scrapy.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_fixtures.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/integration/test_request_queue.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_create_proxy_configuration.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_dataset.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_env_helpers.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_helpers.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_key_value_store.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_log.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_non_default_instance.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_actor_request_queue.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_configuration.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/actor/test_request_list.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/extensions/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/extensions/test_httpcache.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/middlewares/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/middlewares/test_apify_proxy.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/pipelines/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/pipelines/test_actor_dataset_push.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/requests/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/requests/test_to_apify_request.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/requests/test_to_scrapy_request.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/utils/__init__.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/utils/test_apply_apify_settings.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/scrapy/utils/test_get_basic_auth_header.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/test_crypto.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/tests/unit/test_proxy_configuration.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/.eslintrc.json +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/babel.config.js +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/build_api_reference.sh +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/generate_module_shortcuts.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/sidebars.js +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/ApiLink.jsx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/Gradients.jsx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/Highlights.jsx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/Highlights.module.css +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/RunnableCodeBlock.jsx +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/components/RunnableCodeBlock.module.css +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/css/custom.css +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/pages/home_page_example.py +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/src/pages/index.js +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/static/.nojekyll +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/static/img/docs-og.png +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/tools/docs-prettier.config.js +0 -0
- {apify-2.7.1b3 → apify-2.7.2}/website/tools/utils/externalLink.js +0 -0
|
@@ -32,26 +32,26 @@ jobs:
|
|
|
32
32
|
name: Lint check
|
|
33
33
|
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
|
|
34
34
|
with:
|
|
35
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
35
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
36
36
|
|
|
37
37
|
type_check:
|
|
38
38
|
name: Type check
|
|
39
39
|
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
|
|
40
40
|
with:
|
|
41
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
41
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
42
42
|
|
|
43
43
|
unit_tests:
|
|
44
44
|
name: Unit tests
|
|
45
45
|
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
|
|
46
46
|
with:
|
|
47
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
47
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
48
48
|
|
|
49
49
|
integration_tests:
|
|
50
50
|
name: Integration tests
|
|
51
51
|
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
|
|
52
52
|
secrets: inherit
|
|
53
53
|
with:
|
|
54
|
-
python-versions: '["3.
|
|
54
|
+
python-versions: '["3.9", "3.13"]'
|
|
55
55
|
|
|
56
56
|
update_changelog:
|
|
57
57
|
name: Update changelog
|
|
@@ -43,26 +43,26 @@ jobs:
|
|
|
43
43
|
name: Lint check
|
|
44
44
|
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
|
|
45
45
|
with:
|
|
46
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
46
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
47
47
|
|
|
48
48
|
type_check:
|
|
49
49
|
name: Type check
|
|
50
50
|
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
|
|
51
51
|
with:
|
|
52
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
52
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
53
53
|
|
|
54
54
|
unit_tests:
|
|
55
55
|
name: Unit tests
|
|
56
56
|
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
|
|
57
57
|
with:
|
|
58
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
58
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
59
59
|
|
|
60
60
|
integration_tests:
|
|
61
61
|
name: Integration tests
|
|
62
62
|
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
|
|
63
63
|
secrets: inherit
|
|
64
64
|
with:
|
|
65
|
-
python-versions: '["3.
|
|
65
|
+
python-versions: '["3.9", "3.13"]'
|
|
66
66
|
|
|
67
67
|
update_changelog:
|
|
68
68
|
name: Update changelog
|
|
@@ -11,19 +11,19 @@ jobs:
|
|
|
11
11
|
name: Lint check
|
|
12
12
|
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
|
|
13
13
|
with:
|
|
14
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
14
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
15
15
|
|
|
16
16
|
type_check:
|
|
17
17
|
name: Type check
|
|
18
18
|
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
|
|
19
19
|
with:
|
|
20
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
20
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
21
21
|
|
|
22
22
|
unit_tests:
|
|
23
23
|
name: Unit tests
|
|
24
24
|
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
|
|
25
25
|
with:
|
|
26
|
-
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
|
|
26
|
+
python-versions: '["3.9", "3.10", "3.11", "3.12", "3.13"]'
|
|
27
27
|
|
|
28
28
|
docs_check:
|
|
29
29
|
name: Docs check
|
|
@@ -35,4 +35,4 @@ jobs:
|
|
|
35
35
|
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
|
|
36
36
|
secrets: inherit
|
|
37
37
|
with:
|
|
38
|
-
python-versions: '["3.
|
|
38
|
+
python-versions: '["3.9", "3.13"]'
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.7.2](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.2) (2025-07-30)
|
|
6
|
+
|
|
7
|
+
### 🐛 Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Restrict apify-shared and apify-client versions (#523) ([581ebae](https://github.com/apify/apify-sdk-python/commit/581ebae5752a984a34cbabc02c49945ae392db00))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## [2.7.1](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.1) (2025-07-24)
|
|
13
|
+
|
|
14
|
+
### 🐛 Bug Fixes
|
|
15
|
+
|
|
16
|
+
- Add back support for Python 3.9.
|
|
17
|
+
|
|
18
|
+
|
|
5
19
|
## [2.7.0](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.0) (2025-07-14)
|
|
6
20
|
|
|
7
21
|
### 🚀 Features
|
|
@@ -9,11 +23,6 @@ All notable changes to this project will be documented in this file.
|
|
|
9
23
|
- Expose `logger` argument on `Actor.call` to control log redirection from started Actor run ([#487](https://github.com/apify/apify-sdk-python/pull/487)) ([aa6fa47](https://github.com/apify/apify-sdk-python/commit/aa6fa4750ea1bc7909be1191c0d276a2046930c2)) by [@Pijukatel](https://github.com/Pijukatel)
|
|
10
24
|
- **crypto:** Decrypt secret objects ([#482](https://github.com/apify/apify-sdk-python/pull/482)) ([ce9daf7](https://github.com/apify/apify-sdk-python/commit/ce9daf7381212b8dc194e8a643e5ca0dedbc0078)) by [@MFori](https://github.com/MFori)
|
|
11
25
|
|
|
12
|
-
### 🐛 Bug Fixes
|
|
13
|
-
|
|
14
|
-
- Sync `@docusaurus` theme version [internal] ([#500](https://github.com/apify/apify-sdk-python/pull/500)) ([a7485e7](https://github.com/apify/apify-sdk-python/commit/a7485e7d2276fde464ce862573d5b95e7d4d836a)) by [@katzino](https://github.com/katzino)
|
|
15
|
-
- Tagline overlap ([#501](https://github.com/apify/apify-sdk-python/pull/501)) ([bae8340](https://github.com/apify/apify-sdk-python/commit/bae8340c46fea756ea35ea4d591da84c09d478e2)) by [@katzino](https://github.com/katzino)
|
|
16
|
-
|
|
17
26
|
|
|
18
27
|
## [2.6.0](https://github.com/apify/apify-sdk-python/releases/tag/v2.6.0) (2025-06-09)
|
|
19
28
|
|
|
@@ -4,7 +4,7 @@ Here you'll find a contributing guide to get started with development.
|
|
|
4
4
|
|
|
5
5
|
## Environment
|
|
6
6
|
|
|
7
|
-
For local development, it is required to have Python 3.
|
|
7
|
+
For local development, it is required to have Python 3.9 (or a later version) installed.
|
|
8
8
|
|
|
9
9
|
We use [uv](https://docs.astral.sh/uv/) for project management. Install it and set up your IDE accordingly.
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apify
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.2
|
|
4
4
|
Summary: Apify SDK for Python
|
|
5
5
|
Project-URL: Apify Homepage, https://apify.com
|
|
6
6
|
Project-URL: Changelog, https://docs.apify.com/sdk/python/docs/changelog
|
|
@@ -219,14 +219,15 @@ Classifier: Environment :: Console
|
|
|
219
219
|
Classifier: Intended Audience :: Developers
|
|
220
220
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
221
221
|
Classifier: Operating System :: OS Independent
|
|
222
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
222
223
|
Classifier: Programming Language :: Python :: 3.10
|
|
223
224
|
Classifier: Programming Language :: Python :: 3.11
|
|
224
225
|
Classifier: Programming Language :: Python :: 3.12
|
|
225
226
|
Classifier: Programming Language :: Python :: 3.13
|
|
226
227
|
Classifier: Topic :: Software Development :: Libraries
|
|
227
|
-
Requires-Python: >=3.
|
|
228
|
-
Requires-Dist: apify-client
|
|
229
|
-
Requires-Dist: apify-shared
|
|
228
|
+
Requires-Python: >=3.9
|
|
229
|
+
Requires-Dist: apify-client<2.0.0
|
|
230
|
+
Requires-Dist: apify-shared<2.0.0
|
|
230
231
|
Requires-Dist: crawlee~=0.6.0
|
|
231
232
|
Requires-Dist: cryptography>=42.0.0
|
|
232
233
|
Requires-Dist: httpx>=0.27.0
|
|
@@ -11,7 +11,7 @@ In this page, you'll learn how to create and run Apify Actors locally on your co
|
|
|
11
11
|
|
|
12
12
|
## Requirements
|
|
13
13
|
|
|
14
|
-
The Apify SDK requires Python version 3.
|
|
14
|
+
The Apify SDK requires Python version 3.9 or above to run Python Actors locally.
|
|
15
15
|
|
|
16
16
|
## Creating your first Actor
|
|
17
17
|
|
|
@@ -7,8 +7,6 @@ import CodeBlock from '@theme/CodeBlock';
|
|
|
7
7
|
|
|
8
8
|
import LogConfigExample from '!!raw-loader!./code/10_log_config.py';
|
|
9
9
|
import LoggerUsageExample from '!!raw-loader!./code/10_logger_usage.py';
|
|
10
|
-
import RedirectLog from '!!raw-loader!./code/10_redirect_log.py';
|
|
11
|
-
import RedirectLogExistingRun from '!!raw-loader!./code/10_redirect_log_existing_run.py';
|
|
12
10
|
|
|
13
11
|
The Apify SDK is logging useful information through the [`logging`](https://docs.python.org/3/library/logging.html) module from Python's standard library, into the logger with the name `apify`.
|
|
14
12
|
|
|
@@ -84,31 +82,3 @@ Result:
|
|
|
84
82
|
</pre>
|
|
85
83
|
|
|
86
84
|
<!-- markdownlint-enable no-inline-html -->
|
|
87
|
-
|
|
88
|
-
## Redirect logs from other Actor runs
|
|
89
|
-
|
|
90
|
-
In some situations, one Actor is going to start one or more other Actors and wait for them to finish and produce some results. In such cases, you might want to redirect the logs and status messages of the started Actors runs back to the parent Actor run, so that you can see the progress of the started Actors' runs in the parent Actor's logs. This guide will show possibilities on how to do it.
|
|
91
|
-
|
|
92
|
-
### Redirecting logs from Actor.call
|
|
93
|
-
|
|
94
|
-
Typical use case for log redirection is to call another Actor using the [`Actor.call`](../../reference/class/Actor#call) method. This method has an optional `logger` argument, which is by default set to the `default` literal. This means that the logs of the called Actor will be automatically redirected to the parent Actor's logs with default formatting and filtering. If you set the `logger` argument to `None`, then no log redirection happens. The third option is to pass your own `Logger` instance with the possibility to define your own formatter, filter, and handler. Below you can see those three possible ways of log redirection when starting another Actor run through [`Actor.call`](../../reference/class/Actor#call).
|
|
95
|
-
|
|
96
|
-
<CodeBlock className="language-python">
|
|
97
|
-
{RedirectLog}
|
|
98
|
-
</CodeBlock>
|
|
99
|
-
|
|
100
|
-
Each default redirect logger log entry will have a specific format. After the timestamp, it will contain cyan colored text that will contain the redirect information - the other actor's name and the run ID. The rest of the log message will be printed in the same manner as the parent Actor's logger is configured.
|
|
101
|
-
|
|
102
|
-
The log redirection can be deep, meaning that if the other actor also starts another actor and is redirecting logs from it, then in the top-level Actor, you can see it as well. See the following example screenshot of the Apify log console when one actor recursively starts itself (there are 2 levels of recursion in the example).
|
|
103
|
-
|
|
104
|
-

|
|
105
|
-
|
|
106
|
-
### Redirecting logs from already running Actor run
|
|
107
|
-
|
|
108
|
-
In some cases, you might want to connect to an already running Actor run and redirect its logs to your current Actor run. This can be done using the [ApifyClient](../../reference/class/Actor#apify_client) and getting the streamed log from a specific Actor run. You can then use it as a context manager, and the log redirection will be active in the context, or you can control the log redirection manually by explicitly calling `start` and `stop` methods.
|
|
109
|
-
|
|
110
|
-
You can further decide whether you want to redirect just new logs of the ongoing Actor run, or if you also want to redirect historical logs from that Actor's run, so all logs it has produced since it was started. Both options are shown in the example code below.
|
|
111
|
-
|
|
112
|
-
<CodeBlock className="language-python">
|
|
113
|
-
{RedirectLogExistingRun}
|
|
114
|
-
</CodeBlock>
|
|
@@ -4,18 +4,19 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "apify"
|
|
7
|
-
version = "2.7.
|
|
7
|
+
version = "2.7.2"
|
|
8
8
|
description = "Apify SDK for Python"
|
|
9
9
|
authors = [{ name = "Apify Technologies s.r.o.", email = "support@apify.com" }]
|
|
10
10
|
license = { file = "LICENSE" }
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Development Status :: 5 - Production/Stable",
|
|
15
15
|
"Environment :: Console",
|
|
16
16
|
"Intended Audience :: Developers",
|
|
17
17
|
"License :: OSI Approved :: Apache Software License",
|
|
18
18
|
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
19
20
|
"Programming Language :: Python :: 3.10",
|
|
20
21
|
"Programming Language :: Python :: 3.11",
|
|
21
22
|
"Programming Language :: Python :: 3.12",
|
|
@@ -34,8 +35,8 @@ keywords = [
|
|
|
34
35
|
"scraping",
|
|
35
36
|
]
|
|
36
37
|
dependencies = [
|
|
37
|
-
"apify-client
|
|
38
|
-
"apify-shared
|
|
38
|
+
"apify-client<2.0.0",
|
|
39
|
+
"apify-shared<2.0.0",
|
|
39
40
|
"crawlee~=0.6.0",
|
|
40
41
|
"cryptography>=42.0.0",
|
|
41
42
|
"httpx>=0.27.0",
|
|
@@ -64,11 +65,11 @@ scrapy = ["scrapy>=2.11.0"]
|
|
|
64
65
|
dev = [
|
|
65
66
|
"build~=1.2.0",
|
|
66
67
|
"dycw-pytest-only>=2.1.1",
|
|
67
|
-
"griffe~=1.
|
|
68
|
-
"mypy~=1.
|
|
68
|
+
"griffe~=1.7.0",
|
|
69
|
+
"mypy~=1.16.0",
|
|
69
70
|
"pre-commit~=4.2.0",
|
|
70
71
|
"pydoc-markdown~=4.8.0",
|
|
71
|
-
"pytest-asyncio~=1.
|
|
72
|
+
"pytest-asyncio~=1.0.0",
|
|
72
73
|
"pytest-cov~=6.2.0",
|
|
73
74
|
"pytest-timeout>=2.4.0",
|
|
74
75
|
"pytest-xdist~=3.8.0",
|
|
@@ -187,7 +188,7 @@ asyncio_mode = "auto"
|
|
|
187
188
|
timeout = 1200
|
|
188
189
|
|
|
189
190
|
[tool.mypy]
|
|
190
|
-
python_version = "3.
|
|
191
|
+
python_version = "3.9"
|
|
191
192
|
plugins = ["pydantic.mypy"]
|
|
192
193
|
files = ["src", "tests", "docs", "website"]
|
|
193
194
|
check_untyped_defs = true
|
|
@@ -214,7 +215,7 @@ module = [
|
|
|
214
215
|
ignore_missing_imports = true
|
|
215
216
|
|
|
216
217
|
[tool.basedpyright]
|
|
217
|
-
pythonVersion = "3.
|
|
218
|
+
pythonVersion = "3.9"
|
|
218
219
|
typeCheckingMode = "standard"
|
|
219
220
|
include = ["src", "tests", "docs", "website"]
|
|
220
221
|
|
|
@@ -5,7 +5,7 @@ import os
|
|
|
5
5
|
import sys
|
|
6
6
|
from contextlib import suppress
|
|
7
7
|
from datetime import datetime, timedelta, timezone
|
|
8
|
-
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, cast, overload
|
|
9
9
|
|
|
10
10
|
from lazy_object_proxy import Proxy
|
|
11
11
|
from more_itertools import flatten
|
|
@@ -13,7 +13,7 @@ from pydantic import AliasChoices
|
|
|
13
13
|
|
|
14
14
|
from apify_client import ApifyClientAsync
|
|
15
15
|
from apify_shared.consts import ActorEnvVars, ActorExitCodes, ApifyEnvVars
|
|
16
|
-
from apify_shared.utils import maybe_extract_enum_member_value
|
|
16
|
+
from apify_shared.utils import ignore_docs, maybe_extract_enum_member_value
|
|
17
17
|
from crawlee import service_locator
|
|
18
18
|
from crawlee.events import (
|
|
19
19
|
Event,
|
|
@@ -39,7 +39,6 @@ from apify.storages import Dataset, KeyValueStore, RequestQueue
|
|
|
39
39
|
|
|
40
40
|
if TYPE_CHECKING:
|
|
41
41
|
import logging
|
|
42
|
-
from collections.abc import Callable
|
|
43
42
|
from types import TracebackType
|
|
44
43
|
|
|
45
44
|
from typing_extensions import Self
|
|
@@ -54,46 +53,9 @@ MainReturnType = TypeVar('MainReturnType')
|
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
@docs_name('Actor')
|
|
57
|
-
@docs_group('
|
|
56
|
+
@docs_group('Classes')
|
|
58
57
|
class _ActorType:
|
|
59
|
-
"""The
|
|
60
|
-
|
|
61
|
-
Actors are serverless programs running in the cloud that can perform anything from simple actions
|
|
62
|
-
(such as filling out a web form or sending an email) to complex operations (such as crawling an
|
|
63
|
-
entire website or removing duplicates from a large dataset). They are packaged as Docker containers
|
|
64
|
-
which accept well-defined JSON input, perform an action, and optionally produce well-defined output.
|
|
65
|
-
|
|
66
|
-
### References
|
|
67
|
-
|
|
68
|
-
- Apify platform documentation: https://docs.apify.com/platform/actors
|
|
69
|
-
- Actor whitepaper: https://whitepaper.actor/
|
|
70
|
-
|
|
71
|
-
### Usage
|
|
72
|
-
|
|
73
|
-
```python
|
|
74
|
-
import asyncio
|
|
75
|
-
|
|
76
|
-
import httpx
|
|
77
|
-
from apify import Actor
|
|
78
|
-
from bs4 import BeautifulSoup
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
async def main() -> None:
|
|
82
|
-
async with Actor:
|
|
83
|
-
actor_input = await Actor.get_input()
|
|
84
|
-
async with httpx.AsyncClient() as client:
|
|
85
|
-
response = await client.get(actor_input['url'])
|
|
86
|
-
soup = BeautifulSoup(response.content, 'html.parser')
|
|
87
|
-
data = {
|
|
88
|
-
'url': actor_input['url'],
|
|
89
|
-
'title': soup.title.string if soup.title else None,
|
|
90
|
-
}
|
|
91
|
-
await Actor.push_data(data)
|
|
92
|
-
|
|
93
|
-
if __name__ == '__main__':
|
|
94
|
-
asyncio.run(main())
|
|
95
|
-
```
|
|
96
|
-
"""
|
|
58
|
+
"""The class of `Actor`. Only make a new instance if you're absolutely sure you need to."""
|
|
97
59
|
|
|
98
60
|
_is_rebooting = False
|
|
99
61
|
_is_any_instance_initialized = False
|
|
@@ -145,6 +107,7 @@ class _ActorType:
|
|
|
145
107
|
|
|
146
108
|
self._is_initialized = False
|
|
147
109
|
|
|
110
|
+
@ignore_docs
|
|
148
111
|
async def __aenter__(self) -> Self:
|
|
149
112
|
"""Initialize the Actor.
|
|
150
113
|
|
|
@@ -156,6 +119,7 @@ class _ActorType:
|
|
|
156
119
|
await self.init()
|
|
157
120
|
return self
|
|
158
121
|
|
|
122
|
+
@ignore_docs
|
|
159
123
|
async def __aexit__(
|
|
160
124
|
self,
|
|
161
125
|
_exc_type: type[BaseException] | None,
|
|
@@ -4,10 +4,11 @@ import math
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from datetime import datetime, timezone
|
|
6
6
|
from decimal import Decimal
|
|
7
|
-
from typing import TYPE_CHECKING, Protocol
|
|
7
|
+
from typing import TYPE_CHECKING, Protocol, Union
|
|
8
8
|
|
|
9
9
|
from pydantic import TypeAdapter
|
|
10
10
|
|
|
11
|
+
from apify_shared.utils import ignore_docs
|
|
11
12
|
from crawlee._utils.context import ensure_context
|
|
12
13
|
|
|
13
14
|
from apify._models import ActorRun, PricingModel
|
|
@@ -22,21 +23,13 @@ if TYPE_CHECKING:
|
|
|
22
23
|
|
|
23
24
|
from apify._configuration import Configuration
|
|
24
25
|
|
|
25
|
-
run_validator = TypeAdapter[ActorRun | None](ActorRun | None)
|
|
26
26
|
|
|
27
|
+
run_validator: TypeAdapter[ActorRun | None] = TypeAdapter(Union[ActorRun, None])
|
|
27
28
|
|
|
28
|
-
@docs_group('Charging')
|
|
29
|
-
class ChargingManager(Protocol):
|
|
30
|
-
"""Provides fine-grained access to pay-per-event functionality.
|
|
31
|
-
|
|
32
|
-
The ChargingManager allows you to charge for specific events in your Actor when using
|
|
33
|
-
the pay-per-event pricing model. This enables precise cost control and transparent
|
|
34
|
-
billing for different operations within your Actor.
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
"""
|
|
30
|
+
@docs_group('Interfaces')
|
|
31
|
+
class ChargingManager(Protocol):
|
|
32
|
+
"""Provides fine-grained access to pay-per-event functionality."""
|
|
40
33
|
|
|
41
34
|
async def charge(self, event_name: str, count: int = 1) -> ChargeResult:
|
|
42
35
|
"""Charge for a specified number of events - sub-operations of the Actor.
|
|
@@ -65,7 +58,7 @@ class ChargingManager(Protocol):
|
|
|
65
58
|
"""
|
|
66
59
|
|
|
67
60
|
|
|
68
|
-
@docs_group('
|
|
61
|
+
@docs_group('Data structures')
|
|
69
62
|
@dataclass(frozen=True)
|
|
70
63
|
class ChargeResult:
|
|
71
64
|
"""Result of the `ChargingManager.charge` method."""
|
|
@@ -80,7 +73,7 @@ class ChargeResult:
|
|
|
80
73
|
"""How many events of each known type can still be charged within the limit."""
|
|
81
74
|
|
|
82
75
|
|
|
83
|
-
@docs_group('
|
|
76
|
+
@docs_group('Data structures')
|
|
84
77
|
@dataclass
|
|
85
78
|
class ActorPricingInfo:
|
|
86
79
|
"""Result of the `ChargingManager.get_pricing_info` method."""
|
|
@@ -98,6 +91,7 @@ class ActorPricingInfo:
|
|
|
98
91
|
"""Price of every known event type."""
|
|
99
92
|
|
|
100
93
|
|
|
94
|
+
@ignore_docs
|
|
101
95
|
class ChargingManagerImplementation(ChargingManager):
|
|
102
96
|
"""Implementation of the `ChargingManager` Protocol - this is only meant to be instantiated internally."""
|
|
103
97
|
|
|
@@ -25,7 +25,7 @@ def _transform_to_list(value: Any) -> list[str] | None:
|
|
|
25
25
|
return value if isinstance(value, list) else str(value).split(',')
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
@docs_group('
|
|
28
|
+
@docs_group('Classes')
|
|
29
29
|
class Configuration(CrawleeConfiguration):
|
|
30
30
|
"""A class for specifying the configuration of an Actor.
|
|
31
31
|
|
|
@@ -12,6 +12,7 @@ from cryptography.hazmat.primitives import hashes, serialization
|
|
|
12
12
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
|
13
13
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
14
14
|
|
|
15
|
+
from apify_shared.utils import ignore_docs
|
|
15
16
|
from crawlee._utils.crypto import crypto_random_object_id
|
|
16
17
|
|
|
17
18
|
from apify._consts import ENCRYPTED_INPUT_VALUE_REGEXP, ENCRYPTED_JSON_VALUE_PREFIX, ENCRYPTED_STRING_VALUE_PREFIX
|
|
@@ -21,6 +22,7 @@ ENCRYPTION_IV_LENGTH = 16
|
|
|
21
22
|
ENCRYPTION_AUTH_TAG_LENGTH = 16
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
@ignore_docs
|
|
24
26
|
def public_encrypt(value: str, *, public_key: rsa.RSAPublicKey) -> dict:
|
|
25
27
|
"""Encrypts the given value using AES cipher and the password for encryption using the public key.
|
|
26
28
|
|
|
@@ -64,6 +66,7 @@ def public_encrypt(value: str, *, public_key: rsa.RSAPublicKey) -> dict:
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
@ignore_docs
|
|
67
70
|
def private_decrypt(
|
|
68
71
|
encrypted_password: str,
|
|
69
72
|
encrypted_value: str,
|
|
@@ -115,6 +118,7 @@ def private_decrypt(
|
|
|
115
118
|
return decipher_bytes.decode('utf-8')
|
|
116
119
|
|
|
117
120
|
|
|
121
|
+
@ignore_docs
|
|
118
122
|
def load_private_key(private_key_file_base64: str, private_key_password: str) -> rsa.RSAPrivateKey:
|
|
119
123
|
private_key = serialization.load_pem_private_key(
|
|
120
124
|
base64.b64decode(private_key_file_base64.encode('utf-8')),
|
|
@@ -134,6 +138,7 @@ def _load_public_key(public_key_file_base64: str) -> rsa.RSAPublicKey:
|
|
|
134
138
|
return public_key
|
|
135
139
|
|
|
136
140
|
|
|
141
|
+
@ignore_docs
|
|
137
142
|
def decrypt_input_secrets(private_key: rsa.RSAPrivateKey, input_data: Any) -> Any:
|
|
138
143
|
"""Decrypt input secrets."""
|
|
139
144
|
if not isinstance(input_data, dict):
|
|
@@ -175,6 +180,7 @@ def encode_base62(num: int) -> str:
|
|
|
175
180
|
return res
|
|
176
181
|
|
|
177
182
|
|
|
183
|
+
@ignore_docs
|
|
178
184
|
def create_hmac_signature(secret_key: str, message: str) -> str:
|
|
179
185
|
"""Generate an HMAC signature and encodes it using Base62. Base62 encoding reduces the signature length.
|
|
180
186
|
|
|
@@ -13,10 +13,10 @@ from crawlee._utils.urls import validate_http_url
|
|
|
13
13
|
from apify._utils import docs_group
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
|
-
from
|
|
16
|
+
from typing_extensions import TypeAlias
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@docs_group('
|
|
19
|
+
@docs_group('Data structures')
|
|
20
20
|
class Webhook(BaseModel):
|
|
21
21
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
22
22
|
|
|
@@ -35,14 +35,14 @@ class Webhook(BaseModel):
|
|
|
35
35
|
] = None
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
@docs_group('
|
|
38
|
+
@docs_group('Data structures')
|
|
39
39
|
class ActorRunMeta(BaseModel):
|
|
40
40
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
41
41
|
|
|
42
42
|
origin: Annotated[MetaOrigin, Field()]
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
@docs_group('
|
|
45
|
+
@docs_group('Data structures')
|
|
46
46
|
class ActorRunStats(BaseModel):
|
|
47
47
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
48
48
|
|
|
@@ -63,7 +63,7 @@ class ActorRunStats(BaseModel):
|
|
|
63
63
|
compute_units: Annotated[float, Field(alias='computeUnits')]
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
@docs_group('
|
|
66
|
+
@docs_group('Data structures')
|
|
67
67
|
class ActorRunOptions(BaseModel):
|
|
68
68
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
69
69
|
|
|
@@ -74,7 +74,7 @@ class ActorRunOptions(BaseModel):
|
|
|
74
74
|
max_total_charge_usd: Annotated[Decimal | None, Field(alias='maxTotalChargeUsd')] = None
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
@docs_group('
|
|
77
|
+
@docs_group('Data structures')
|
|
78
78
|
class ActorRunUsage(BaseModel):
|
|
79
79
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
80
80
|
|
|
@@ -92,7 +92,7 @@ class ActorRunUsage(BaseModel):
|
|
|
92
92
|
proxy_serps: Annotated[float | None, Field(alias='PROXY_SERPS')] = None
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
@docs_group('
|
|
95
|
+
@docs_group('Data structures')
|
|
96
96
|
class ActorRun(BaseModel):
|
|
97
97
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
98
98
|
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from typing import TYPE_CHECKING, Annotated, Any, Literal
|
|
5
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal, Union
|
|
6
6
|
|
|
7
7
|
import websockets.asyncio.client
|
|
8
8
|
from pydantic import BaseModel, Discriminator, Field, TypeAdapter
|
|
@@ -27,10 +27,17 @@ if TYPE_CHECKING:
|
|
|
27
27
|
|
|
28
28
|
from apify._configuration import Configuration
|
|
29
29
|
|
|
30
|
+
|
|
30
31
|
__all__ = ['EventManager', 'LocalEventManager', 'PlatformEventManager']
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
@docs_group('
|
|
34
|
+
@docs_group('Data structures')
|
|
35
|
+
class PersistStateEvent(BaseModel):
|
|
36
|
+
name: Literal[Event.PERSIST_STATE]
|
|
37
|
+
data: Annotated[EventPersistStateData, Field(default_factory=lambda: EventPersistStateData(is_migrating=False))]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@docs_group('Data structures')
|
|
34
41
|
class SystemInfoEventData(BaseModel):
|
|
35
42
|
mem_avg_bytes: Annotated[float, Field(alias='memAvgBytes')]
|
|
36
43
|
mem_current_bytes: Annotated[float, Field(alias='memCurrentBytes')]
|
|
@@ -57,37 +64,31 @@ class SystemInfoEventData(BaseModel):
|
|
|
57
64
|
)
|
|
58
65
|
|
|
59
66
|
|
|
60
|
-
@docs_group('
|
|
61
|
-
class PersistStateEvent(BaseModel):
|
|
62
|
-
name: Literal[Event.PERSIST_STATE]
|
|
63
|
-
data: Annotated[EventPersistStateData, Field(default_factory=lambda: EventPersistStateData(is_migrating=False))]
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@docs_group('Events')
|
|
67
|
+
@docs_group('Data structures')
|
|
67
68
|
class SystemInfoEvent(BaseModel):
|
|
68
69
|
name: Literal[Event.SYSTEM_INFO]
|
|
69
70
|
data: SystemInfoEventData
|
|
70
71
|
|
|
71
72
|
|
|
72
|
-
@docs_group('
|
|
73
|
+
@docs_group('Data structures')
|
|
73
74
|
class MigratingEvent(BaseModel):
|
|
74
75
|
name: Literal[Event.MIGRATING]
|
|
75
76
|
data: Annotated[EventMigratingData, Field(default_factory=EventMigratingData)]
|
|
76
77
|
|
|
77
78
|
|
|
78
|
-
@docs_group('
|
|
79
|
+
@docs_group('Data structures')
|
|
79
80
|
class AbortingEvent(BaseModel):
|
|
80
81
|
name: Literal[Event.ABORTING]
|
|
81
82
|
data: Annotated[EventAbortingData, Field(default_factory=EventAbortingData)]
|
|
82
83
|
|
|
83
84
|
|
|
84
|
-
@docs_group('
|
|
85
|
+
@docs_group('Data structures')
|
|
85
86
|
class ExitEvent(BaseModel):
|
|
86
87
|
name: Literal[Event.EXIT]
|
|
87
88
|
data: Annotated[EventExitData, Field(default_factory=EventExitData)]
|
|
88
89
|
|
|
89
90
|
|
|
90
|
-
@docs_group('
|
|
91
|
+
@docs_group('Data structures')
|
|
91
92
|
class EventWithoutData(BaseModel):
|
|
92
93
|
name: Literal[
|
|
93
94
|
Event.SESSION_RETIRED,
|
|
@@ -100,26 +101,41 @@ class EventWithoutData(BaseModel):
|
|
|
100
101
|
data: Any = None
|
|
101
102
|
|
|
102
103
|
|
|
103
|
-
@docs_group('
|
|
104
|
+
@docs_group('Data structures')
|
|
104
105
|
class DeprecatedEvent(BaseModel):
|
|
105
106
|
name: Literal['cpuInfo']
|
|
106
107
|
data: Annotated[dict[str, Any], Field(default_factory=dict)]
|
|
107
108
|
|
|
108
109
|
|
|
109
|
-
@docs_group('
|
|
110
|
+
@docs_group('Data structures')
|
|
110
111
|
class UnknownEvent(BaseModel):
|
|
111
112
|
name: str
|
|
112
113
|
data: Annotated[dict[str, Any], Field(default_factory=dict)]
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
EventMessage =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
EventMessage = Union[
|
|
117
|
+
PersistStateEvent,
|
|
118
|
+
SystemInfoEvent,
|
|
119
|
+
MigratingEvent,
|
|
120
|
+
AbortingEvent,
|
|
121
|
+
ExitEvent,
|
|
122
|
+
EventWithoutData,
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
event_data_adapter: TypeAdapter[EventMessage | DeprecatedEvent | UnknownEvent] = TypeAdapter(
|
|
127
|
+
Union[
|
|
128
|
+
Annotated[
|
|
129
|
+
EventMessage,
|
|
130
|
+
Discriminator('name'),
|
|
131
|
+
],
|
|
132
|
+
DeprecatedEvent,
|
|
133
|
+
UnknownEvent,
|
|
134
|
+
]
|
|
119
135
|
)
|
|
120
136
|
|
|
121
137
|
|
|
122
|
-
@docs_group('
|
|
138
|
+
@docs_group('Classes')
|
|
123
139
|
class PlatformEventManager(EventManager):
|
|
124
140
|
"""A class for managing Actor events.
|
|
125
141
|
|