apify 2.4.0b2__tar.gz → 2.4.0b3__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 (196) hide show
  1. {apify-2.4.0b2 → apify-2.4.0b3}/PKG-INFO +1 -1
  2. {apify-2.4.0b2 → apify-2.4.0b3}/pyproject.toml +1 -1
  3. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_actor.py +38 -9
  4. apify-2.4.0b3/tests/unit/actor/test_actor_log.py +104 -0
  5. apify-2.4.0b2/tests/unit/actor/test_actor_log.py +0 -93
  6. {apify-2.4.0b2 → apify-2.4.0b3}/.editorconfig +0 -0
  7. {apify-2.4.0b2 → apify-2.4.0b3}/.github/CODEOWNERS +0 -0
  8. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/build_and_deploy_docs.yaml +0 -0
  9. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/check_pr_title.yaml +0 -0
  10. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/pre_release.yaml +0 -0
  11. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/release.yaml +0 -0
  12. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/run_code_checks.yaml +0 -0
  13. {apify-2.4.0b2 → apify-2.4.0b3}/.github/workflows/update_new_issue.yaml +0 -0
  14. {apify-2.4.0b2 → apify-2.4.0b3}/.gitignore +0 -0
  15. {apify-2.4.0b2 → apify-2.4.0b3}/.markdownlint.yaml +0 -0
  16. {apify-2.4.0b2 → apify-2.4.0b3}/.pre-commit-config.yaml +0 -0
  17. {apify-2.4.0b2 → apify-2.4.0b3}/CHANGELOG.md +0 -0
  18. {apify-2.4.0b2 → apify-2.4.0b3}/CONTRIBUTING.md +0 -0
  19. {apify-2.4.0b2 → apify-2.4.0b3}/LICENSE +0 -0
  20. {apify-2.4.0b2 → apify-2.4.0b3}/Makefile +0 -0
  21. {apify-2.4.0b2 → apify-2.4.0b3}/README.md +0 -0
  22. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/01_introduction.mdx +0 -0
  23. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/02_running_actors_locally.mdx +0 -0
  24. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/03_actor_structure.mdx +0 -0
  25. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/code/01_introduction.py +0 -0
  26. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/code/actor_structure/__init__.py +0 -0
  27. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/code/actor_structure/__main__.py +0 -0
  28. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/code/actor_structure/main.py +0 -0
  29. {apify-2.4.0b2 → apify-2.4.0b3}/docs/01_overview/code/actor_structure/py.typed +0 -0
  30. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/01_beautifulsoup_httpx.mdx +0 -0
  31. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/02_crawlee.mdx +0 -0
  32. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/03_playwright.mdx +0 -0
  33. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/04_selenium.mdx +0 -0
  34. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/05_scrapy.mdx +0 -0
  35. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/01_beautifulsoup_httpx.py +0 -0
  36. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/02_crawlee_beautifulsoup.py +0 -0
  37. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/02_crawlee_playwright.py +0 -0
  38. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/03_playwright.py +0 -0
  39. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/04_selenium.py +0 -0
  40. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/__init__.py +0 -0
  41. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/__main__.py +0 -0
  42. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/items.py +0 -0
  43. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/main.py +0 -0
  44. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/py.typed +0 -0
  45. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/settings.py +0 -0
  46. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/spiders/__init__.py +0 -0
  47. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/spiders/py.typed +0 -0
  48. {apify-2.4.0b2 → apify-2.4.0b3}/docs/02_guides/code/scrapy_project/src/spiders/title.py +0 -0
  49. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/01_actor_lifecycle.mdx +0 -0
  50. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/02_actor_input.mdx +0 -0
  51. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/03_storages.mdx +0 -0
  52. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/04_actor_events.mdx +0 -0
  53. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/05_proxy_management.mdx +0 -0
  54. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/06_interacting_with_other_actors.mdx +0 -0
  55. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/07_webhooks.mdx +0 -0
  56. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/08_access_apify_api.mdx +0 -0
  57. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/09_running_webserver.mdx +0 -0
  58. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/10_logging.mdx +0 -0
  59. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/11_configuration.mdx +0 -0
  60. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/01_context_manager.py +0 -0
  61. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/01_init_exit.py +0 -0
  62. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/01_reboot.py +0 -0
  63. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/01_status_message.py +0 -0
  64. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/02_input.py +0 -0
  65. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_dataset_exports.py +0 -0
  66. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_dataset_read_write.py +0 -0
  67. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_deleting_storages.py +0 -0
  68. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_kvs_iterating.py +0 -0
  69. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_kvs_public_url.py +0 -0
  70. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_kvs_read_write.py +0 -0
  71. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_opening_storages.py +0 -0
  72. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/03_rq.py +0 -0
  73. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/04_actor_events.py +0 -0
  74. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_apify_proxy.py +0 -0
  75. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_apify_proxy_config.py +0 -0
  76. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_custom_proxy.py +0 -0
  77. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_custom_proxy_function.py +0 -0
  78. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_proxy_actor_input.py +0 -0
  79. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_proxy_httpx.py +0 -0
  80. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/05_proxy_rotation.py +0 -0
  81. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/06_interacting_call.py +0 -0
  82. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/06_interacting_call_task.py +0 -0
  83. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/06_interacting_metamorph.py +0 -0
  84. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/06_interacting_start.py +0 -0
  85. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/07_webhook.py +0 -0
  86. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/07_webhook_preventing.py +0 -0
  87. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/08_actor_client.py +0 -0
  88. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/08_actor_new_client.py +0 -0
  89. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/09_webserver.py +0 -0
  90. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/10_log_config.py +0 -0
  91. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/10_logger_usage.py +0 -0
  92. {apify-2.4.0b2 → apify-2.4.0b3}/docs/03_concepts/code/11_config.py +0 -0
  93. {apify-2.4.0b2 → apify-2.4.0b3}/docs/04_upgrading/upgrading_to_v2.md +0 -0
  94. {apify-2.4.0b2 → apify-2.4.0b3}/docs/pyproject.toml +0 -0
  95. {apify-2.4.0b2 → apify-2.4.0b3}/renovate.json +0 -0
  96. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/__init__.py +0 -0
  97. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_charging.py +0 -0
  98. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_configuration.py +0 -0
  99. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_consts.py +0 -0
  100. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_crypto.py +0 -0
  101. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_models.py +0 -0
  102. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_platform_event_manager.py +0 -0
  103. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_proxy_configuration.py +0 -0
  104. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/_utils.py +0 -0
  105. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/__init__.py +0 -0
  106. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_apify_storage_client.py +0 -0
  107. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_dataset_client.py +0 -0
  108. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_dataset_collection_client.py +0 -0
  109. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_key_value_store_client.py +0 -0
  110. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_key_value_store_collection_client.py +0 -0
  111. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_request_queue_client.py +0 -0
  112. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/_request_queue_collection_client.py +0 -0
  113. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/apify_storage_client/py.typed +0 -0
  114. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/log.py +0 -0
  115. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/py.typed +0 -0
  116. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/__init__.py +0 -0
  117. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/_actor_runner.py +0 -0
  118. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/_async_thread.py +0 -0
  119. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/_logging_config.py +0 -0
  120. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/middlewares/__init__.py +0 -0
  121. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/middlewares/apify_proxy.py +0 -0
  122. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/middlewares/py.typed +0 -0
  123. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/pipelines/__init__.py +0 -0
  124. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/pipelines/actor_dataset_push.py +0 -0
  125. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/pipelines/py.typed +0 -0
  126. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/py.typed +0 -0
  127. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/requests.py +0 -0
  128. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/scheduler.py +0 -0
  129. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/scrapy/utils.py +0 -0
  130. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/storages/__init__.py +0 -0
  131. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/storages/_request_list.py +0 -0
  132. {apify-2.4.0b2 → apify-2.4.0b3}/src/apify/storages/py.typed +0 -0
  133. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/README.md +0 -0
  134. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/__init__.py +0 -0
  135. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/_utils.py +0 -0
  136. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/actor_source_base/Dockerfile +0 -0
  137. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/actor_source_base/requirements.txt +0 -0
  138. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/actor_source_base/src/__init__.py +0 -0
  139. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/actor_source_base/src/__main__.py +0 -0
  140. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/actor_source_base/src/main.py +0 -0
  141. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/conftest.py +0 -0
  142. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_api_helpers.py +0 -0
  143. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_charge.py +0 -0
  144. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_create_proxy_configuration.py +0 -0
  145. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_dataset.py +0 -0
  146. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_events.py +0 -0
  147. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_key_value_store.py +0 -0
  148. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_lifecycle.py +0 -0
  149. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_log.py +0 -0
  150. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_request_queue.py +0 -0
  151. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_actor_scrapy.py +0 -0
  152. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_fixtures.py +0 -0
  153. {apify-2.4.0b2 → apify-2.4.0b3}/tests/integration/test_request_queue.py +0 -0
  154. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/__init__.py +0 -0
  155. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/__init__.py +0 -0
  156. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_create_proxy_configuration.py +0 -0
  157. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_dataset.py +0 -0
  158. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_env_helpers.py +0 -0
  159. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_helpers.py +0 -0
  160. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_key_value_store.py +0 -0
  161. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_lifecycle.py +0 -0
  162. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_non_default_instance.py +0 -0
  163. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_actor_request_queue.py +0 -0
  164. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/actor/test_request_list.py +0 -0
  165. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/conftest.py +0 -0
  166. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/__init__.py +0 -0
  167. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/middlewares/__init__.py +0 -0
  168. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/middlewares/test_apify_proxy.py +0 -0
  169. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/pipelines/__init__.py +0 -0
  170. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/pipelines/test_actor_dataset_push.py +0 -0
  171. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/requests/__init__.py +0 -0
  172. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/requests/test_to_apify_request.py +0 -0
  173. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/requests/test_to_scrapy_request.py +0 -0
  174. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/utils/__init__.py +0 -0
  175. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/utils/test_apply_apify_settings.py +0 -0
  176. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/scrapy/utils/test_get_basic_auth_header.py +0 -0
  177. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/test_crypto.py +0 -0
  178. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/test_platform_event_manager.py +0 -0
  179. {apify-2.4.0b2 → apify-2.4.0b3}/tests/unit/test_proxy_configuration.py +0 -0
  180. {apify-2.4.0b2 → apify-2.4.0b3}/uv.lock +0 -0
  181. {apify-2.4.0b2 → apify-2.4.0b3}/website/.eslintrc.json +0 -0
  182. {apify-2.4.0b2 → apify-2.4.0b3}/website/babel.config.js +0 -0
  183. {apify-2.4.0b2 → apify-2.4.0b3}/website/build_api_reference.sh +0 -0
  184. {apify-2.4.0b2 → apify-2.4.0b3}/website/docusaurus.config.js +0 -0
  185. {apify-2.4.0b2 → apify-2.4.0b3}/website/generate_module_shortcuts.py +0 -0
  186. {apify-2.4.0b2 → apify-2.4.0b3}/website/package-lock.json +0 -0
  187. {apify-2.4.0b2 → apify-2.4.0b3}/website/package.json +0 -0
  188. {apify-2.4.0b2 → apify-2.4.0b3}/website/sidebars.js +0 -0
  189. {apify-2.4.0b2 → apify-2.4.0b3}/website/src/css/custom.css +0 -0
  190. {apify-2.4.0b2 → apify-2.4.0b3}/website/src/pages/home_page_example.py +0 -0
  191. {apify-2.4.0b2 → apify-2.4.0b3}/website/src/pages/index.js +0 -0
  192. {apify-2.4.0b2 → apify-2.4.0b3}/website/src/pages/index.module.css +0 -0
  193. {apify-2.4.0b2 → apify-2.4.0b3}/website/static/.nojekyll +0 -0
  194. {apify-2.4.0b2 → apify-2.4.0b3}/website/static/img/docs-og.png +0 -0
  195. {apify-2.4.0b2 → apify-2.4.0b3}/website/tools/docs-prettier.config.js +0 -0
  196. {apify-2.4.0b2 → apify-2.4.0b3}/website/tools/utils/externalLink.js +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify
3
- Version: 2.4.0b2
3
+ Version: 2.4.0b3
4
4
  Summary: Apify SDK for Python
5
5
  Project-URL: Homepage, https://docs.apify.com/sdk/python/
6
6
  Project-URL: Apify homepage, https://apify.com
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "apify"
7
- version = "2.4.0b2"
7
+ version = "2.4.0b3"
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" }
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import os
5
5
  import sys
6
+ from contextlib import suppress
6
7
  from datetime import timedelta
7
8
  from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, cast, overload
8
9
 
@@ -64,6 +65,7 @@ class _ActorType:
64
65
  configuration: Configuration | None = None,
65
66
  *,
66
67
  configure_logging: bool = True,
68
+ exit_process: bool | None = None,
67
69
  ) -> None:
68
70
  """Create an Actor instance.
69
71
 
@@ -74,7 +76,10 @@ class _ActorType:
74
76
  configuration: The Actor configuration to be used. If not passed, a new Configuration instance will
75
77
  be created.
76
78
  configure_logging: Should the default logging configuration be configured?
79
+ exit_process: Whether the Actor should call `sys.exit` when the context manager exits. The default is
80
+ True except for the IPython, Pytest and Scrapy environments.
77
81
  """
82
+ self._exit_process = self._get_default_exit_process() if exit_process is None else exit_process
78
83
  self._is_exiting = False
79
84
 
80
85
  self._configuration = configuration or Configuration.get_global_configuration()
@@ -141,9 +146,19 @@ class _ActorType:
141
146
 
142
147
  return super().__repr__()
143
148
 
144
- def __call__(self, configuration: Configuration | None = None, *, configure_logging: bool = True) -> Self:
149
+ def __call__(
150
+ self,
151
+ configuration: Configuration | None = None,
152
+ *,
153
+ configure_logging: bool = True,
154
+ exit_process: bool | None = None,
155
+ ) -> Self:
145
156
  """Make a new Actor instance with a non-default configuration."""
146
- return self.__class__(configuration=configuration, configure_logging=configure_logging)
157
+ return self.__class__(
158
+ configuration=configuration,
159
+ configure_logging=configure_logging,
160
+ exit_process=exit_process,
161
+ )
147
162
 
148
163
  @property
149
164
  def apify_client(self) -> ApifyClientAsync:
@@ -281,13 +296,7 @@ class _ActorType:
281
296
  await asyncio.wait_for(finalize(), cleanup_timeout.total_seconds())
282
297
  self._is_initialized = False
283
298
 
284
- if is_running_in_ipython():
285
- self.log.debug(f'Not calling sys.exit({exit_code}) because Actor is running in IPython')
286
- elif os.getenv('PYTEST_CURRENT_TEST', default=False): # noqa: PLW1508
287
- self.log.debug(f'Not calling sys.exit({exit_code}) because Actor is running in an unit test')
288
- elif os.getenv('SCRAPY_SETTINGS_MODULE'):
289
- self.log.debug(f'Not calling sys.exit({exit_code}) because Actor is running with Scrapy')
290
- else:
299
+ if self._exit_process:
291
300
  sys.exit(exit_code)
292
301
 
293
302
  async def fail(
@@ -1128,6 +1137,26 @@ class _ActorType:
1128
1137
 
1129
1138
  return proxy_configuration
1130
1139
 
1140
+ def _get_default_exit_process(self) -> bool:
1141
+ """Returns False for IPython, Pytest, and Scrapy environments, True otherwise."""
1142
+ if is_running_in_ipython():
1143
+ self.log.debug('Running in IPython, setting default `exit_process` to False.')
1144
+ return False
1145
+
1146
+ # Check if running in Pytest by detecting the relevant environment variable.
1147
+ if os.getenv('PYTEST_CURRENT_TEST'):
1148
+ self.log.debug('Running in Pytest, setting default `exit_process` to False.')
1149
+ return False
1150
+
1151
+ # Check if running in Scrapy by attempting to import it.
1152
+ with suppress(ImportError):
1153
+ import scrapy # noqa: F401
1154
+
1155
+ self.log.debug('Running in Scrapy, setting default `exit_process` to False.')
1156
+ return False
1157
+
1158
+ return True
1159
+
1131
1160
 
1132
1161
  Actor = cast(_ActorType, Proxy(_ActorType))
1133
1162
  """The entry point of the SDK, through which all the Actor operations should be done."""
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import logging
5
+ from typing import TYPE_CHECKING
6
+
7
+ from apify import Actor
8
+ from apify.log import logger
9
+
10
+ if TYPE_CHECKING:
11
+ import pytest
12
+
13
+
14
+ async def test_actor_logs_messages_correctly(caplog: pytest.LogCaptureFixture) -> None:
15
+ caplog.set_level(logging.DEBUG, logger='apify')
16
+
17
+ with contextlib.suppress(RuntimeError):
18
+ async with Actor(configure_logging=False):
19
+ # Test Actor.log
20
+ Actor.log.debug('Debug message')
21
+ Actor.log.info('Info message')
22
+
23
+ # Test logger
24
+ logger.warning('Warning message')
25
+ logger.error('Error message')
26
+
27
+ # Test that exception is logged with the traceback
28
+ try:
29
+ raise ValueError('Dummy ValueError')
30
+ except Exception:
31
+ Actor.log.exception('Exception message')
32
+
33
+ # Test multiline message being indented correctly
34
+ logger.info('Multi\nline\nlog\nmessage')
35
+
36
+ # Test that exception in Actor.main is logged with the traceback
37
+ raise RuntimeError('Dummy RuntimeError')
38
+
39
+ # Updated expected number of log records (an extra record is now captured)
40
+ assert len(caplog.records) == 14
41
+
42
+ # Record 0: Extra Pytest context log
43
+ assert caplog.records[0].levelno == logging.DEBUG
44
+ assert caplog.records[0].message.startswith('Running in Pytest')
45
+
46
+ # Record 1: Duplicate Pytest context log
47
+ assert caplog.records[1].levelno == logging.DEBUG
48
+ assert caplog.records[0].message.startswith('Running in Pytest')
49
+
50
+ # Record 2: Initializing Actor...
51
+ assert caplog.records[2].levelno == logging.INFO
52
+ assert caplog.records[2].message == 'Initializing Actor...'
53
+
54
+ # Record 3: System info
55
+ assert caplog.records[3].levelno == logging.INFO
56
+ assert caplog.records[3].message == 'System info'
57
+
58
+ # Record 4: Event manager initialized
59
+ assert caplog.records[4].levelno == logging.DEBUG
60
+ assert caplog.records[4].message == 'Event manager initialized'
61
+
62
+ # Record 5: Charging manager initialized
63
+ assert caplog.records[5].levelno == logging.DEBUG
64
+ assert caplog.records[5].message == 'Charging manager initialized'
65
+
66
+ # Record 6: Debug message
67
+ assert caplog.records[6].levelno == logging.DEBUG
68
+ assert caplog.records[6].message == 'Debug message'
69
+
70
+ # Record 7: Info message
71
+ assert caplog.records[7].levelno == logging.INFO
72
+ assert caplog.records[7].message == 'Info message'
73
+
74
+ # Record 8: Warning message
75
+ assert caplog.records[8].levelno == logging.WARNING
76
+ assert caplog.records[8].message == 'Warning message'
77
+
78
+ # Record 9: Error message
79
+ assert caplog.records[9].levelno == logging.ERROR
80
+ assert caplog.records[9].message == 'Error message'
81
+
82
+ # Record 10: Exception message with traceback (ValueError)
83
+ assert caplog.records[10].levelno == logging.ERROR
84
+ assert caplog.records[10].message == 'Exception message'
85
+ assert caplog.records[10].exc_info is not None
86
+ assert caplog.records[10].exc_info[0] is ValueError
87
+ assert isinstance(caplog.records[10].exc_info[1], ValueError)
88
+ assert str(caplog.records[10].exc_info[1]) == 'Dummy ValueError'
89
+
90
+ # Record 11: Multiline log message
91
+ assert caplog.records[11].levelno == logging.INFO
92
+ assert caplog.records[11].message == 'Multi\nline\nlog\nmessage'
93
+
94
+ # Record 12: Actor failed with an exception (RuntimeError)
95
+ assert caplog.records[12].levelno == logging.ERROR
96
+ assert caplog.records[12].message == 'Actor failed with an exception'
97
+ assert caplog.records[12].exc_info is not None
98
+ assert caplog.records[12].exc_info[0] is RuntimeError
99
+ assert isinstance(caplog.records[12].exc_info[1], RuntimeError)
100
+ assert str(caplog.records[12].exc_info[1]) == 'Dummy RuntimeError'
101
+
102
+ # Record 13: Exiting Actor
103
+ assert caplog.records[13].levelno == logging.INFO
104
+ assert caplog.records[13].message == 'Exiting Actor'
@@ -1,93 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import contextlib
4
- import logging
5
- import sys
6
- from typing import TYPE_CHECKING
7
-
8
- from apify_client import __version__ as apify_client_version
9
-
10
- from apify import Actor, __version__
11
- from apify.log import logger
12
-
13
- if TYPE_CHECKING:
14
- import pytest
15
-
16
-
17
- async def test_actor_logs_messages_correctly(caplog: pytest.LogCaptureFixture) -> None:
18
- caplog.set_level(logging.DEBUG, logger='apify')
19
-
20
- with contextlib.suppress(RuntimeError):
21
- async with Actor(configure_logging=False):
22
- # Test Actor.log
23
- Actor.log.debug('Debug message')
24
- Actor.log.info('Info message')
25
-
26
- # Test logger
27
- logger.warning('Warning message')
28
- logger.error('Error message')
29
-
30
- # Test that exception is logged with the traceback
31
- try:
32
- raise ValueError('Dummy ValueError')
33
- except Exception:
34
- Actor.log.exception('Exception message')
35
-
36
- # Test multiline message being indented correctly
37
- logger.info('Multi\nline\nlog\nmessage')
38
-
39
- # Test that exception in Actor.main is logged with the traceback
40
- raise RuntimeError('Dummy RuntimeError')
41
-
42
- assert len(caplog.records) == 13
43
-
44
- assert caplog.records[0].levelno == logging.INFO
45
- assert caplog.records[0].message == 'Initializing Actor...'
46
-
47
- assert caplog.records[1].levelno == logging.INFO
48
- assert caplog.records[1].message == 'System info'
49
- assert getattr(caplog.records[1], 'apify_sdk_version', None) == __version__
50
- assert getattr(caplog.records[1], 'apify_client_version', None) == apify_client_version
51
- assert getattr(caplog.records[1], 'python_version', None) == '.'.join([str(x) for x in sys.version_info[:3]])
52
- assert getattr(caplog.records[1], 'os', None) == sys.platform
53
-
54
- assert caplog.records[2].levelno == logging.DEBUG
55
- assert caplog.records[2].message == 'Event manager initialized'
56
-
57
- assert caplog.records[3].levelno == logging.DEBUG
58
- assert caplog.records[3].message == 'Charging manager initialized'
59
-
60
- assert caplog.records[4].levelno == logging.DEBUG
61
- assert caplog.records[4].message == 'Debug message'
62
-
63
- assert caplog.records[5].levelno == logging.INFO
64
- assert caplog.records[5].message == 'Info message'
65
-
66
- assert caplog.records[6].levelno == logging.WARNING
67
- assert caplog.records[6].message == 'Warning message'
68
-
69
- assert caplog.records[7].levelno == logging.ERROR
70
- assert caplog.records[7].message == 'Error message'
71
-
72
- assert caplog.records[8].levelno == logging.ERROR
73
- assert caplog.records[8].message == 'Exception message'
74
- assert caplog.records[8].exc_info is not None
75
- assert caplog.records[8].exc_info[0] is ValueError
76
- assert isinstance(caplog.records[8].exc_info[1], ValueError)
77
- assert str(caplog.records[8].exc_info[1]) == 'Dummy ValueError'
78
-
79
- assert caplog.records[9].levelno == logging.INFO
80
- assert caplog.records[9].message == 'Multi\nline\nlog\nmessage'
81
-
82
- assert caplog.records[10].levelno == logging.ERROR
83
- assert caplog.records[10].message == 'Actor failed with an exception'
84
- assert caplog.records[10].exc_info is not None
85
- assert caplog.records[10].exc_info[0] is RuntimeError
86
- assert isinstance(caplog.records[10].exc_info[1], RuntimeError)
87
- assert str(caplog.records[10].exc_info[1]) == 'Dummy RuntimeError'
88
-
89
- assert caplog.records[11].levelno == logging.INFO
90
- assert caplog.records[11].message == 'Exiting Actor'
91
-
92
- assert caplog.records[12].levelno == logging.DEBUG
93
- assert caplog.records[12].message == 'Not calling sys.exit(91) because Actor is running in an unit test'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes