apify 2.7.1b4__tar.gz → 2.7.1b5__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.

Files changed (215) hide show
  1. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/pre_release.yaml +4 -0
  2. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/release.yaml +4 -0
  3. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/run_code_checks.yaml +1 -6
  4. {apify-2.7.1b4 → apify-2.7.1b5}/CHANGELOG.md +7 -0
  5. {apify-2.7.1b4 → apify-2.7.1b5}/PKG-INFO +1 -1
  6. {apify-2.7.1b4 → apify-2.7.1b5}/pyproject.toml +4 -2
  7. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/actor_source_base/Dockerfile +1 -1
  8. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/actor_source_base/requirements.txt +2 -0
  9. apify-2.7.1b5/tests/integration/actor_source_base/server.py +101 -0
  10. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_api_helpers.py +2 -2
  11. apify-2.7.1b5/tests/integration/test_crawlers_with_storages.py +111 -0
  12. {apify-2.7.1b4 → apify-2.7.1b5}/uv.lock +324 -101
  13. {apify-2.7.1b4 → apify-2.7.1b5}/website/docusaurus.config.js +4 -0
  14. {apify-2.7.1b4 → apify-2.7.1b5}/website/package-lock.json +17 -3
  15. {apify-2.7.1b4 → apify-2.7.1b5}/.editorconfig +0 -0
  16. {apify-2.7.1b4 → apify-2.7.1b5}/.github/CODEOWNERS +0 -0
  17. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/build_and_deploy_docs.yaml +0 -0
  18. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/check_pr_title.yaml +0 -0
  19. {apify-2.7.1b4 → apify-2.7.1b5}/.github/workflows/update_new_issue.yaml +0 -0
  20. {apify-2.7.1b4 → apify-2.7.1b5}/.gitignore +0 -0
  21. {apify-2.7.1b4 → apify-2.7.1b5}/.markdownlint.yaml +0 -0
  22. {apify-2.7.1b4 → apify-2.7.1b5}/.pre-commit-config.yaml +0 -0
  23. {apify-2.7.1b4 → apify-2.7.1b5}/CONTRIBUTING.md +0 -0
  24. {apify-2.7.1b4 → apify-2.7.1b5}/LICENSE +0 -0
  25. {apify-2.7.1b4 → apify-2.7.1b5}/Makefile +0 -0
  26. {apify-2.7.1b4 → apify-2.7.1b5}/README.md +0 -0
  27. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/01_introduction.mdx +0 -0
  28. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/02_running_actors_locally.mdx +0 -0
  29. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/03_actor_structure.mdx +0 -0
  30. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/code/01_introduction.py +0 -0
  31. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/code/actor_structure/__init__.py +0 -0
  32. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/code/actor_structure/__main__.py +0 -0
  33. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/code/actor_structure/main.py +0 -0
  34. {apify-2.7.1b4 → apify-2.7.1b5}/docs/01_overview/code/actor_structure/py.typed +0 -0
  35. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/01_beautifulsoup_httpx.mdx +0 -0
  36. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/02_crawlee.mdx +0 -0
  37. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/03_playwright.mdx +0 -0
  38. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/04_selenium.mdx +0 -0
  39. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/05_scrapy.mdx +0 -0
  40. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/01_beautifulsoup_httpx.py +0 -0
  41. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/02_crawlee_beautifulsoup.py +0 -0
  42. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/02_crawlee_playwright.py +0 -0
  43. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/03_playwright.py +0 -0
  44. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/04_selenium.py +0 -0
  45. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/__init__.py +0 -0
  46. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/__main__.py +0 -0
  47. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/items.py +0 -0
  48. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/main.py +0 -0
  49. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/py.typed +0 -0
  50. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/settings.py +0 -0
  51. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/spiders/__init__.py +0 -0
  52. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/spiders/py.typed +0 -0
  53. {apify-2.7.1b4 → apify-2.7.1b5}/docs/02_guides/code/scrapy_project/src/spiders/title.py +0 -0
  54. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/01_actor_lifecycle.mdx +0 -0
  55. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/02_actor_input.mdx +0 -0
  56. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/03_storages.mdx +0 -0
  57. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/04_actor_events.mdx +0 -0
  58. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/05_proxy_management.mdx +0 -0
  59. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/06_interacting_with_other_actors.mdx +0 -0
  60. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/07_webhooks.mdx +0 -0
  61. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/08_access_apify_api.mdx +0 -0
  62. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/09_running_webserver.mdx +0 -0
  63. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/10_logging.mdx +0 -0
  64. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/11_configuration.mdx +0 -0
  65. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/12_pay_per_event.mdx +0 -0
  66. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/01_context_manager.py +0 -0
  67. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/01_init_exit.py +0 -0
  68. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/01_reboot.py +0 -0
  69. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/01_status_message.py +0 -0
  70. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/02_input.py +0 -0
  71. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_dataset_exports.py +0 -0
  72. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_dataset_read_write.py +0 -0
  73. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_deleting_storages.py +0 -0
  74. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_kvs_iterating.py +0 -0
  75. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_kvs_public_url.py +0 -0
  76. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_kvs_read_write.py +0 -0
  77. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_opening_storages.py +0 -0
  78. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/03_rq.py +0 -0
  79. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/04_actor_events.py +0 -0
  80. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_apify_proxy.py +0 -0
  81. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_apify_proxy_config.py +0 -0
  82. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_custom_proxy.py +0 -0
  83. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_custom_proxy_function.py +0 -0
  84. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_proxy_actor_input.py +0 -0
  85. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_proxy_httpx.py +0 -0
  86. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/05_proxy_rotation.py +0 -0
  87. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/06_interacting_call.py +0 -0
  88. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/06_interacting_call_task.py +0 -0
  89. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/06_interacting_metamorph.py +0 -0
  90. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/06_interacting_start.py +0 -0
  91. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/07_webhook.py +0 -0
  92. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/07_webhook_preventing.py +0 -0
  93. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/08_actor_client.py +0 -0
  94. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/08_actor_new_client.py +0 -0
  95. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/09_webserver.py +0 -0
  96. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/10_log_config.py +0 -0
  97. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/10_logger_usage.py +0 -0
  98. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/10_redirect_log.py +0 -0
  99. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/10_redirect_log_existing_run.py +0 -0
  100. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/11_config.py +0 -0
  101. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/actor_charge.py +0 -0
  102. {apify-2.7.1b4 → apify-2.7.1b5}/docs/03_concepts/code/conditional_actor_charge.py +0 -0
  103. {apify-2.7.1b4 → apify-2.7.1b5}/docs/04_upgrading/upgrading_to_v2.md +0 -0
  104. {apify-2.7.1b4 → apify-2.7.1b5}/docs/pyproject.toml +0 -0
  105. {apify-2.7.1b4 → apify-2.7.1b5}/renovate.json +0 -0
  106. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/__init__.py +0 -0
  107. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_actor.py +0 -0
  108. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_charging.py +0 -0
  109. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_configuration.py +0 -0
  110. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_consts.py +0 -0
  111. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_crypto.py +0 -0
  112. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_models.py +0 -0
  113. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_platform_event_manager.py +0 -0
  114. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_proxy_configuration.py +0 -0
  115. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/_utils.py +0 -0
  116. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/__init__.py +0 -0
  117. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_apify_storage_client.py +0 -0
  118. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_dataset_client.py +0 -0
  119. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_dataset_collection_client.py +0 -0
  120. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_key_value_store_client.py +0 -0
  121. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_key_value_store_collection_client.py +0 -0
  122. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_request_queue_client.py +0 -0
  123. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/_request_queue_collection_client.py +0 -0
  124. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/apify_storage_client/py.typed +0 -0
  125. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/log.py +0 -0
  126. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/py.typed +0 -0
  127. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/__init__.py +0 -0
  128. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/_actor_runner.py +0 -0
  129. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/_async_thread.py +0 -0
  130. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/_logging_config.py +0 -0
  131. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/extensions/__init__.py +0 -0
  132. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/extensions/_httpcache.py +0 -0
  133. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/middlewares/__init__.py +0 -0
  134. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/middlewares/apify_proxy.py +0 -0
  135. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/middlewares/py.typed +0 -0
  136. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/pipelines/__init__.py +0 -0
  137. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/pipelines/actor_dataset_push.py +0 -0
  138. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/pipelines/py.typed +0 -0
  139. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/py.typed +0 -0
  140. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/requests.py +0 -0
  141. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/scheduler.py +0 -0
  142. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/scrapy/utils.py +0 -0
  143. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/storages/__init__.py +0 -0
  144. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/storages/_request_list.py +0 -0
  145. {apify-2.7.1b4 → apify-2.7.1b5}/src/apify/storages/py.typed +0 -0
  146. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/README.md +0 -0
  147. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/__init__.py +0 -0
  148. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/_utils.py +0 -0
  149. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/actor_source_base/src/__init__.py +0 -0
  150. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/actor_source_base/src/__main__.py +0 -0
  151. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/actor_source_base/src/main.py +0 -0
  152. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/conftest.py +0 -0
  153. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_call_timeouts.py +0 -0
  154. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_charge.py +0 -0
  155. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_create_proxy_configuration.py +0 -0
  156. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_dataset.py +0 -0
  157. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_events.py +0 -0
  158. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_key_value_store.py +0 -0
  159. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_lifecycle.py +0 -0
  160. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_log.py +0 -0
  161. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_request_queue.py +0 -0
  162. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_actor_scrapy.py +0 -0
  163. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_fixtures.py +0 -0
  164. {apify-2.7.1b4 → apify-2.7.1b5}/tests/integration/test_request_queue.py +0 -0
  165. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/__init__.py +0 -0
  166. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/__init__.py +0 -0
  167. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_create_proxy_configuration.py +0 -0
  168. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_dataset.py +0 -0
  169. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_env_helpers.py +0 -0
  170. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_helpers.py +0 -0
  171. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_key_value_store.py +0 -0
  172. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_lifecycle.py +0 -0
  173. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_log.py +0 -0
  174. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_non_default_instance.py +0 -0
  175. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_actor_request_queue.py +0 -0
  176. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_configuration.py +0 -0
  177. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/actor/test_request_list.py +0 -0
  178. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/conftest.py +0 -0
  179. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/__init__.py +0 -0
  180. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/extensions/__init__.py +0 -0
  181. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/extensions/test_httpcache.py +0 -0
  182. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/middlewares/__init__.py +0 -0
  183. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/middlewares/test_apify_proxy.py +0 -0
  184. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/pipelines/__init__.py +0 -0
  185. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/pipelines/test_actor_dataset_push.py +0 -0
  186. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/requests/__init__.py +0 -0
  187. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/requests/test_to_apify_request.py +0 -0
  188. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/requests/test_to_scrapy_request.py +0 -0
  189. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/utils/__init__.py +0 -0
  190. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/utils/test_apply_apify_settings.py +0 -0
  191. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/scrapy/utils/test_get_basic_auth_header.py +0 -0
  192. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/test_crypto.py +0 -0
  193. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/test_platform_event_manager.py +0 -0
  194. {apify-2.7.1b4 → apify-2.7.1b5}/tests/unit/test_proxy_configuration.py +0 -0
  195. {apify-2.7.1b4 → apify-2.7.1b5}/website/.eslintrc.json +0 -0
  196. {apify-2.7.1b4 → apify-2.7.1b5}/website/babel.config.js +0 -0
  197. {apify-2.7.1b4 → apify-2.7.1b5}/website/build_api_reference.sh +0 -0
  198. {apify-2.7.1b4 → apify-2.7.1b5}/website/generate_module_shortcuts.py +0 -0
  199. {apify-2.7.1b4 → apify-2.7.1b5}/website/package.json +0 -0
  200. {apify-2.7.1b4 → apify-2.7.1b5}/website/sidebars.js +0 -0
  201. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/ApiLink.jsx +0 -0
  202. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/Gradients.jsx +0 -0
  203. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/Highlights.jsx +0 -0
  204. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/Highlights.module.css +0 -0
  205. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/RunnableCodeBlock.jsx +0 -0
  206. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/components/RunnableCodeBlock.module.css +0 -0
  207. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/css/custom.css +0 -0
  208. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/pages/home_page_example.py +0 -0
  209. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/pages/index.js +0 -0
  210. {apify-2.7.1b4 → apify-2.7.1b5}/website/src/pages/index.module.css +0 -0
  211. {apify-2.7.1b4 → apify-2.7.1b5}/website/static/.nojekyll +0 -0
  212. {apify-2.7.1b4 → apify-2.7.1b5}/website/static/img/docs-og.png +0 -0
  213. {apify-2.7.1b4 → apify-2.7.1b5}/website/static/img/guides/redirected_logs_example.webp +0 -0
  214. {apify-2.7.1b4 → apify-2.7.1b5}/website/tools/docs-prettier.config.js +0 -0
  215. {apify-2.7.1b4 → apify-2.7.1b5}/website/tools/utils/externalLink.js +0 -0
@@ -11,6 +11,10 @@ on:
11
11
  # Or it can be triggered manually.
12
12
  workflow_dispatch:
13
13
 
14
+ concurrency:
15
+ group: release
16
+ cancel-in-progress: false
17
+
14
18
  jobs:
15
19
  release_metadata:
16
20
  if: "!startsWith(github.event.head_commit.message, 'docs') && !startsWith(github.event.head_commit.message, 'ci') && startsWith(github.repository, 'apify/')"
@@ -21,6 +21,10 @@ on:
21
21
  type: string
22
22
  default: ""
23
23
 
24
+ concurrency:
25
+ group: release
26
+ cancel-in-progress: false
27
+
24
28
  jobs:
25
29
  release_metadata:
26
30
  name: Prepare release metadata
@@ -6,12 +6,7 @@ on:
6
6
  # step required for PRs from forks. This prevents their potential exposure.
7
7
  pull_request:
8
8
 
9
- # Pushing to the master branch triggers code checks
10
- push:
11
- branches:
12
- - master
13
- tags-ignore:
14
- - "**" # Ignore all tags to prevent duplicate checks when tags are pushed.
9
+ # Trigger for pushing to the master branch is handled by the pre-release workflow.
15
10
 
16
11
  # It should also be possible to trigger checks manually
17
12
  workflow_dispatch:
@@ -23,6 +23,13 @@ All notable changes to this project will be documented in this file.
23
23
  - 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)
24
24
 
25
25
 
26
+ ## [2.7.2](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.2) (2025-07-30)
27
+
28
+ ### 🐛 Bug Fixes
29
+
30
+ - Restrict apify-shared and apify-client versions ([#523](https://github.com/apify/apify-sdk-python/pull/523)) ([581ebae](https://github.com/apify/apify-sdk-python/commit/581ebae5752a984a34cbabc02c49945ae392db00)) by [@vdusek](https://github.com/vdusek)
31
+
32
+
26
33
  ## [2.7.1](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.1) (2025-07-24)
27
34
 
28
35
  ### 🐛 Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify
3
- Version: 2.7.1b4
3
+ Version: 2.7.1b5
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "apify"
7
- version = "2.7.1b4"
7
+ version = "2.7.1b5"
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" }
@@ -62,7 +62,8 @@ scrapy = ["scrapy>=2.11.0"]
62
62
 
63
63
  [dependency-groups]
64
64
  dev = [
65
- "build~=1.2.0",
65
+ "build~=1.3.0",
66
+ "crawlee[parsel]",
66
67
  "dycw-pytest-only>=2.1.1",
67
68
  "griffe~=1.9.0",
68
69
  "mypy~=1.17.0",
@@ -76,6 +77,7 @@ dev = [
76
77
  "respx~=0.22.0",
77
78
  "ruff~=0.12.0",
78
79
  "setuptools", # setuptools are used by pytest but not explicitly required
80
+ "uvicorn[standard]",
79
81
  ]
80
82
 
81
83
  [tool.hatch.build.targets.wheel]
@@ -12,4 +12,4 @@ RUN echo "Python version:" \
12
12
  && echo "All installed Python packages:" \
13
13
  && pip freeze
14
14
 
15
- CMD ["python3", "-m", "src"]
15
+ CMD ["sh", "-c", "python server.py & python -m src"]
@@ -1,2 +1,4 @@
1
1
  # The test fixture will put the Apify SDK wheel path on the next line
2
2
  APIFY_SDK_WHEEL_PLACEHOLDER
3
+ uvicorn[standard]
4
+ crawlee[parsel]
@@ -0,0 +1,101 @@
1
+ """
2
+ Test server is infinite server http://localhost:8080/{any_number} and each page has links to the next 10 pages.
3
+ For example:
4
+ http://localhost:8080/ contains links:
5
+ http://localhost:8080/0, http://localhost:8080/1, ..., http://localhost:8080/9
6
+
7
+ http://localhost:8080/1 contains links:
8
+ http://localhost:8080/10, http://localhost:8080/11, ..., http://localhost:8080/19
9
+
10
+ ... and so on.
11
+ """
12
+
13
+ import asyncio
14
+ import logging
15
+ from collections.abc import Awaitable, Callable, Coroutine
16
+ from socket import socket
17
+ from typing import Any
18
+
19
+ from uvicorn import Config
20
+ from uvicorn.server import Server
21
+ from yarl import URL
22
+
23
+ Receive = Callable[[], Awaitable[dict[str, Any]]]
24
+ Send = Callable[[dict[str, Any]], Coroutine[None, None, None]]
25
+
26
+
27
+ async def send_html_response(send: Send, html_content: bytes, status: int = 200) -> None:
28
+ """Send an HTML response to the client."""
29
+ await send(
30
+ {
31
+ 'type': 'http.response.start',
32
+ 'status': status,
33
+ 'headers': [[b'content-type', b'text/html; charset=utf-8']],
34
+ }
35
+ )
36
+ await send({'type': 'http.response.body', 'body': html_content})
37
+
38
+
39
+ async def app(scope: dict[str, Any], _: Receive, send: Send) -> None:
40
+ """Main ASGI application handler that routes requests to specific handlers.
41
+
42
+ Args:
43
+ scope: The ASGI connection scope.
44
+ _: The ASGI receive function.
45
+ send: The ASGI send function.
46
+ """
47
+ assert scope['type'] == 'http'
48
+ path = scope['path']
49
+
50
+ links = '\n'.join(f'<a href="{path}{i}">{path}{i}</a>' for i in range(10))
51
+ await send_html_response(
52
+ send,
53
+ f"""\
54
+ <html><head>
55
+ <title>Title for {path} </title>
56
+ </head>
57
+ <body>
58
+ {links}
59
+ </body></html>""".encode(),
60
+ )
61
+
62
+
63
+ class TestServer(Server):
64
+ """A test HTTP server implementation based on Uvicorn Server."""
65
+
66
+ @property
67
+ def url(self) -> URL:
68
+ """Get the base URL of the server.
69
+
70
+ Returns:
71
+ A URL instance with the server's base URL.
72
+ """
73
+ protocol = 'https' if self.config.is_ssl else 'http'
74
+ return URL(f'{protocol}://{self.config.host}:{self.config.port}/')
75
+
76
+ async def serve(self, sockets: list[socket] | None = None) -> None:
77
+ """Run the server."""
78
+ if sockets:
79
+ raise RuntimeError('Simple TestServer does not support custom sockets')
80
+ self.restart_requested = asyncio.Event()
81
+
82
+ loop = asyncio.get_event_loop()
83
+ tasks = {
84
+ loop.create_task(super().serve()),
85
+ }
86
+ await asyncio.wait(tasks)
87
+
88
+
89
+ if __name__ == '__main__':
90
+ asyncio.run(
91
+ TestServer(
92
+ config=Config(
93
+ app=app,
94
+ lifespan='off',
95
+ loop='asyncio',
96
+ port=8080,
97
+ log_config=None,
98
+ log_level=logging.CRITICAL,
99
+ )
100
+ ).serve()
101
+ )
@@ -400,12 +400,12 @@ async def test_actor_adds_webhook_and_receives_event(
400
400
  async with Actor:
401
401
 
402
402
  class WebhookHandler(BaseHTTPRequestHandler):
403
- def do_GET(self) -> None: # noqa: N802
403
+ def do_GET(self) -> None:
404
404
  self.send_response(200)
405
405
  self.end_headers()
406
406
  self.wfile.write(bytes('Hello, world!', encoding='utf-8'))
407
407
 
408
- def do_POST(self) -> None: # noqa: N802
408
+ def do_POST(self) -> None:
409
409
  nonlocal webhook_body
410
410
  content_length = self.headers.get('content-length')
411
411
  length = int(content_length) if content_length else 0
@@ -0,0 +1,111 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from .conftest import MakeActorFunction, RunActorFunction
7
+
8
+
9
+ async def test_actor_on_platform_max_crawl_depth(
10
+ make_actor: MakeActorFunction,
11
+ run_actor: RunActorFunction,
12
+ ) -> None:
13
+ """Test that the actor respects max_crawl_depth."""
14
+
15
+ async def main() -> None:
16
+ """The crawler entry point."""
17
+ import re
18
+
19
+ from crawlee.crawlers import ParselCrawler, ParselCrawlingContext
20
+
21
+ from apify import Actor
22
+
23
+ async with Actor:
24
+ crawler = ParselCrawler(max_crawl_depth=2)
25
+ finished = []
26
+ enqueue_pattern = re.compile(r'http://localhost:8080/2+$')
27
+
28
+ @crawler.router.default_handler
29
+ async def default_handler(context: ParselCrawlingContext) -> None:
30
+ """Default request handler."""
31
+ context.log.info(f'Processing {context.request.url} ...')
32
+ await context.enqueue_links(include=[enqueue_pattern])
33
+ finished.append(context.request.url)
34
+
35
+ await crawler.run(['http://localhost:8080/'])
36
+ assert finished == ['http://localhost:8080/', 'http://localhost:8080/2', 'http://localhost:8080/22']
37
+
38
+ actor = await make_actor(label='crawler-max-depth', main_func=main)
39
+ run_result = await run_actor(actor)
40
+
41
+ assert run_result.status == 'SUCCEEDED'
42
+
43
+
44
+ async def test_actor_on_platform_max_requests_per_crawl(
45
+ make_actor: MakeActorFunction,
46
+ run_actor: RunActorFunction,
47
+ ) -> None:
48
+ """Test that the actor respects max_requests_per_crawl."""
49
+
50
+ async def main() -> None:
51
+ """The crawler entry point."""
52
+ from crawlee import ConcurrencySettings
53
+ from crawlee.crawlers import ParselCrawler, ParselCrawlingContext
54
+
55
+ from apify import Actor
56
+
57
+ async with Actor:
58
+ crawler = ParselCrawler(
59
+ max_requests_per_crawl=3, concurrency_settings=ConcurrencySettings(max_concurrency=1)
60
+ )
61
+ finished = []
62
+
63
+ @crawler.router.default_handler
64
+ async def default_handler(context: ParselCrawlingContext) -> None:
65
+ """Default request handler."""
66
+ context.log.info(f'Processing {context.request.url} ...')
67
+ await context.enqueue_links()
68
+ finished.append(context.request.url)
69
+
70
+ await crawler.run(['http://localhost:8080/'])
71
+ assert len(finished) == 3
72
+
73
+ actor = await make_actor(label='crawler-max-requests', main_func=main)
74
+ run_result = await run_actor(actor)
75
+
76
+ assert run_result.status == 'SUCCEEDED'
77
+
78
+
79
+ async def test_actor_on_platform_max_request_retries(
80
+ make_actor: MakeActorFunction,
81
+ run_actor: RunActorFunction,
82
+ ) -> None:
83
+ """Test that the actor respects max_request_retries."""
84
+
85
+ async def main() -> None:
86
+ """The crawler entry point."""
87
+ from crawlee.crawlers import BasicCrawlingContext, ParselCrawler, ParselCrawlingContext
88
+
89
+ from apify import Actor
90
+
91
+ async with Actor:
92
+ max_retries = 3
93
+ crawler = ParselCrawler(max_request_retries=max_retries)
94
+ failed_counter = 0
95
+
96
+ @crawler.error_handler
97
+ async def error_handler(_: BasicCrawlingContext, __: Exception) -> None:
98
+ nonlocal failed_counter
99
+ failed_counter += 1
100
+
101
+ @crawler.router.default_handler
102
+ async def default_handler(_: ParselCrawlingContext) -> None:
103
+ raise RuntimeError('Some error')
104
+
105
+ await crawler.run(['http://localhost:8080/'])
106
+ assert failed_counter == max_retries, f'{failed_counter=}'
107
+
108
+ actor = await make_actor(label='crawler-max-retries', main_func=main)
109
+ run_result = await run_actor(actor)
110
+
111
+ assert run_result.status == 'SUCCEEDED'