anchorbrowser 0.1.0a1__tar.gz → 0.1.0a3__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.
Files changed (144) hide show
  1. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/.gitignore +0 -1
  2. anchorbrowser-0.1.0a3/.release-please-manifest.json +3 -0
  3. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/CHANGELOG.md +26 -0
  4. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/PKG-INFO +3 -1
  5. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/pyproject.toml +30 -45
  6. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/requirements-dev.lock +27 -0
  7. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/requirements.lock +39 -0
  8. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_client.py +17 -5
  9. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_models.py +23 -2
  10. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_version.py +1 -1
  11. anchorbrowser-0.1.0a3/src/anchorbrowser/lib/agent.py +69 -0
  12. anchorbrowser-0.1.0a3/src/anchorbrowser/lib/browser.py +186 -0
  13. anchorbrowser-0.1.0a3/src/anchorbrowser/resources/agent.py +305 -0
  14. anchorbrowser-0.1.0a3/src/anchorbrowser/resources/browser.py +152 -0
  15. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_manifest.py +4 -1
  16. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_models.py +28 -1
  17. anchorbrowser-0.1.0a1/.release-please-manifest.json +0 -3
  18. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/CONTRIBUTING.md +0 -0
  19. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/LICENSE +0 -0
  20. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/README.md +0 -0
  21. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/SECURITY.md +0 -0
  22. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/api.md +0 -0
  23. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/bin/check-release-environment +0 -0
  24. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/bin/publish-pypi +0 -0
  25. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/examples/.keep +0 -0
  26. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/mypy.ini +0 -0
  27. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/noxfile.py +0 -0
  28. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/release-please-config.json +0 -0
  29. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/__init__.py +0 -0
  30. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_base_client.py +0 -0
  31. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_compat.py +0 -0
  32. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_constants.py +0 -0
  33. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_exceptions.py +0 -0
  34. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_files.py +0 -0
  35. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_qs.py +0 -0
  36. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_resource.py +0 -0
  37. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_response.py +0 -0
  38. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_streaming.py +0 -0
  39. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_types.py +0 -0
  40. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/__init__.py +0 -0
  41. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_logs.py +0 -0
  42. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_proxy.py +0 -0
  43. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_reflection.py +0 -0
  44. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_resources_proxy.py +0 -0
  45. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_streams.py +0 -0
  46. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_sync.py +0 -0
  47. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_transform.py +0 -0
  48. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_typing.py +0 -0
  49. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/_utils/_utils.py +0 -0
  50. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/lib/.keep +0 -0
  51. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/py.typed +0 -0
  52. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/__init__.py +0 -0
  53. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/extensions.py +0 -0
  54. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/profiles.py +0 -0
  55. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/__init__.py +0 -0
  56. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/all.py +0 -0
  57. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/clipboard.py +0 -0
  58. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/keyboard.py +0 -0
  59. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/mouse.py +0 -0
  60. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/recordings/__init__.py +0 -0
  61. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/recordings/primary.py +0 -0
  62. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/recordings/recordings.py +0 -0
  63. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/sessions/sessions.py +0 -0
  64. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/resources/tools.py +0 -0
  65. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/__init__.py +0 -0
  66. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_delete_response.py +0 -0
  67. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_list_response.py +0 -0
  68. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_retrieve_response.py +0 -0
  69. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_upload_params.py +0 -0
  70. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/extension_upload_response.py +0 -0
  71. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/profile_create_params.py +0 -0
  72. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/profile_list_response.py +0 -0
  73. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/profile_retrieve_response.py +0 -0
  74. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/profile_update_params.py +0 -0
  75. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_copy_response.py +0 -0
  76. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_create_params.py +0 -0
  77. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_create_response.py +0 -0
  78. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_drag_and_drop_params.py +0 -0
  79. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_drag_and_drop_response.py +0 -0
  80. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_goto_params.py +0 -0
  81. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_goto_response.py +0 -0
  82. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_paste_params.py +0 -0
  83. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_paste_response.py +0 -0
  84. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_retrieve_downloads_response.py +0 -0
  85. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_scroll_params.py +0 -0
  86. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/session_scroll_response.py +0 -0
  87. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/__init__.py +0 -0
  88. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/all_status_response.py +0 -0
  89. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/clipboard_get_response.py +0 -0
  90. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/clipboard_set_params.py +0 -0
  91. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/clipboard_set_response.py +0 -0
  92. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/keyboard_shortcut_params.py +0 -0
  93. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/keyboard_shortcut_response.py +0 -0
  94. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/keyboard_type_params.py +0 -0
  95. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/keyboard_type_response.py +0 -0
  96. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_click_params.py +0 -0
  97. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_click_response.py +0 -0
  98. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_double_click_params.py +0 -0
  99. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_double_click_response.py +0 -0
  100. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_down_params.py +0 -0
  101. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_down_response.py +0 -0
  102. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_move_params.py +0 -0
  103. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_move_response.py +0 -0
  104. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_up_params.py +0 -0
  105. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/mouse_up_response.py +0 -0
  106. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/recording_list_response.py +0 -0
  107. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/recording_pause_response.py +0 -0
  108. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/recording_resume_response.py +0 -0
  109. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/sessions/recordings/__init__.py +0 -0
  110. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/shared/__init__.py +0 -0
  111. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/shared/success_response.py +0 -0
  112. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/tool_fetch_webpage_params.py +0 -0
  113. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/tool_fetch_webpage_response.py +0 -0
  114. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/tool_perform_web_task_params.py +0 -0
  115. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/tool_perform_web_task_response.py +0 -0
  116. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/src/anchorbrowser/types/tool_screenshot_webpage_params.py +0 -0
  117. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/__init__.py +0 -0
  118. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/__init__.py +0 -0
  119. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/__init__.py +0 -0
  120. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/recordings/__init__.py +0 -0
  121. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/recordings/test_primary.py +0 -0
  122. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/test_all.py +0 -0
  123. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/test_clipboard.py +0 -0
  124. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/test_keyboard.py +0 -0
  125. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/test_mouse.py +0 -0
  126. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/sessions/test_recordings.py +0 -0
  127. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/test_extensions.py +0 -0
  128. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/test_profiles.py +0 -0
  129. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/test_sessions.py +0 -0
  130. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/api_resources/test_tools.py +0 -0
  131. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/conftest.py +0 -0
  132. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/sample_file.txt +0 -0
  133. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_client.py +0 -0
  134. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_deepcopy.py +0 -0
  135. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_extract_files.py +0 -0
  136. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_files.py +0 -0
  137. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_qs.py +0 -0
  138. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_required_args.py +0 -0
  139. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_response.py +0 -0
  140. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_streaming.py +0 -0
  141. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_transform.py +0 -0
  142. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_utils/test_proxy.py +0 -0
  143. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/test_utils/test_typing.py +0 -0
  144. {anchorbrowser-0.1.0a1 → anchorbrowser-0.1.0a3}/tests/utils.py +0 -0
@@ -1,5 +1,4 @@
1
1
  .prism.log
2
- .vscode
3
2
  _dev
4
3
 
5
4
  __pycache__
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.3"
3
+ }
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.3 (2025-07-25)
4
+
5
+ Full Changelog: [v0.1.0-alpha.2...v0.1.0-alpha.3](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/compare/v0.1.0-alpha.2...v0.1.0-alpha.3)
6
+
7
+ ### Chores
8
+
9
+ * **project:** add settings file for vscode ([700d561](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/commit/700d5613b0d22d41afa095b4dc4e62d8cfb822ae))
10
+
11
+ ## 0.1.0-alpha.2 (2025-07-23)
12
+
13
+ Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/compare/v0.1.0-alpha.1...v0.1.0-alpha.2)
14
+
15
+ ### Features
16
+
17
+ * **agent:** add Agent and Browser resources for AI task execution ([36eab12](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/commit/36eab12a4d3ea747a6f863c3c43cc51a03461ba4))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **parsing:** parse extra field types ([0348a34](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/commit/0348a34079f2fc5ecf9ad5d5eaf1fed486d0263c))
23
+
24
+
25
+ ### Refactors
26
+
27
+ * add type hints to agent and browser resource methods for improved clarity ([047d45c](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/commit/047d45c79efd205353f21b9ec6d9960d332ddc94))
28
+
3
29
  ## 0.1.0-alpha.1 (2025-07-22)
4
30
 
5
31
  Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/anchorbrowser/AnchorBrowser-SDK-Python/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: anchorbrowser
3
- Version: 0.1.0a1
3
+ Version: 0.1.0a3
4
4
  Summary: The official Python library for the anchorbrowser API
5
5
  Project-URL: Homepage, https://github.com/anchorbrowser/AnchorBrowser-SDK-Python
6
6
  Project-URL: Repository, https://github.com/anchorbrowser/AnchorBrowser-SDK-Python
@@ -26,8 +26,10 @@ Requires-Dist: anyio<5,>=3.5.0
26
26
  Requires-Dist: distro<2,>=1.7.0
27
27
  Requires-Dist: httpx<1,>=0.23.0
28
28
  Requires-Dist: pydantic<3,>=1.9.0
29
+ Requires-Dist: pytest-playwright
29
30
  Requires-Dist: sniffio
30
31
  Requires-Dist: typing-extensions<5,>=4.10
32
+ Requires-Dist: websockets
31
33
  Provides-Extra: aiohttp
32
34
  Requires-Dist: aiohttp; extra == 'aiohttp'
33
35
  Requires-Dist: httpx-aiohttp>=0.1.8; extra == 'aiohttp'
@@ -1,19 +1,19 @@
1
1
  [project]
2
2
  name = "anchorbrowser"
3
- version = "0.1.0-alpha.1"
3
+ version = "0.1.0-alpha.3"
4
4
  description = "The official Python library for the anchorbrowser API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
7
- authors = [
8
- { name = "Anchorbrowser", email = "support@anchorbrowser.io" },
9
- ]
7
+ authors = [{ name = "Anchorbrowser", email = "support@anchorbrowser.io" }]
10
8
  dependencies = [
11
- "httpx>=0.23.0, <1",
12
- "pydantic>=1.9.0, <3",
13
- "typing-extensions>=4.10, <5",
14
- "anyio>=3.5.0, <5",
15
- "distro>=1.7.0, <2",
16
- "sniffio",
9
+ "httpx>=0.23.0, <1",
10
+ "pydantic>=1.9.0, <3",
11
+ "typing-extensions>=4.10, <5",
12
+ "anyio>=3.5.0, <5",
13
+ "distro>=1.7.0, <2",
14
+ "sniffio",
15
+ "pytest-playwright",
16
+ "websockets",
17
17
  ]
18
18
  requires-python = ">= 3.8"
19
19
  classifiers = [
@@ -31,7 +31,7 @@ classifiers = [
31
31
  "Operating System :: POSIX :: Linux",
32
32
  "Operating System :: Microsoft :: Windows",
33
33
  "Topic :: Software Development :: Libraries :: Python Modules",
34
- "License :: OSI Approved :: Apache Software License"
34
+ "License :: OSI Approved :: Apache Software License",
35
35
  ]
36
36
 
37
37
  [project.urls]
@@ -45,19 +45,19 @@ aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"]
45
45
  managed = true
46
46
  # version pins are in requirements-dev.lock
47
47
  dev-dependencies = [
48
- "pyright==1.1.399",
49
- "mypy",
50
- "respx",
51
- "pytest",
52
- "pytest-asyncio",
53
- "ruff",
54
- "time-machine",
55
- "nox",
56
- "dirty-equals>=0.6.0",
57
- "importlib-metadata>=6.7.0",
58
- "rich>=13.7.1",
59
- "nest_asyncio==1.6.0",
60
- "pytest-xdist>=3.6.1",
48
+ "pyright==1.1.399",
49
+ "mypy",
50
+ "respx",
51
+ "pytest",
52
+ "pytest-asyncio",
53
+ "ruff",
54
+ "time-machine",
55
+ "nox",
56
+ "dirty-equals>=0.6.0",
57
+ "importlib-metadata>=6.7.0",
58
+ "rich>=13.7.1",
59
+ "nest_asyncio==1.6.0",
60
+ "pytest-xdist>=3.6.1",
61
61
  ]
62
62
 
63
63
  [tool.rye.scripts]
@@ -67,24 +67,17 @@ format = { chain = [
67
67
  "fix:ruff",
68
68
  # run formatting again to fix any inconsistencies when imports are stripped
69
69
  "format:ruff",
70
- ]}
70
+ ] }
71
71
  "format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md"
72
72
  "format:ruff" = "ruff format"
73
73
 
74
- "lint" = { chain = [
75
- "check:ruff",
76
- "typecheck",
77
- "check:importable",
78
- ]}
74
+ "lint" = { chain = ["check:ruff", "typecheck", "check:importable"] }
79
75
  "check:ruff" = "ruff check ."
80
76
  "fix:ruff" = "ruff check --fix ."
81
77
 
82
78
  "check:importable" = "python -c 'import anchorbrowser'"
83
79
 
84
- typecheck = { chain = [
85
- "typecheck:pyright",
86
- "typecheck:mypy"
87
- ]}
80
+ typecheck = { chain = ["typecheck:pyright", "typecheck:mypy"] }
88
81
  "typecheck:pyright" = "pyright"
89
82
  "typecheck:verify-types" = "pyright --verifytypes anchorbrowser --ignoreexternal"
90
83
  "typecheck:mypy" = "mypy ."
@@ -94,9 +87,7 @@ requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"]
94
87
  build-backend = "hatchling.build"
95
88
 
96
89
  [tool.hatch.build]
97
- include = [
98
- "src/*"
99
- ]
90
+ include = ["src/*"]
100
91
 
101
92
  [tool.hatch.build.targets.wheel]
102
93
  packages = ["src/anchorbrowser"]
@@ -133,9 +124,7 @@ addopts = "--tb=short -n auto"
133
124
  xfail_strict = true
134
125
  asyncio_mode = "auto"
135
126
  asyncio_default_fixture_loop_scope = "session"
136
- filterwarnings = [
137
- "error"
138
- ]
127
+ filterwarnings = ["error"]
139
128
 
140
129
  [tool.pyright]
141
130
  # this enables practically every flag given by pyright.
@@ -144,11 +133,7 @@ filterwarnings = [
144
133
  typeCheckingMode = "strict"
145
134
  pythonVersion = "3.8"
146
135
 
147
- exclude = [
148
- "_dev",
149
- ".venv",
150
- ".nox",
151
- ]
136
+ exclude = ["_dev", ".venv", ".nox"]
152
137
 
153
138
  reportImplicitOverride = true
154
139
  reportOverlappingOverload = false
@@ -31,6 +31,9 @@ attrs==25.3.0
31
31
  certifi==2023.7.22
32
32
  # via httpcore
33
33
  # via httpx
34
+ # via requests
35
+ charset-normalizer==3.4.2
36
+ # via requests
34
37
  colorlog==6.7.0
35
38
  # via nox
36
39
  dirty-equals==0.6.0
@@ -48,6 +51,8 @@ filelock==3.12.4
48
51
  frozenlist==1.6.2
49
52
  # via aiohttp
50
53
  # via aiosignal
54
+ greenlet==3.2.3
55
+ # via playwright
51
56
  h11==0.16.0
52
57
  # via httpcore
53
58
  httpcore==1.0.9
@@ -61,6 +66,7 @@ httpx-aiohttp==0.1.8
61
66
  idna==3.4
62
67
  # via anyio
63
68
  # via httpx
69
+ # via requests
64
70
  # via yarl
65
71
  importlib-metadata==7.0.0
66
72
  iniconfig==2.0.0
@@ -84,6 +90,8 @@ packaging==23.2
84
90
  # via pytest
85
91
  platformdirs==3.11.0
86
92
  # via virtualenv
93
+ playwright==1.53.0
94
+ # via pytest-playwright
87
95
  pluggy==1.5.0
88
96
  # via pytest
89
97
  propcache==0.3.1
@@ -93,18 +101,30 @@ pydantic==2.10.3
93
101
  # via anchorbrowser
94
102
  pydantic-core==2.27.1
95
103
  # via pydantic
104
+ pyee==13.0.0
105
+ # via playwright
96
106
  pygments==2.18.0
97
107
  # via rich
98
108
  pyright==1.1.399
99
109
  pytest==8.3.3
100
110
  # via pytest-asyncio
111
+ # via pytest-base-url
112
+ # via pytest-playwright
101
113
  # via pytest-xdist
102
114
  pytest-asyncio==0.24.0
115
+ pytest-base-url==2.1.0
116
+ # via pytest-playwright
117
+ pytest-playwright==0.7.0
118
+ # via anchorbrowser
103
119
  pytest-xdist==3.7.0
104
120
  python-dateutil==2.8.2
105
121
  # via time-machine
122
+ python-slugify==8.0.4
123
+ # via pytest-playwright
106
124
  pytz==2023.3.post1
107
125
  # via dirty-equals
126
+ requests==2.32.4
127
+ # via pytest-base-url
108
128
  respx==0.22.0
109
129
  rich==13.7.1
110
130
  ruff==0.9.4
@@ -115,6 +135,8 @@ six==1.16.0
115
135
  sniffio==1.3.0
116
136
  # via anchorbrowser
117
137
  # via anyio
138
+ text-unidecode==1.3
139
+ # via python-slugify
118
140
  time-machine==2.9.0
119
141
  tomli==2.0.2
120
142
  # via mypy
@@ -126,9 +148,14 @@ typing-extensions==4.12.2
126
148
  # via mypy
127
149
  # via pydantic
128
150
  # via pydantic-core
151
+ # via pyee
129
152
  # via pyright
153
+ urllib3==2.5.0
154
+ # via requests
130
155
  virtualenv==20.24.5
131
156
  # via nox
157
+ websockets==15.0.1
158
+ # via anchorbrowser
132
159
  yarl==1.20.0
133
160
  # via aiohttp
134
161
  zipp==3.17.0
@@ -29,13 +29,19 @@ attrs==25.3.0
29
29
  certifi==2023.7.22
30
30
  # via httpcore
31
31
  # via httpx
32
+ # via requests
33
+ charset-normalizer==3.4.2
34
+ # via requests
32
35
  distro==1.8.0
33
36
  # via anchorbrowser
34
37
  exceptiongroup==1.2.2
35
38
  # via anyio
39
+ # via pytest
36
40
  frozenlist==1.6.2
37
41
  # via aiohttp
38
42
  # via aiosignal
43
+ greenlet==3.2.3
44
+ # via playwright
39
45
  h11==0.16.0
40
46
  # via httpcore
41
47
  httpcore==1.0.9
@@ -48,10 +54,19 @@ httpx-aiohttp==0.1.8
48
54
  idna==3.4
49
55
  # via anyio
50
56
  # via httpx
57
+ # via requests
51
58
  # via yarl
59
+ iniconfig==2.1.0
60
+ # via pytest
52
61
  multidict==6.4.4
53
62
  # via aiohttp
54
63
  # via yarl
64
+ packaging==25.0
65
+ # via pytest
66
+ playwright==1.53.0
67
+ # via pytest-playwright
68
+ pluggy==1.6.0
69
+ # via pytest
55
70
  propcache==0.3.1
56
71
  # via aiohttp
57
72
  # via yarl
@@ -59,14 +74,38 @@ pydantic==2.10.3
59
74
  # via anchorbrowser
60
75
  pydantic-core==2.27.1
61
76
  # via pydantic
77
+ pyee==13.0.0
78
+ # via playwright
79
+ pygments==2.19.2
80
+ # via pytest
81
+ pytest==8.4.1
82
+ # via pytest-base-url
83
+ # via pytest-playwright
84
+ pytest-base-url==2.1.0
85
+ # via pytest-playwright
86
+ pytest-playwright==0.7.0
87
+ # via anchorbrowser
88
+ python-slugify==8.0.4
89
+ # via pytest-playwright
90
+ requests==2.32.4
91
+ # via pytest-base-url
62
92
  sniffio==1.3.0
63
93
  # via anchorbrowser
64
94
  # via anyio
95
+ text-unidecode==1.3
96
+ # via python-slugify
97
+ tomli==2.2.1
98
+ # via pytest
65
99
  typing-extensions==4.12.2
66
100
  # via anchorbrowser
67
101
  # via anyio
68
102
  # via multidict
69
103
  # via pydantic
70
104
  # via pydantic-core
105
+ # via pyee
106
+ urllib3==2.5.0
107
+ # via requests
108
+ websockets==15.0.1
109
+ # via anchorbrowser
71
110
  yarl==1.20.0
72
111
  # via aiohttp
@@ -21,7 +21,7 @@ from ._types import (
21
21
  )
22
22
  from ._utils import is_given, get_async_library
23
23
  from ._version import __version__
24
- from .resources import tools, profiles, extensions
24
+ from .resources import agent, tools, browser, profiles, extensions
25
25
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
26
26
  from ._exceptions import APIStatusError, AnchorbrowserError
27
27
  from ._base_client import (
@@ -48,6 +48,8 @@ class Anchorbrowser(SyncAPIClient):
48
48
  sessions: sessions.SessionsResource
49
49
  tools: tools.ToolsResource
50
50
  extensions: extensions.ExtensionsResource
51
+ browser: browser.BrowserResource
52
+ agent: agent.AgentResource
51
53
  with_raw_response: AnchorbrowserWithRawResponse
52
54
  with_streaming_response: AnchorbrowserWithStreamedResponse
53
55
 
@@ -109,6 +111,8 @@ class Anchorbrowser(SyncAPIClient):
109
111
  self.sessions = sessions.SessionsResource(self)
110
112
  self.tools = tools.ToolsResource(self)
111
113
  self.extensions = extensions.ExtensionsResource(self)
114
+ self.browser = browser.BrowserResource(self)
115
+ self.agent = agent.AgentResource(self)
112
116
  self.with_raw_response = AnchorbrowserWithRawResponse(self)
113
117
  self.with_streaming_response = AnchorbrowserWithStreamedResponse(self)
114
118
 
@@ -222,6 +226,8 @@ class AsyncAnchorbrowser(AsyncAPIClient):
222
226
  sessions: sessions.AsyncSessionsResource
223
227
  tools: tools.AsyncToolsResource
224
228
  extensions: extensions.AsyncExtensionsResource
229
+ browser: browser.AsyncBrowserResource
230
+ agent: agent.AsyncAgentResource
225
231
  with_raw_response: AsyncAnchorbrowserWithRawResponse
226
232
  with_streaming_response: AsyncAnchorbrowserWithStreamedResponse
227
233
 
@@ -283,6 +289,8 @@ class AsyncAnchorbrowser(AsyncAPIClient):
283
289
  self.sessions = sessions.AsyncSessionsResource(self)
284
290
  self.tools = tools.AsyncToolsResource(self)
285
291
  self.extensions = extensions.AsyncExtensionsResource(self)
292
+ self.browser = browser.AsyncBrowserResource(self)
293
+ self.agent = agent.AsyncAgentResource(self)
286
294
  self.with_raw_response = AsyncAnchorbrowserWithRawResponse(self)
287
295
  self.with_streaming_response = AsyncAnchorbrowserWithStreamedResponse(self)
288
296
 
@@ -397,7 +405,8 @@ class AnchorbrowserWithRawResponse:
397
405
  self.sessions = sessions.SessionsResourceWithRawResponse(client.sessions)
398
406
  self.tools = tools.ToolsResourceWithRawResponse(client.tools)
399
407
  self.extensions = extensions.ExtensionsResourceWithRawResponse(client.extensions)
400
-
408
+ self.browser = browser.BrowserResourceWithRawResponse(client.browser)
409
+ self.agent = agent.AgentResourceWithRawResponse(client.agent)
401
410
 
402
411
  class AsyncAnchorbrowserWithRawResponse:
403
412
  def __init__(self, client: AsyncAnchorbrowser) -> None:
@@ -405,7 +414,8 @@ class AsyncAnchorbrowserWithRawResponse:
405
414
  self.sessions = sessions.AsyncSessionsResourceWithRawResponse(client.sessions)
406
415
  self.tools = tools.AsyncToolsResourceWithRawResponse(client.tools)
407
416
  self.extensions = extensions.AsyncExtensionsResourceWithRawResponse(client.extensions)
408
-
417
+ self.browser = browser.AsyncBrowserResourceWithRawResponse(client.browser)
418
+ self.agent = agent.AsyncAgentResourceWithRawResponse(client.agent)
409
419
 
410
420
  class AnchorbrowserWithStreamedResponse:
411
421
  def __init__(self, client: Anchorbrowser) -> None:
@@ -413,7 +423,8 @@ class AnchorbrowserWithStreamedResponse:
413
423
  self.sessions = sessions.SessionsResourceWithStreamingResponse(client.sessions)
414
424
  self.tools = tools.ToolsResourceWithStreamingResponse(client.tools)
415
425
  self.extensions = extensions.ExtensionsResourceWithStreamingResponse(client.extensions)
416
-
426
+ self.browser = browser.BrowserResourceWithStreamingResponse(client.browser)
427
+ self.agent = agent.AgentResourceWithStreamingResponse(client.agent)
417
428
 
418
429
  class AsyncAnchorbrowserWithStreamedResponse:
419
430
  def __init__(self, client: AsyncAnchorbrowser) -> None:
@@ -421,7 +432,8 @@ class AsyncAnchorbrowserWithStreamedResponse:
421
432
  self.sessions = sessions.AsyncSessionsResourceWithStreamingResponse(client.sessions)
422
433
  self.tools = tools.AsyncToolsResourceWithStreamingResponse(client.tools)
423
434
  self.extensions = extensions.AsyncExtensionsResourceWithStreamingResponse(client.extensions)
424
-
435
+ self.browser = browser.AsyncBrowserResourceWithStreamingResponse(client.browser)
436
+ self.agent = agent.AsyncAgentResourceWithStreamingResponse(client.agent)
425
437
 
426
438
  Client = Anchorbrowser
427
439
 
@@ -208,14 +208,18 @@ class BaseModel(pydantic.BaseModel):
208
208
  else:
209
209
  fields_values[name] = field_get_default(field)
210
210
 
211
+ extra_field_type = _get_extra_fields_type(__cls)
212
+
211
213
  _extra = {}
212
214
  for key, value in values.items():
213
215
  if key not in model_fields:
216
+ parsed = construct_type(value=value, type_=extra_field_type) if extra_field_type is not None else value
217
+
214
218
  if PYDANTIC_V2:
215
- _extra[key] = value
219
+ _extra[key] = parsed
216
220
  else:
217
221
  _fields_set.add(key)
218
- fields_values[key] = value
222
+ fields_values[key] = parsed
219
223
 
220
224
  object.__setattr__(m, "__dict__", fields_values)
221
225
 
@@ -370,6 +374,23 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
370
374
  return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None))
371
375
 
372
376
 
377
+ def _get_extra_fields_type(cls: type[pydantic.BaseModel]) -> type | None:
378
+ if not PYDANTIC_V2:
379
+ # TODO
380
+ return None
381
+
382
+ schema = cls.__pydantic_core_schema__
383
+ if schema["type"] == "model":
384
+ fields = schema["schema"]
385
+ if fields["type"] == "model-fields":
386
+ extras = fields.get("extras_schema")
387
+ if extras and "cls" in extras:
388
+ # mypy can't narrow the type
389
+ return extras["cls"] # type: ignore[no-any-return]
390
+
391
+ return None
392
+
393
+
373
394
  def is_basemodel(type_: type) -> bool:
374
395
  """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`"""
375
396
  if is_union(type_):
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "anchorbrowser"
4
- __version__ = "0.1.0-alpha.1" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.3" # x-release-please-version
@@ -0,0 +1,69 @@
1
+ import json
2
+ import asyncio
3
+ import threading
4
+ from typing import Any, Dict, Callable, Optional, TypedDict
5
+ from asyncio import Future
6
+
7
+ from ..lib.browser import BrowserSetup, get_agent_ws_url
8
+
9
+
10
+ class AgentTaskParams(TypedDict, total=False):
11
+ url: Optional[str]
12
+ output_schema: Optional[Dict[str, Any]]
13
+ on_agent_step: Optional[Callable[[str], None]]
14
+
15
+
16
+ def create_task_payload(prompt: str, output_schema: Optional[Dict[str, Any]] = None) -> str:
17
+ if not prompt or prompt.strip() == "":
18
+ raise ValueError("Prompt cannot be empty")
19
+
20
+ return json.dumps(
21
+ {
22
+ "prompt": prompt,
23
+ "output_schema": output_schema,
24
+ }
25
+ )
26
+
27
+
28
+ def on_agent_step_sync(on_agent_step: Callable[[str], None], browser_setup: BrowserSetup) -> Future[None]:
29
+ import websockets
30
+
31
+ async def websocket_listener() -> None:
32
+ ws_url = get_agent_ws_url(browser_setup.base_url, browser_setup.session_id)
33
+ try:
34
+ async with websockets.connect(ws_url) as ws:
35
+ async for ws_msg in ws:
36
+ on_agent_step(str(ws_msg))
37
+ except Exception as e:
38
+ future.set_exception(e)
39
+
40
+ def run_in_thread() -> None:
41
+ loop = asyncio.new_event_loop()
42
+ asyncio.set_event_loop(loop)
43
+ try:
44
+ loop.run_until_complete(websocket_listener())
45
+ finally:
46
+ loop.close()
47
+
48
+ # Create a future to track the task
49
+ future = Future[None]()
50
+ try:
51
+ thread = threading.Thread(target=lambda: future.set_result(run_in_thread()))
52
+ thread.daemon = True
53
+ thread.start()
54
+ except Exception:
55
+ pass
56
+
57
+ return future
58
+
59
+
60
+ def on_agent_step_async(on_agent_step: Callable[[str], None], browser_setup: BrowserSetup) -> None:
61
+ import websockets
62
+
63
+ async def websocket_listener() -> None:
64
+ ws_url = get_agent_ws_url(browser_setup.base_url, browser_setup.session_id)
65
+ async with websockets.connect(ws_url) as ws:
66
+ async for ws_msg in ws:
67
+ on_agent_step(str(ws_msg))
68
+
69
+ asyncio.create_task(websocket_listener())