apify 2.7.1b6__tar.gz → 2.7.1b7__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 (216) hide show
  1. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/build_and_deploy_docs.yaml +1 -1
  2. {apify-2.7.1b6 → apify-2.7.1b7}/CHANGELOG.md +3 -7
  3. {apify-2.7.1b6 → apify-2.7.1b7}/PKG-INFO +1 -1
  4. {apify-2.7.1b6 → apify-2.7.1b7}/pyproject.toml +6 -4
  5. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_configuration.py +9 -0
  6. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_crawlers_with_storages.py +3 -0
  7. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_create_proxy_configuration.py +37 -28
  8. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_request_list.py +35 -22
  9. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/conftest.py +38 -1
  10. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/test_proxy_configuration.py +72 -68
  11. {apify-2.7.1b6 → apify-2.7.1b7}/uv.lock +204 -182
  12. {apify-2.7.1b6 → apify-2.7.1b7}/website/docusaurus.config.js +14 -2
  13. {apify-2.7.1b6 → apify-2.7.1b7}/website/package-lock.json +338 -3
  14. {apify-2.7.1b6 → apify-2.7.1b7}/website/package.json +1 -0
  15. apify-2.7.1b7/website/src/components/RunnableCodeBlock.jsx +46 -0
  16. apify-2.7.1b6/website/src/components/RunnableCodeBlock.jsx +0 -44
  17. {apify-2.7.1b6 → apify-2.7.1b7}/.editorconfig +0 -0
  18. {apify-2.7.1b6 → apify-2.7.1b7}/.github/CODEOWNERS +0 -0
  19. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/check_pr_title.yaml +0 -0
  20. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/pre_release.yaml +0 -0
  21. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/release.yaml +0 -0
  22. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/run_code_checks.yaml +0 -0
  23. {apify-2.7.1b6 → apify-2.7.1b7}/.github/workflows/update_new_issue.yaml +0 -0
  24. {apify-2.7.1b6 → apify-2.7.1b7}/.gitignore +0 -0
  25. {apify-2.7.1b6 → apify-2.7.1b7}/.markdownlint.yaml +0 -0
  26. {apify-2.7.1b6 → apify-2.7.1b7}/.pre-commit-config.yaml +0 -0
  27. {apify-2.7.1b6 → apify-2.7.1b7}/CONTRIBUTING.md +0 -0
  28. {apify-2.7.1b6 → apify-2.7.1b7}/LICENSE +0 -0
  29. {apify-2.7.1b6 → apify-2.7.1b7}/Makefile +0 -0
  30. {apify-2.7.1b6 → apify-2.7.1b7}/README.md +0 -0
  31. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/01_introduction.mdx +0 -0
  32. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/02_running_actors_locally.mdx +0 -0
  33. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/03_actor_structure.mdx +0 -0
  34. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/code/01_introduction.py +0 -0
  35. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/code/actor_structure/__init__.py +0 -0
  36. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/code/actor_structure/__main__.py +0 -0
  37. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/code/actor_structure/main.py +0 -0
  38. {apify-2.7.1b6 → apify-2.7.1b7}/docs/01_overview/code/actor_structure/py.typed +0 -0
  39. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/01_beautifulsoup_httpx.mdx +0 -0
  40. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/02_crawlee.mdx +0 -0
  41. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/03_playwright.mdx +0 -0
  42. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/04_selenium.mdx +0 -0
  43. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/05_scrapy.mdx +0 -0
  44. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/01_beautifulsoup_httpx.py +0 -0
  45. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/02_crawlee_beautifulsoup.py +0 -0
  46. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/02_crawlee_playwright.py +0 -0
  47. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/03_playwright.py +0 -0
  48. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/04_selenium.py +0 -0
  49. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/__init__.py +0 -0
  50. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/__main__.py +0 -0
  51. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/items.py +0 -0
  52. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/main.py +0 -0
  53. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/py.typed +0 -0
  54. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/settings.py +0 -0
  55. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/spiders/__init__.py +0 -0
  56. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/spiders/py.typed +0 -0
  57. {apify-2.7.1b6 → apify-2.7.1b7}/docs/02_guides/code/scrapy_project/src/spiders/title.py +0 -0
  58. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/01_actor_lifecycle.mdx +0 -0
  59. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/02_actor_input.mdx +0 -0
  60. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/03_storages.mdx +0 -0
  61. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/04_actor_events.mdx +0 -0
  62. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/05_proxy_management.mdx +0 -0
  63. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/06_interacting_with_other_actors.mdx +0 -0
  64. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/07_webhooks.mdx +0 -0
  65. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/08_access_apify_api.mdx +0 -0
  66. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/09_running_webserver.mdx +0 -0
  67. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/10_logging.mdx +0 -0
  68. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/11_configuration.mdx +0 -0
  69. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/12_pay_per_event.mdx +0 -0
  70. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/01_context_manager.py +0 -0
  71. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/01_init_exit.py +0 -0
  72. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/01_reboot.py +0 -0
  73. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/01_status_message.py +0 -0
  74. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/02_input.py +0 -0
  75. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_dataset_exports.py +0 -0
  76. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_dataset_read_write.py +0 -0
  77. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_deleting_storages.py +0 -0
  78. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_kvs_iterating.py +0 -0
  79. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_kvs_public_url.py +0 -0
  80. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_kvs_read_write.py +0 -0
  81. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_opening_storages.py +0 -0
  82. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/03_rq.py +0 -0
  83. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/04_actor_events.py +0 -0
  84. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_apify_proxy.py +0 -0
  85. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_apify_proxy_config.py +0 -0
  86. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_custom_proxy.py +0 -0
  87. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_custom_proxy_function.py +0 -0
  88. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_proxy_actor_input.py +0 -0
  89. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_proxy_httpx.py +0 -0
  90. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/05_proxy_rotation.py +0 -0
  91. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/06_interacting_call.py +0 -0
  92. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/06_interacting_call_task.py +0 -0
  93. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/06_interacting_metamorph.py +0 -0
  94. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/06_interacting_start.py +0 -0
  95. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/07_webhook.py +0 -0
  96. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/07_webhook_preventing.py +0 -0
  97. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/08_actor_client.py +0 -0
  98. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/08_actor_new_client.py +0 -0
  99. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/09_webserver.py +0 -0
  100. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/10_log_config.py +0 -0
  101. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/10_logger_usage.py +0 -0
  102. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/10_redirect_log.py +0 -0
  103. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/10_redirect_log_existing_run.py +0 -0
  104. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/11_config.py +0 -0
  105. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/actor_charge.py +0 -0
  106. {apify-2.7.1b6 → apify-2.7.1b7}/docs/03_concepts/code/conditional_actor_charge.py +0 -0
  107. {apify-2.7.1b6 → apify-2.7.1b7}/docs/04_upgrading/upgrading_to_v2.md +0 -0
  108. {apify-2.7.1b6 → apify-2.7.1b7}/docs/pyproject.toml +0 -0
  109. {apify-2.7.1b6 → apify-2.7.1b7}/renovate.json +0 -0
  110. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/__init__.py +0 -0
  111. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_actor.py +0 -0
  112. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_charging.py +0 -0
  113. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_consts.py +0 -0
  114. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_crypto.py +0 -0
  115. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_models.py +0 -0
  116. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_platform_event_manager.py +0 -0
  117. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_proxy_configuration.py +0 -0
  118. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/_utils.py +0 -0
  119. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/__init__.py +0 -0
  120. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_apify_storage_client.py +0 -0
  121. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_dataset_client.py +0 -0
  122. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_dataset_collection_client.py +0 -0
  123. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_key_value_store_client.py +0 -0
  124. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_key_value_store_collection_client.py +0 -0
  125. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_request_queue_client.py +0 -0
  126. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/_request_queue_collection_client.py +0 -0
  127. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/apify_storage_client/py.typed +0 -0
  128. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/log.py +0 -0
  129. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/py.typed +0 -0
  130. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/__init__.py +0 -0
  131. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/_actor_runner.py +0 -0
  132. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/_async_thread.py +0 -0
  133. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/_logging_config.py +0 -0
  134. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/extensions/__init__.py +0 -0
  135. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/extensions/_httpcache.py +0 -0
  136. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/middlewares/__init__.py +0 -0
  137. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/middlewares/apify_proxy.py +0 -0
  138. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/middlewares/py.typed +0 -0
  139. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/pipelines/__init__.py +0 -0
  140. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/pipelines/actor_dataset_push.py +0 -0
  141. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/pipelines/py.typed +0 -0
  142. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/py.typed +0 -0
  143. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/requests.py +0 -0
  144. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/scheduler.py +0 -0
  145. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/scrapy/utils.py +0 -0
  146. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/storages/__init__.py +0 -0
  147. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/storages/_request_list.py +0 -0
  148. {apify-2.7.1b6 → apify-2.7.1b7}/src/apify/storages/py.typed +0 -0
  149. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/README.md +0 -0
  150. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/__init__.py +0 -0
  151. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/_utils.py +0 -0
  152. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/Dockerfile +0 -0
  153. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/requirements.txt +0 -0
  154. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/server.py +0 -0
  155. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/src/__init__.py +0 -0
  156. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/src/__main__.py +0 -0
  157. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/actor_source_base/src/main.py +0 -0
  158. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/conftest.py +0 -0
  159. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_api_helpers.py +0 -0
  160. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_call_timeouts.py +0 -0
  161. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_charge.py +0 -0
  162. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_create_proxy_configuration.py +0 -0
  163. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_dataset.py +0 -0
  164. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_events.py +0 -0
  165. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_key_value_store.py +0 -0
  166. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_lifecycle.py +0 -0
  167. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_log.py +0 -0
  168. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_request_queue.py +0 -0
  169. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_actor_scrapy.py +0 -0
  170. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_fixtures.py +0 -0
  171. {apify-2.7.1b6 → apify-2.7.1b7}/tests/integration/test_request_queue.py +0 -0
  172. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/__init__.py +0 -0
  173. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/__init__.py +0 -0
  174. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_dataset.py +0 -0
  175. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_env_helpers.py +0 -0
  176. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_helpers.py +0 -0
  177. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_key_value_store.py +0 -0
  178. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_lifecycle.py +0 -0
  179. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_log.py +0 -0
  180. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_non_default_instance.py +0 -0
  181. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_actor_request_queue.py +0 -0
  182. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/actor/test_configuration.py +0 -0
  183. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/__init__.py +0 -0
  184. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/extensions/__init__.py +0 -0
  185. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/extensions/test_httpcache.py +0 -0
  186. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/middlewares/__init__.py +0 -0
  187. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/middlewares/test_apify_proxy.py +0 -0
  188. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/pipelines/__init__.py +0 -0
  189. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/pipelines/test_actor_dataset_push.py +0 -0
  190. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/requests/__init__.py +0 -0
  191. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/requests/test_to_apify_request.py +0 -0
  192. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/requests/test_to_scrapy_request.py +0 -0
  193. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/utils/__init__.py +0 -0
  194. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/utils/test_apply_apify_settings.py +0 -0
  195. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/scrapy/utils/test_get_basic_auth_header.py +0 -0
  196. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/test_crypto.py +0 -0
  197. {apify-2.7.1b6 → apify-2.7.1b7}/tests/unit/test_platform_event_manager.py +0 -0
  198. {apify-2.7.1b6 → apify-2.7.1b7}/website/.eslintrc.json +0 -0
  199. {apify-2.7.1b6 → apify-2.7.1b7}/website/babel.config.js +0 -0
  200. {apify-2.7.1b6 → apify-2.7.1b7}/website/build_api_reference.sh +0 -0
  201. {apify-2.7.1b6 → apify-2.7.1b7}/website/generate_module_shortcuts.py +0 -0
  202. {apify-2.7.1b6 → apify-2.7.1b7}/website/sidebars.js +0 -0
  203. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/components/ApiLink.jsx +0 -0
  204. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/components/Gradients.jsx +0 -0
  205. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/components/Highlights.jsx +0 -0
  206. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/components/Highlights.module.css +0 -0
  207. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/components/RunnableCodeBlock.module.css +0 -0
  208. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/css/custom.css +0 -0
  209. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/pages/home_page_example.py +0 -0
  210. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/pages/index.js +0 -0
  211. {apify-2.7.1b6 → apify-2.7.1b7}/website/src/pages/index.module.css +0 -0
  212. {apify-2.7.1b6 → apify-2.7.1b7}/website/static/.nojekyll +0 -0
  213. {apify-2.7.1b6 → apify-2.7.1b7}/website/static/img/docs-og.png +0 -0
  214. {apify-2.7.1b6 → apify-2.7.1b7}/website/static/img/guides/redirected_logs_example.webp +0 -0
  215. {apify-2.7.1b6 → apify-2.7.1b7}/website/tools/docs-prettier.config.js +0 -0
  216. {apify-2.7.1b6 → apify-2.7.1b7}/website/tools/utils/externalLink.js +0 -0
@@ -22,7 +22,7 @@ jobs:
22
22
 
23
23
  steps:
24
24
  - name: Checkout repository
25
- uses: actions/checkout@v4
25
+ uses: actions/checkout@v5
26
26
  with:
27
27
  token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
28
28
 
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
8
8
  ### 🐛 Bug Fixes
9
9
 
10
10
  - Restrict apify-shared and apify-client versions ([#523](https://github.com/apify/apify-sdk-python/pull/523)) ([b3ae5a9](https://github.com/apify/apify-sdk-python/commit/b3ae5a972a65454a4998eda59c9fcc3f6b7e8579)) by [@vdusek](https://github.com/vdusek)
11
+ - Expose `APIFY_USER_IS_PAYING` env var to the configuration ([#507](https://github.com/apify/apify-sdk-python/pull/507)) ([0801e54](https://github.com/apify/apify-sdk-python/commit/0801e54887317c1280cc6828ecd3f2cc53287e76)) by [@stepskop](https://github.com/stepskop)
11
12
 
12
13
 
13
14
  <!-- git-cliff-unreleased-end -->
@@ -23,16 +24,11 @@ All notable changes to this project will be documented in this file.
23
24
  - 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
25
 
25
26
 
26
- ## [2.7.0](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.0) (2025-07-14)
27
-
28
- ### 🚀 Features
29
-
30
- - **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)
27
+ ## [2.7.3](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.3) (2025-08-11)
31
28
 
32
29
  ### 🐛 Bug Fixes
33
30
 
34
- - 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)
35
- - 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)
31
+ - Expose `APIFY_USER_IS_PAYING` env var to the configuration (#507) ([0de022c](https://github.com/apify/apify-sdk-python/commit/0de022c3435f24c821053c771e7b659433e3fb6e))
36
32
 
37
33
 
38
34
  ## [2.7.2](https://github.com/apify/apify-sdk-python/releases/tag/v2.7.2) (2025-07-30)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify
3
- Version: 2.7.1b6
3
+ Version: 2.7.1b7
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.1b6"
7
+ version = "2.7.1b7"
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" }
@@ -65,19 +65,21 @@ dev = [
65
65
  "build~=1.3.0",
66
66
  "crawlee[parsel]",
67
67
  "dycw-pytest-only>=2.1.1",
68
- "griffe~=1.9.0",
68
+ "griffe~=1.11.0",
69
69
  "mypy~=1.17.0",
70
- "pre-commit~=4.2.0",
70
+ "pre-commit~=4.3.0",
71
71
  "pydoc-markdown~=4.8.0",
72
72
  "pytest-asyncio~=1.1.0",
73
73
  "pytest-cov~=6.2.0",
74
+ "pytest-httpserver>=1.1.3",
74
75
  "pytest-timeout>=2.4.0",
75
76
  "pytest-xdist~=3.8.0",
76
77
  "pytest~=8.4.0",
77
- "respx~=0.22.0",
78
78
  "ruff~=0.12.0",
79
79
  "setuptools", # setuptools are used by pytest but not explicitly required
80
80
  "uvicorn[standard]",
81
+ "werkzeug~=3.1.3", # Werkzeug is used by httpserver
82
+ "yarl~=1.20.0", # yarl is used by crawlee
81
83
  ]
82
84
 
83
85
  [tool.hatch.build.targets.wheel]
@@ -334,6 +334,15 @@ class Configuration(CrawleeConfiguration):
334
334
  ),
335
335
  ] = None
336
336
 
337
+ user_is_paying: Annotated[
338
+ bool,
339
+ Field(
340
+ alias='apify_user_is_paying',
341
+ description='True if the user calling the Actor is paying user',
342
+ ),
343
+ BeforeValidator(lambda val: False if val == '' else val),
344
+ ] = False
345
+
337
346
  web_server_port: Annotated[
338
347
  int,
339
348
  Field(
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
+ import pytest
6
+
5
7
  if TYPE_CHECKING:
6
8
  from .conftest import MakeActorFunction, RunActorFunction
7
9
 
@@ -76,6 +78,7 @@ async def test_actor_on_platform_max_requests_per_crawl(
76
78
  assert run_result.status == 'SUCCEEDED'
77
79
 
78
80
 
81
+ @pytest.mark.skip(reason='Sometimes crawler does not respect max_request_retries argument, see issue #540')
79
82
  async def test_actor_on_platform_max_request_retries(
80
83
  make_actor: MakeActorFunction,
81
84
  run_actor: RunActorFunction,
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
+ from unittest.mock import Mock
4
5
 
5
- import httpx
6
6
  import pytest
7
7
 
8
8
  from apify_client import ApifyClientAsync
@@ -11,7 +11,8 @@ from apify_shared.consts import ApifyEnvVars
11
11
  from apify import Actor
12
12
 
13
13
  if TYPE_CHECKING:
14
- from respx import MockRouter
14
+ from pytest_httpserver import HTTPServer
15
+ from werkzeug import Request, Response
15
16
 
16
17
  from ..conftest import ApifyClientAsyncPatcher
17
18
 
@@ -24,25 +25,29 @@ def patched_apify_client(apify_client_async_patcher: ApifyClientAsyncPatcher) ->
24
25
  return ApifyClientAsync()
25
26
 
26
27
 
28
+ @pytest.mark.usefixtures('patched_httpx_client')
27
29
  async def test_basic_proxy_configuration_creation(
28
30
  monkeypatch: pytest.MonkeyPatch,
29
- respx_mock: MockRouter,
31
+ httpserver: HTTPServer,
30
32
  patched_apify_client: ApifyClientAsync,
31
33
  ) -> None:
32
- dummy_proxy_status_url = 'http://dummy-proxy-status-url.com'
34
+ dummy_proxy_status_url = str(httpserver.url_for('/')).removesuffix('/')
33
35
  monkeypatch.setenv(ApifyEnvVars.TOKEN.value, 'DUMMY_TOKEN')
34
36
  monkeypatch.setenv(ApifyEnvVars.PROXY_STATUS_URL.value, dummy_proxy_status_url)
35
37
 
36
- route = respx_mock.get(dummy_proxy_status_url)
37
- route.mock(
38
- httpx.Response(
39
- 200,
40
- json={
41
- 'connected': True,
42
- 'connectionError': None,
43
- 'isManInTheMiddle': True,
44
- },
45
- )
38
+ call_mock = Mock()
39
+
40
+ def request_handler(request: Request, response: Response) -> Response:
41
+ call_mock(request.url)
42
+ return response
43
+
44
+ httpserver.expect_oneshot_request('/').with_post_hook(request_handler).respond_with_json(
45
+ {
46
+ 'connected': True,
47
+ 'connectionError': None,
48
+ 'isManInTheMiddle': True,
49
+ },
50
+ status=200,
46
51
  )
47
52
 
48
53
  groups = ['GROUP1', 'GROUP2']
@@ -58,32 +63,36 @@ async def test_basic_proxy_configuration_creation(
58
63
  assert proxy_configuration._country_code == country_code
59
64
 
60
65
  assert len(patched_apify_client.calls['user']['get']) == 1 # type: ignore[attr-defined]
61
- assert len(route.calls) == 1
66
+ assert call_mock.call_count == 1
62
67
 
63
68
  await Actor.exit()
64
69
 
65
70
 
71
+ @pytest.mark.usefixtures('patched_httpx_client')
66
72
  async def test_proxy_configuration_with_actor_proxy_input(
67
73
  monkeypatch: pytest.MonkeyPatch,
68
- respx_mock: MockRouter,
74
+ httpserver: HTTPServer,
69
75
  patched_apify_client: ApifyClientAsync,
70
76
  ) -> None:
71
- dummy_proxy_status_url = 'http://dummy-proxy-status-url.com'
77
+ dummy_proxy_status_url = str(httpserver.url_for('/')).removesuffix('/')
72
78
  dummy_proxy_url = 'http://dummy-proxy.com:8000'
73
79
 
74
80
  monkeypatch.setenv(ApifyEnvVars.TOKEN.value, 'DUMMY_TOKEN')
75
81
  monkeypatch.setenv(ApifyEnvVars.PROXY_STATUS_URL.value, dummy_proxy_status_url)
76
82
 
77
- route = respx_mock.get(dummy_proxy_status_url)
78
- route.mock(
79
- httpx.Response(
80
- 200,
81
- json={
82
- 'connected': True,
83
- 'connectionError': None,
84
- 'isManInTheMiddle': True,
85
- },
86
- )
83
+ call_mock = Mock()
84
+
85
+ def request_handler(request: Request, response: Response) -> Response:
86
+ call_mock(request.url)
87
+ return response
88
+
89
+ httpserver.expect_request('/').with_post_hook(request_handler).respond_with_json(
90
+ {
91
+ 'connected': True,
92
+ 'connectionError': None,
93
+ 'isManInTheMiddle': True,
94
+ },
95
+ status=200,
87
96
  )
88
97
 
89
98
  await Actor.init()
@@ -138,6 +147,6 @@ async def test_proxy_configuration_with_actor_proxy_input(
138
147
  )
139
148
 
140
149
  assert len(patched_apify_client.calls['user']['get']) == 2 # type: ignore[attr-defined]
141
- assert len(route.calls) == 2
150
+ assert call_mock.call_count == 2
142
151
 
143
152
  await Actor.exit()
@@ -2,17 +2,21 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
  from dataclasses import dataclass
5
- from typing import Any, get_args
5
+ from typing import TYPE_CHECKING, Any, get_args
6
+ from unittest.mock import Mock
6
7
 
7
8
  import pytest
8
- import respx
9
- from httpx import Response
9
+ from yarl import URL
10
10
 
11
11
  from crawlee._request import UserData
12
12
  from crawlee._types import HttpMethod
13
13
 
14
14
  from apify.storages._request_list import URL_NO_COMMAS_REGEX, RequestList
15
15
 
16
+ if TYPE_CHECKING:
17
+ from pytest_httpserver import HTTPServer
18
+ from werkzeug import Request, Response
19
+
16
20
 
17
21
  @pytest.mark.parametrize(
18
22
  argnames='request_method',
@@ -67,20 +71,19 @@ async def test_request_list_open_request_types(
67
71
  assert request.headers.root == optional_input.get('headers', {})
68
72
 
69
73
 
70
- @respx.mock
71
- async def test_request_list_open_from_url_correctly_send_requests() -> None:
74
+ async def test_request_list_open_from_url_correctly_send_requests(httpserver: HTTPServer) -> None:
72
75
  """Test that requests are sent to expected urls."""
73
76
  request_list_sources_input: list[dict[str, Any]] = [
74
77
  {
75
- 'requestsFromUrl': 'https://abc.dev/file.txt',
78
+ 'requestsFromUrl': httpserver.url_for('/file.txt'),
76
79
  'method': 'GET',
77
80
  },
78
81
  {
79
- 'requestsFromUrl': 'https://www.abc.dev/file2',
82
+ 'requestsFromUrl': httpserver.url_for('/file2'),
80
83
  'method': 'PUT',
81
84
  },
82
85
  {
83
- 'requestsFromUrl': 'https://www.something.som',
86
+ 'requestsFromUrl': httpserver.url_for('/something'),
84
87
  'method': 'POST',
85
88
  'headers': {'key': 'value'},
86
89
  'payload': 'some_payload',
@@ -88,16 +91,28 @@ async def test_request_list_open_from_url_correctly_send_requests() -> None:
88
91
  },
89
92
  ]
90
93
 
91
- routes = [respx.get(entry['requestsFromUrl']) for entry in request_list_sources_input]
94
+ routes: dict[str, Mock] = {}
95
+
96
+ def request_handler(request: Request, response: Response) -> Response:
97
+ routes[request.url]()
98
+ return response
99
+
100
+ for entry in request_list_sources_input:
101
+ path = str(URL(entry['requestsFromUrl']).path)
102
+ httpserver.expect_oneshot_request(path).with_post_hook(request_handler).respond_with_data(status=200)
103
+ routes[entry['requestsFromUrl']] = Mock()
92
104
 
93
105
  await RequestList.open(request_list_sources_input=request_list_sources_input)
94
106
 
95
- for route in routes:
96
- assert route.called
107
+ assert len(routes) == len(request_list_sources_input)
97
108
 
109
+ for entity in request_list_sources_input:
110
+ entity_url = entity['requestsFromUrl']
111
+ assert entity_url in routes
112
+ assert routes[entity_url].called
98
113
 
99
- @respx.mock
100
- async def test_request_list_open_from_url() -> None:
114
+
115
+ async def test_request_list_open_from_url(httpserver: HTTPServer) -> None:
101
116
  """Test that create_request_list is correctly reading urls from remote url sources and also from simple input."""
102
117
  expected_simple_url = 'https://www.someurl.com'
103
118
  expected_remote_urls_1 = {'http://www.something.com', 'https://www.somethingelse.com', 'http://www.bla.net'}
@@ -111,11 +126,11 @@ async def test_request_list_open_from_url() -> None:
111
126
 
112
127
  mocked_urls = (
113
128
  MockedUrlInfo(
114
- 'https://abc.dev/file.txt',
129
+ httpserver.url_for('/file.txt'),
115
130
  'blablabla{} more blablabla{} , even more blablabla. {} '.format(*expected_remote_urls_1),
116
131
  ),
117
132
  MockedUrlInfo(
118
- 'https://www.abc.dev/file2',
133
+ httpserver.url_for('/file2'),
119
134
  'some stuff{} more stuff{} www.false_positive.com'.format(*expected_remote_urls_2),
120
135
  ),
121
136
  )
@@ -132,7 +147,8 @@ async def test_request_list_open_from_url() -> None:
132
147
  },
133
148
  ]
134
149
  for mocked_url in mocked_urls:
135
- respx.get(mocked_url.url).mock(return_value=Response(200, text=mocked_url.response_text))
150
+ path = str(URL(mocked_url.url).path)
151
+ httpserver.expect_oneshot_request(path).respond_with_data(status=200, response_data=mocked_url.response_text)
136
152
 
137
153
  request_list = await RequestList.open(request_list_sources_input=request_list_sources_input)
138
154
  generated_requests = []
@@ -143,23 +159,20 @@ async def test_request_list_open_from_url() -> None:
143
159
  assert {generated_request.url for generated_request in generated_requests} == expected_urls
144
160
 
145
161
 
146
- @respx.mock
147
- async def test_request_list_open_from_url_additional_inputs() -> None:
162
+ async def test_request_list_open_from_url_additional_inputs(httpserver: HTTPServer) -> None:
148
163
  """Test that all generated request properties are correctly populated from input values."""
149
164
  expected_url = 'https://www.someurl.com'
150
165
  example_start_url_input: dict[str, Any] = {
151
- 'requestsFromUrl': 'https://crawlee.dev/file.txt',
166
+ 'requestsFromUrl': httpserver.url_for('/file.txt'),
152
167
  'method': 'POST',
153
168
  'headers': {'key': 'value'},
154
169
  'payload': 'some_payload',
155
170
  'userData': {'another_key': 'another_value'},
156
171
  }
157
-
158
- respx.get(example_start_url_input['requestsFromUrl']).mock(return_value=Response(200, text=expected_url))
172
+ httpserver.expect_oneshot_request('/file.txt').respond_with_data(status=200, response_data=expected_url)
159
173
 
160
174
  request_list = await RequestList.open(request_list_sources_input=[example_start_url_input])
161
175
  request = await request_list.fetch_next_request()
162
-
163
176
  # Check all properties correctly created for request
164
177
  assert request
165
178
  assert request.url == expected_url
@@ -4,9 +4,12 @@ import asyncio
4
4
  import inspect
5
5
  import os
6
6
  from collections import defaultdict
7
+ from logging import getLogger
7
8
  from typing import TYPE_CHECKING, Any, get_type_hints
8
9
 
10
+ import httpx
9
11
  import pytest
12
+ from pytest_httpserver import HTTPServer
10
13
 
11
14
  from apify_client import ApifyClientAsync
12
15
  from apify_shared.consts import ApifyEnvVars
@@ -18,7 +21,7 @@ from crawlee.storages import _creation_management
18
21
  import apify._actor
19
22
 
20
23
  if TYPE_CHECKING:
21
- from collections.abc import Callable
24
+ from collections.abc import Callable, Iterator
22
25
  from pathlib import Path
23
26
 
24
27
 
@@ -187,3 +190,37 @@ def memory_storage_client() -> MemoryStorageClient:
187
190
  configuration.write_metadata = True
188
191
 
189
192
  return MemoryStorageClient.from_config(configuration)
193
+
194
+
195
+ @pytest.fixture(scope='session')
196
+ def make_httpserver() -> Iterator[HTTPServer]:
197
+ werkzeug_logger = getLogger('werkzeug')
198
+ werkzeug_logger.disabled = True
199
+
200
+ server = HTTPServer(threaded=True, host='127.0.0.1')
201
+ server.start()
202
+ yield server
203
+ server.clear() # type: ignore[no-untyped-call]
204
+ if server.is_running():
205
+ server.stop() # type: ignore[no-untyped-call]
206
+
207
+
208
+ @pytest.fixture
209
+ def httpserver(make_httpserver: HTTPServer) -> Iterator[HTTPServer]:
210
+ server = make_httpserver
211
+ yield server
212
+ server.clear() # type: ignore[no-untyped-call]
213
+
214
+
215
+ @pytest.fixture
216
+ def patched_httpx_client(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
217
+ """Patch httpx client to drop proxy settings."""
218
+
219
+ class ProxylessAsyncClient(httpx.AsyncClient):
220
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
221
+ kwargs.pop('proxy', None)
222
+ super().__init__(*args, **kwargs)
223
+
224
+ monkeypatch.setattr(httpx, 'AsyncClient', ProxylessAsyncClient)
225
+ yield
226
+ monkeypatch.undo()