bytekit-sdk 0.3.2__tar.gz → 0.3.4__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.
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/.gitignore +8 -0
- bytekit_sdk-0.3.4/CHANGELOG.md +192 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/PKG-INFO +35 -4
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/README.md +34 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/pyproject.toml +32 -2
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/account/get_account.py +15 -10
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/bulk/create_bulk.py +104 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/bulk/delete_bulk.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/bulk/get_bulk.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/bulk/list_bulk_screenshots.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch/get_fetch.py +31 -27
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch/post_fetch.py +16 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch_bulk/create_fetch_bulk.py +44 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch_bulk/get_fetch_bulk.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/create_monitor.py +12 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/delete_monitor.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/get_monitor.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/list_monitor_captures.py +11 -12
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/list_monitors.py +18 -18
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/update_monitor.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape/get_scrape.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape_bulk/get_scrape_bulk.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/screenshots/create_screenshot.py +25 -9
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/screenshots/get_screenshot.py +2 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/sitemap/create_sitemap.py +16 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/sitemap/get_sitemap.py +6 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/webhooks/list_webhook_deliveries.py +9 -9
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/webhooks/retry_webhook_delivery.py +22 -3
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/client.py +82 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/__init__.py +22 -6
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body.py +16 -20
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults.py +27 -52
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item.py +4 -24
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_response_202.py +21 -8
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_fetch_bulk_body.py +6 -6
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_fetch_bulk_body_defaults.py +4 -4
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_fetch_bulk_body_urls_item_type_1.py +1 -20
- bytekit_sdk-0.3.4/src/bytekit/models/create_fetch_bulk_response_202.py +179 -0
- bytekit_sdk-0.3.4/src/bytekit/models/create_fetch_bulk_response_202_status.py +10 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_defaults.py +7 -8
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_items_item.py +7 -12
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_response_202.py +21 -8
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_body.py +5 -10
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_response_200_results_item.py +6 -5
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/delete_bulk_response_200.py +17 -8
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_bulk_response_200.py +17 -8
- bytekit_sdk-0.3.4/src/bytekit/models/get_fetch_bulk_response_200.py +201 -0
- bytekit_sdk-0.3.4/src/bytekit/models/get_fetch_bulk_response_200_items_item.py +211 -0
- bytekit_sdk-0.3.4/src/bytekit/models/get_fetch_bulk_response_200_items_item_status.py +12 -0
- bytekit_sdk-0.3.4/src/bytekit/models/get_fetch_bulk_response_200_status.py +10 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_scrape_bulk_response_200.py +17 -8
- bytekit_sdk-0.3.4/src/bytekit/models/list_bulk_screenshots_response_200.py +100 -0
- bytekit_sdk-0.3.4/src/bytekit/models/list_bulk_screenshots_response_200_items_item.py +344 -0
- bytekit_sdk-0.3.4/src/bytekit/models/list_bulk_screenshots_response_200_items_item_status.py +12 -0
- bytekit_sdk-0.3.4/src/bytekit/models/list_bulk_screenshots_response_200_items_item_type.py +10 -0
- bytekit_sdk-0.3.2/CHANGELOG.md +0 -89
- bytekit_sdk-0.3.2/src/bytekit/models/create_fetch_bulk_body_metadata.py +0 -44
- bytekit_sdk-0.3.2/src/bytekit/models/create_fetch_bulk_response_202.py +0 -44
- bytekit_sdk-0.3.2/src/bytekit/models/create_scrape_bulk_body_items_item_metadata.py +0 -44
- bytekit_sdk-0.3.2/src/bytekit/models/get_fetch_bulk_response_200.py +0 -44
- bytekit_sdk-0.3.2/src/bytekit/models/list_bulk_screenshots_response_200.py +0 -44
- bytekit_sdk-0.3.2/tests/__init__.py +0 -0
- bytekit_sdk-0.3.2/tests/conftest.py +0 -97
- bytekit_sdk-0.3.2/tests/fixtures/unpatched_client.py.snapshot +0 -365
- bytekit_sdk-0.3.2/tests/fixtures/unpatched_create_scrape.py.snapshot +0 -197
- bytekit_sdk-0.3.2/tests/fixtures/unpatched_delete_monitor.py.snapshot +0 -155
- bytekit_sdk-0.3.2/tests/fixtures/unpatched_errors.py.snapshot +0 -16
- bytekit_sdk-0.3.2/tests/fixtures/unpatched_get_fetch.py.snapshot +0 -254
- bytekit_sdk-0.3.2/tests/test_bulk_delete.py +0 -33
- bytekit_sdk-0.3.2/tests/test_client.py +0 -121
- bytekit_sdk-0.3.2/tests/test_client_defaults.py +0 -122
- bytekit_sdk-0.3.2/tests/test_deactivated_resources.py +0 -108
- bytekit_sdk-0.3.2/tests/test_generate_docs.py +0 -285
- bytekit_sdk-0.3.2/tests/test_models.py +0 -178
- bytekit_sdk-0.3.2/tests/test_no_materialized_defaults.py +0 -31
- bytekit_sdk-0.3.2/tests/test_op_error_paths.py +0 -360
- bytekit_sdk-0.3.2/tests/test_package_identity.py +0 -24
- bytekit_sdk-0.3.2/tests/test_patch_functions.py +0 -308
- bytekit_sdk-0.3.2/tests/test_prune_stale_api.py +0 -753
- bytekit_sdk-0.3.2/tests/test_publish_metadata.py +0 -179
- bytekit_sdk-0.3.2/tests/test_readme_examples.py +0 -127
- bytekit_sdk-0.3.2/tests/test_regen_durability.py +0 -170
- bytekit_sdk-0.3.2/tests/test_removed_surface.py +0 -50
- bytekit_sdk-0.3.2/tests/test_scrape_markdown_opts.py +0 -157
- bytekit_sdk-0.3.2/tests/test_scrape_scored_formats.py +0 -135
- bytekit_sdk-0.3.2/tests/test_sdist_contents.py +0 -182
- bytekit_sdk-0.3.2/tests/test_search.py +0 -209
- bytekit_sdk-0.3.2/tests/test_search_errors.py +0 -97
- bytekit_sdk-0.3.2/tests/test_spec_field_parity.py +0 -106
- bytekit_sdk-0.3.2/tests/test_typed_search_surface.py +0 -181
- bytekit_sdk-0.3.2/tests/test_usage.py +0 -80
- bytekit_sdk-0.3.2/tests/test_version.py +0 -110
- bytekit_sdk-0.3.2/tests/test_webhook_deliveries.py +0 -59
- bytekit_sdk-0.3.2/tests/test_wheel_contents.py +0 -109
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/LICENSE +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/account/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/bulk/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/fetch_bulk/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/monitors/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape/create_scrape.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape_bulk/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/scrape_bulk/create_scrape_bulk.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/screenshots/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/search/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/search/create_search.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/sitemap/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/usage/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/usage/get_usage.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/usage/get_usage_by_endpoint.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/usage/get_usage_daily.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/api/webhooks/__init__.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/errors.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_api_key.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_api_key_environment.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_auto_topup.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_plan.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_subscription.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_subscription_plan.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_bearer_response_subscription_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_session_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_session_response_notifications.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/account_session_response_plan.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/bandwidth_balance.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/capture_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/capture_response_outcome.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/clip.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/cookie.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_device.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_2_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_3_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_formats_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_viewport_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_defaults_wait_until.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_device.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_formats_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_scenario.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_viewport_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_body_items_item_wait_until.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_bulk_response_202_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_fetch_bulk_body_defaults_format.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_fetch_bulk_body_urls_item_type_1_format.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_custom.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_defaults_formats_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_defaults_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_items_item_custom.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_items_item_formats_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_body_items_item_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_scrape_bulk_response_202_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_body_date_range.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_body_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_response_200_results_item_image.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_response_502.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/create_search_response_502_error.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/credit_balance.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/delete_bulk_response_200_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/error.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/error_error.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/error_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_cache_ttl_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_custom.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_format.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_markdown_images.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_markdown_links.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/fetch_request_markdown_mode.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_bulk_response_200_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_fetch_cache_ttl_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_fetch_format.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_scrape_bulk_response_200_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_by_endpoint_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_by_endpoint_response_200_rows_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_by_endpoint_response_200_rows_item_endpoint.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_by_endpoint_response_200_totals.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_daily_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_daily_response_200_data_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/get_usage_response_200_plan_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/list_monitor_captures_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/list_monitors_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/list_monitors_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/list_webhook_deliveries_response_200.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/list_webhook_deliveries_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/metadata.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_interval_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_notify_on.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_options.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_scrape_options.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_request_webhook_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_create_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response_interval_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response_metadata_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_response_webhook_headers_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_interval_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_notify_on.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_options.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_scrape_options.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/monitor_update_request_webhook_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_error_envelope.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_error_envelope_error.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_error_envelope_error_code.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_error_envelope_schema_version.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_error_envelope_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_formats.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_markdown_tokens.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_metadata.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_queued_envelope.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_queued_envelope_schema_version.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_queued_envelope_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_cache_ttl_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_custom.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_events_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_formats_item.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_markdown_images.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_markdown_links.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_markdown_mode.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_token_encoding.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_request_x_internal_scrape_path.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_scored_image.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_scored_link.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_stats.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_success_envelope.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_success_envelope_cache.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_success_envelope_custom.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_success_envelope_schema_version.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_success_envelope_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_table.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_table_kind.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_warning.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/scrape_warning_code.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_device.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_device_scale_factor_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_device_scale_factor_type_2_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_device_scale_factor_type_3_type_1.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_format.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_headers.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_request_wait_until.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/screenshot_response_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_request.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_request_process_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_request_process_type_0_options.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_request_strategy.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response_cache.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response_metadata_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response_process_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response_sources_type_0.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/sitemap_response_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/viewport.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/webhook_delivery_response.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/webhook_delivery_response_event_type.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/models/webhook_delivery_response_status.py +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/py.typed +0 -0
- {bytekit_sdk-0.3.2 → bytekit_sdk-0.3.4}/src/bytekit/types.py +0 -0
|
@@ -47,6 +47,14 @@ packages/http-fetcher/server
|
|
|
47
47
|
packages/http-fetcher/browserforge-bench
|
|
48
48
|
__pycache__/
|
|
49
49
|
*.pyc
|
|
50
|
+
# ruff's incremental cache. Written by the openapi-python-client post-hooks INSIDE the
|
|
51
|
+
# generated output dir (packages/sdk-python/src/bytekit/.ruff_cache/). ruff already drops a
|
|
52
|
+
# self-ignoring `.gitignore` containing `*` in there, which is exactly why the directory went
|
|
53
|
+
# unnoticed for so long — `git status` never mentions it. This entry is belt-and-braces so the
|
|
54
|
+
# by-product is ignored even if ruff stops self-ignoring. The reproducibility gate
|
|
55
|
+
# (ci/scripts/check-sdk-python-regen.sh) excludes it from BOTH of its diffs: cache entry names
|
|
56
|
+
# are hashes of the absolute path, so two clean-room generates differ by construction.
|
|
57
|
+
.ruff_cache/
|
|
50
58
|
# Generated artifact — reproduced via `pnpm --filter @rapidcrawl/sdk-python generate`
|
|
51
59
|
packages/sdk-python/filtered-openapi.yaml
|
|
52
60
|
# NOTE: the MCP server's generated docs JSON (see packages/mcp-server/src) is intentionally
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the ByteKit Python SDK are documented here.
|
|
4
|
+
PyPI distribution: `bytekit-sdk`. Import name: `bytekit`.
|
|
5
|
+
|
|
6
|
+
## 0.3.4
|
|
7
|
+
|
|
8
|
+
### Breaking
|
|
9
|
+
|
|
10
|
+
- **`CreateBulkBody`, `CreateBulkBodyDefaults`, `CreateBulkBodyItemsItem`, and
|
|
11
|
+
`CreateFetchBulkBodyUrlsItemType1` lost their additional-properties mapping API.**
|
|
12
|
+
`docs/api/openapi.yaml`'s `/v1/bulk` request schema declares `additionalProperties: false`
|
|
13
|
+
on the top-level body, `items[]`, and `defaults` (issue #2641), and `/v1/fetch/bulk`'s
|
|
14
|
+
per-item override schema inside `urls[]` declares the same (issue #2648), matching the
|
|
15
|
+
gateway's own `.strict()` validators. The code generator responds to
|
|
16
|
+
`additionalProperties: false` by omitting the catch-all mapping it otherwise attaches to
|
|
17
|
+
every generated model, so these four models no longer expose `additional_properties`, the
|
|
18
|
+
`additional_keys` property, `__getitem__`, `__setitem__`, `__delitem__`, or `__contains__`.
|
|
19
|
+
Code that did `body["some_key"] = value`, `"some_key" in body`, or read
|
|
20
|
+
`body.additional_keys` on any of these four models will now raise
|
|
21
|
+
`AttributeError`/`TypeError` instead. Use the model's declared `attrs` fields directly
|
|
22
|
+
instead (e.g. `CreateBulkBodyItemsItem(url=..., type=...)`,
|
|
23
|
+
`CreateFetchBulkBodyUrlsItemType1(url=..., format_=...)`); the server itself now rejects
|
|
24
|
+
unrecognized keys on these endpoints with `422 validation_error`, so the removed escape
|
|
25
|
+
hatch could never have reached the API successfully anyway. This is scoped to the four
|
|
26
|
+
`create_bulk_body*` / `create_fetch_bulk_body_urls_item_type_1` models — no other generated
|
|
27
|
+
model is affected.
|
|
28
|
+
|
|
29
|
+
## 0.3.3
|
|
30
|
+
|
|
31
|
+
### Security
|
|
32
|
+
|
|
33
|
+
- **Path parameters are now percent-encoded.** All 13 operations that interpolate an id into
|
|
34
|
+
their URL (`get_scrape`, `get_screenshot`, `get_bulk`, `delete_bulk`,
|
|
35
|
+
`list_bulk_screenshots`, `get_scrape_bulk`, `get_fetch_bulk`, `get_monitor`,
|
|
36
|
+
`update_monitor`, `delete_monitor`, `list_monitor_captures`, `get_sitemap`,
|
|
37
|
+
`retry_webhook_delivery`) previously interpolated the value raw, so an id containing `/`,
|
|
38
|
+
`?`, `#` or traversal segments could retarget the request to a **different path on the same
|
|
39
|
+
authenticated host** — e.g. a `DELETE /v1/bulk/{id}` becoming a delete against another
|
|
40
|
+
resource. Values are now encoded with `quote(str(value), safe="")`. This is **not** a
|
|
41
|
+
breaking change for any id the API issues: hex and `sc_`/`ss_`/`mon_`/`sm_`/`bulk_`-prefixed
|
|
42
|
+
ids contain no reserved characters, so the resulting URL is byte-identical to before.
|
|
43
|
+
No id-format validation was added — the client does not reject id shapes.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- **Reusing one client across several `asyncio.run(...)` calls no longer raises
|
|
48
|
+
`RuntimeError: Event loop is closed`.** An `httpx.AsyncClient`'s connection pool belongs to
|
|
49
|
+
the event loop that created it, and the SDK cached its internal async client
|
|
50
|
+
unconditionally. It now tracks which loop that client was built on and transparently
|
|
51
|
+
rebuilds it when the running loop changes, re-applying `base_url`, headers, timeout,
|
|
52
|
+
`httpx_args` and authentication. Behavior is unchanged when no loop is running, and a client
|
|
53
|
+
you supply via `set_async_httpx_client(...)` is **never** rebuilt or closed — it stays yours
|
|
54
|
+
to manage. See the README's new "Clients and event loops" section.
|
|
55
|
+
- **The README quick start now prints markdown instead of an `Unset` placeholder.** It
|
|
56
|
+
requested no `formats`, so the server applied its `raw_html` default and
|
|
57
|
+
`result.formats.markdown` was legitimately unset. It now asks for
|
|
58
|
+
`formats=[ScrapeRequestFormatsItem.MARKDOWN]` — note `formats` takes enum members, not plain
|
|
59
|
+
strings.
|
|
60
|
+
- **`client.search(type="images")` no longer crashes with a bare `KeyError: 'snippet'`.**
|
|
61
|
+
The OpenAPI spec's search result-item schema declared `snippet` as `required` while its
|
|
62
|
+
own description said the key is omitted for `images` results — a self-contradiction the
|
|
63
|
+
code generator trusted literally, so `CreateSearchResponse200ResultsItem.from_dict`
|
|
64
|
+
unconditionally did `d.pop("snippet")`. `snippet` (like `date`) is now `Union[Unset, str]`,
|
|
65
|
+
matching the real gateway behavior (`web`/`news` results still always carry `snippet`;
|
|
66
|
+
`images` results omit it entirely) — fixed at the spec level (`docs/api/openapi.yaml`) and
|
|
67
|
+
regenerated, not patched in the generated model. (Issue #2579.)
|
|
68
|
+
- **Server defaults are no longer materialized into request wire bodies/query strings
|
|
69
|
+
for inline request bodies and `$ref`'d parameters.** `scripts/filter-spec.ts`'s
|
|
70
|
+
default-stripping traversal previously only followed `$ref`'d request-body component
|
|
71
|
+
schemas, so `ScrapeRequest`/`FetchRequest` were clean but every other request-direction
|
|
72
|
+
shape kept baking in server defaults: `/v1/search`'s fully-inline body (`type`,
|
|
73
|
+
`limit`, `country`, `language`, `date_range`), all three bulk endpoints' bodies and
|
|
74
|
+
their nested `Defaults`/`ItemsItem` models, and `$ref`'d query parameters
|
|
75
|
+
(`GET /v1/fetch`'s `country`/`timeout_ms`/`cache_ttl`, `list_monitors`'
|
|
76
|
+
`limit`/`status`, `list_webhook_deliveries`'/`list_monitor_captures`' `limit`,
|
|
77
|
+
`create_screenshot`'s `async`). The traversal now walks inline request bodies AND
|
|
78
|
+
parameters (both operation-level and shared path-item-level, `$ref`'d or inline)
|
|
79
|
+
before generation, so an omitted optional field always serializes to nothing and
|
|
80
|
+
the server's own default applies — caller-supplied values are unaffected and still
|
|
81
|
+
serialize exactly as given (issue #2592).
|
|
82
|
+
- `tests/test_no_materialized_defaults.py` rewritten to enumerate every
|
|
83
|
+
request-direction model and operation parameter programmatically (walking the
|
|
84
|
+
generated `bytekit.api`/`bytekit.models` trees) instead of sampling two known-clean
|
|
85
|
+
models, so a newly introduced leaker is caught automatically.
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- **The source distribution no longer ships `tests/`.** The bundled suite could not be
|
|
90
|
+
collected from an unpacked sdist: 12 of its 27 modules require the repository's codegen
|
|
91
|
+
scripts or the canonical OpenAPI spec, neither of which belongs in a published
|
|
92
|
+
distribution, and three of them build distributions of the package itself. Nothing
|
|
93
|
+
importable was removed — the **wheel is unchanged**, `py.typed` included, so
|
|
94
|
+
`pip install bytekit-sdk` is unaffected.
|
|
95
|
+
|
|
96
|
+
### Internal
|
|
97
|
+
|
|
98
|
+
- CI now proves the committed client is reproducible from the canonical OpenAPI spec, and that
|
|
99
|
+
the generation chain is deterministic (generating twice yields byte-identical output). This
|
|
100
|
+
closes the gap where a spec change could land with a TypeScript-only regeneration and leave
|
|
101
|
+
the Python client silently stranded on an older spec.
|
|
102
|
+
- `ruff` is now pinned to an exact version alongside the code generator. The generator runs
|
|
103
|
+
`ruff` over everything it emits, so it — not the generator alone — determines the committed
|
|
104
|
+
bytes; the generator itself accepts any `ruff<0.13`, which meant a fresh install could
|
|
105
|
+
reformat the whole tree. Bumping the pin is a deliberate, reviewed reformat.
|
|
106
|
+
- The PEP 561 `py.typed` marker is now emitted by the post-generation injector rather than
|
|
107
|
+
hand-maintained inside the generated tree (the generator omits it under `--meta none`).
|
|
108
|
+
|
|
109
|
+
## 0.3.2
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **`bytekit.__version__`** reports the installed distribution version, resolved at import
|
|
114
|
+
time from `importlib.metadata` (so it can never drift from `pyproject.toml`'s
|
|
115
|
+
`[project].version`). When the package is imported from a source tree with no installed
|
|
116
|
+
distribution it reads `0.0.0.dev0` rather than raising. The dead version override in
|
|
117
|
+
`sdk-python-config.yaml` — inert under `--meta none` and contradicting the real
|
|
118
|
+
version — has been removed, leaving one authoritative version.
|
|
119
|
+
|
|
120
|
+
### Fixed
|
|
121
|
+
|
|
122
|
+
- **`AuthenticatedClient.search()` is now visible to type checkers.** It was attached to the
|
|
123
|
+
class after creation, so despite the package shipping a `py.typed` marker, `mypy` and
|
|
124
|
+
`pyright` reported `"AuthenticatedClient" has no attribute "search"`. It is now declared as a
|
|
125
|
+
real method in the class body that delegates to the same implementation: **runtime behavior,
|
|
126
|
+
arguments, return type and raised errors are unchanged** — only the static surface is fixed.
|
|
127
|
+
|
|
128
|
+
## 0.3.1
|
|
129
|
+
|
|
130
|
+
### Fixed
|
|
131
|
+
|
|
132
|
+
- **The "never a bare `json.JSONDecodeError`" guarantee is now package-wide across all
|
|
133
|
+
generated operations**, not only the `AuthenticatedClient.search()` wrapper. Every
|
|
134
|
+
generated operation previously called `response.json()` unconditionally on a
|
|
135
|
+
DOCUMENTED status, so a `500`/`502` serving an HTML load-balancer page raised a bare
|
|
136
|
+
`json.JSONDecodeError` from inside the SDK. All operations now parse documented
|
|
137
|
+
statuses through a shared guard: a non-JSON body raises the typed
|
|
138
|
+
`errors.UnexpectedStatus` (or returns `None` when
|
|
139
|
+
`raise_on_unexpected_status=False`), carrying the status code and the raw body.
|
|
140
|
+
- **`errors.UnexpectedStatus.code` / `.message` are now populated for generated
|
|
141
|
+
operations too**, from the documented `Error` envelope — previously they were always
|
|
142
|
+
`None` outside `search()`. A string-valued `error` (the masked search-provider `502`)
|
|
143
|
+
still never enriches, so the upstream provider's identity is never surfaced.
|
|
144
|
+
- Behavior on JSON bodies is unchanged: JSON success bodies still parse into their typed
|
|
145
|
+
success models, documented JSON error bodies are still **returned** as typed `Error`
|
|
146
|
+
models rather than raised, and `raise_on_unexpected_status` semantics are untouched.
|
|
147
|
+
The documented non-JSON success paths — `get_fetch`/`post_fetch`'s raw-text `200` and
|
|
148
|
+
`delete_monitor`'s empty `204` — are likewise unaffected.
|
|
149
|
+
- **README error documentation corrected.** The quick-start example wrapped a call in
|
|
150
|
+
`try/except UnexpectedStatus` and then read `response.formats.markdown`, but a
|
|
151
|
+
documented `4xx` _returns_ a typed `Error` model without raising — so the documented
|
|
152
|
+
example failed with `AttributeError: 'Error' object has no attribute 'formats'`. The
|
|
153
|
+
README now documents the real two-tier contract, and the snippet is executed by
|
|
154
|
+
`tests/test_readme_examples.py` so it cannot silently drift again.
|
|
155
|
+
|
|
156
|
+
### Documentation
|
|
157
|
+
|
|
158
|
+
- Removed the contributor-only `Publishing`, `Regenerating`, and `Development` sections
|
|
159
|
+
from the published README (the PyPI long description) — they described internal CI
|
|
160
|
+
mechanics and a monorepo-contributor workflow that do not belong on a public package
|
|
161
|
+
index. The regeneration/development knowledge is preserved in-repo in
|
|
162
|
+
`packages/sdk-python/CLAUDE.md` (not shipped in the distribution).
|
|
163
|
+
- Added a `## License` section and a `LICENSE` file, matching the npm sibling packages.
|
|
164
|
+
|
|
165
|
+
## 0.3.0
|
|
166
|
+
|
|
167
|
+
### Breaking
|
|
168
|
+
|
|
169
|
+
- **PyPI distribution renamed `bytekit` -> `bytekit-sdk`.** PyPI administratively
|
|
170
|
+
denylists the bare name `bytekit`, so the package installs as
|
|
171
|
+
`pip install bytekit-sdk`. The **import name is unchanged** — `import bytekit`
|
|
172
|
+
still works, and no module path moved. Nothing was ever published under the old
|
|
173
|
+
distribution name, so there is no migration for existing installs.
|
|
174
|
+
- **`raise_on_unexpected_status` now defaults to `True`.** Undocumented response
|
|
175
|
+
statuses now raise `errors.UnexpectedStatus` instead of silently returning `None`.
|
|
176
|
+
Callers that relied on the old `None`-return behavior must pass
|
|
177
|
+
`raise_on_unexpected_status=False` explicitly to opt out.
|
|
178
|
+
- **`base_url` is now a keyword-only argument.** It gained a default
|
|
179
|
+
(`https://api.bytekit.com`), and to satisfy attrs field ordering it became
|
|
180
|
+
keyword-only. Any caller passing `base_url` positionally must switch to the
|
|
181
|
+
`base_url=` keyword form. (`base_url=` was already the documented usage.)
|
|
182
|
+
|
|
183
|
+
### Added
|
|
184
|
+
|
|
185
|
+
- `AuthenticatedClient(token=...)` now works out of the box against production:
|
|
186
|
+
`base_url` defaults to `https://api.bytekit.com`.
|
|
187
|
+
- Finite default request timeout of `120s` (`httpx.Timeout(120.0)`) — requests no
|
|
188
|
+
longer hang indefinitely. Override with `timeout=`.
|
|
189
|
+
- `errors.UnexpectedStatus` now carries optional `.code` / `.message` attributes.
|
|
190
|
+
The `AuthenticatedClient.search()` wrapper populates them from the documented
|
|
191
|
+
`Error` envelope, and safely raises a typed error (never a bare
|
|
192
|
+
`json.JSONDecodeError`) on a non-JSON documented-status body such as an HTML 502.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bytekit-sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Official Python SDK for the ByteKit API
|
|
5
5
|
Project-URL: Homepage, https://bytekit.com
|
|
6
6
|
Project-URL: Repository, https://github.com/Hunt-Labs-Inc/ByteKit
|
|
@@ -46,16 +46,24 @@ The installed version is available as `bytekit.__version__`.
|
|
|
46
46
|
from bytekit import AuthenticatedClient
|
|
47
47
|
from bytekit.api.scrape import create_scrape
|
|
48
48
|
from bytekit.models.scrape_request import ScrapeRequest
|
|
49
|
+
from bytekit.models.scrape_request_formats_item import ScrapeRequestFormatsItem
|
|
49
50
|
from bytekit.models.scrape_success_envelope import ScrapeSuccessEnvelope
|
|
50
51
|
|
|
51
52
|
# base_url defaults to https://api.bytekit.com, so only the token is required.
|
|
52
53
|
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
53
54
|
|
|
54
|
-
result = create_scrape.sync(
|
|
55
|
+
result = create_scrape.sync(
|
|
56
|
+
client=client,
|
|
57
|
+
body=ScrapeRequest(
|
|
58
|
+
url="https://example.com",
|
|
59
|
+
# Ask for markdown explicitly. `formats` is a list of enum members, not plain
|
|
60
|
+
# strings. Omit it and the server returns raw HTML instead, leaving
|
|
61
|
+
# `formats.markdown` unset.
|
|
62
|
+
formats=[ScrapeRequestFormatsItem.MARKDOWN],
|
|
63
|
+
),
|
|
64
|
+
)
|
|
55
65
|
|
|
56
66
|
if isinstance(result, ScrapeSuccessEnvelope):
|
|
57
|
-
# formats.markdown is str | Unset — only set when "markdown" was among the
|
|
58
|
-
# requested formats.
|
|
59
67
|
print(result.formats.markdown)
|
|
60
68
|
```
|
|
61
69
|
|
|
@@ -127,6 +135,29 @@ async def main():
|
|
|
127
135
|
asyncio.run(main())
|
|
128
136
|
```
|
|
129
137
|
|
|
138
|
+
### Clients and event loops
|
|
139
|
+
|
|
140
|
+
An `httpx.AsyncClient` — and therefore its connection pool — belongs to the event loop that
|
|
141
|
+
created it. The recommended shape is a context manager, which scopes the client to exactly one
|
|
142
|
+
loop:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
async def main():
|
|
146
|
+
async with AuthenticatedClient(token="sk_live_your_api_key_here") as client:
|
|
147
|
+
...
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Two rules cover everything else:
|
|
151
|
+
|
|
152
|
+
- **A client the SDK builds for you is rebuilt automatically.** If you reuse one client across
|
|
153
|
+
several `asyncio.run(...)` calls, the SDK notices the running loop has changed and transparently
|
|
154
|
+
replaces its internal `AsyncClient`. Your `base_url`, headers, timeout, `httpx_args` and
|
|
155
|
+
authentication are all re-applied, so this is invisible apart from a new connection. Calling
|
|
156
|
+
`get_async_httpx_client()` outside any running loop returns the cached client unchanged.
|
|
157
|
+
- **A client you pass to `set_async_httpx_client(...)` is yours.** The SDK never rebuilds or
|
|
158
|
+
closes it, so a client you supply must be created and used on the same loop — that is the one
|
|
159
|
+
case where crossing loops is still your responsibility.
|
|
160
|
+
|
|
130
161
|
## Available operations
|
|
131
162
|
|
|
132
163
|
| Module | Method | Description |
|
|
@@ -20,16 +20,24 @@ The installed version is available as `bytekit.__version__`.
|
|
|
20
20
|
from bytekit import AuthenticatedClient
|
|
21
21
|
from bytekit.api.scrape import create_scrape
|
|
22
22
|
from bytekit.models.scrape_request import ScrapeRequest
|
|
23
|
+
from bytekit.models.scrape_request_formats_item import ScrapeRequestFormatsItem
|
|
23
24
|
from bytekit.models.scrape_success_envelope import ScrapeSuccessEnvelope
|
|
24
25
|
|
|
25
26
|
# base_url defaults to https://api.bytekit.com, so only the token is required.
|
|
26
27
|
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
27
28
|
|
|
28
|
-
result = create_scrape.sync(
|
|
29
|
+
result = create_scrape.sync(
|
|
30
|
+
client=client,
|
|
31
|
+
body=ScrapeRequest(
|
|
32
|
+
url="https://example.com",
|
|
33
|
+
# Ask for markdown explicitly. `formats` is a list of enum members, not plain
|
|
34
|
+
# strings. Omit it and the server returns raw HTML instead, leaving
|
|
35
|
+
# `formats.markdown` unset.
|
|
36
|
+
formats=[ScrapeRequestFormatsItem.MARKDOWN],
|
|
37
|
+
),
|
|
38
|
+
)
|
|
29
39
|
|
|
30
40
|
if isinstance(result, ScrapeSuccessEnvelope):
|
|
31
|
-
# formats.markdown is str | Unset — only set when "markdown" was among the
|
|
32
|
-
# requested formats.
|
|
33
41
|
print(result.formats.markdown)
|
|
34
42
|
```
|
|
35
43
|
|
|
@@ -101,6 +109,29 @@ async def main():
|
|
|
101
109
|
asyncio.run(main())
|
|
102
110
|
```
|
|
103
111
|
|
|
112
|
+
### Clients and event loops
|
|
113
|
+
|
|
114
|
+
An `httpx.AsyncClient` — and therefore its connection pool — belongs to the event loop that
|
|
115
|
+
created it. The recommended shape is a context manager, which scopes the client to exactly one
|
|
116
|
+
loop:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
async def main():
|
|
120
|
+
async with AuthenticatedClient(token="sk_live_your_api_key_here") as client:
|
|
121
|
+
...
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Two rules cover everything else:
|
|
125
|
+
|
|
126
|
+
- **A client the SDK builds for you is rebuilt automatically.** If you reuse one client across
|
|
127
|
+
several `asyncio.run(...)` calls, the SDK notices the running loop has changed and transparently
|
|
128
|
+
replaces its internal `AsyncClient`. Your `base_url`, headers, timeout, `httpx_args` and
|
|
129
|
+
authentication are all re-applied, so this is invisible apart from a new connection. Calling
|
|
130
|
+
`get_async_httpx_client()` outside any running loop returns the cached client unchanged.
|
|
131
|
+
- **A client you pass to `set_async_httpx_client(...)` is yours.** The SDK never rebuilds or
|
|
132
|
+
closes it, so a client you supply must be created and used on the same loop — that is the one
|
|
133
|
+
case where crossing loops is still your responsibility.
|
|
134
|
+
|
|
104
135
|
## Available operations
|
|
105
136
|
|
|
106
137
|
| Module | Method | Description |
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# `pip install bytekit-sdk` yields a working `import bytekit`. Mirrors the npm sibling
|
|
8
8
|
# @hunt-labs/bytekit-sdk.
|
|
9
9
|
name = "bytekit-sdk"
|
|
10
|
-
version = "0.3.
|
|
10
|
+
version = "0.3.4"
|
|
11
11
|
description = "Official Python SDK for the ByteKit API"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.10"
|
|
@@ -57,6 +57,22 @@ Documentation = "https://bytekit.com/docs"
|
|
|
57
57
|
[dependency-groups]
|
|
58
58
|
dev = [
|
|
59
59
|
"openapi-python-client==0.25.3",
|
|
60
|
+
# THE FORMATTER IS PART OF THE CODEGEN CONTRACT (#2593). openapi-python-client's DEFAULT
|
|
61
|
+
# post_hooks are `ruff check . --fix --extend-select=I` and `ruff format .`, run with
|
|
62
|
+
# cwd = --output-path (see openapi_python_client/config.py) — and sdk-python-config.yaml
|
|
63
|
+
# sets no `post_hooks` override, so they apply. ruff therefore decides the BYTES of every
|
|
64
|
+
# emitted module, which makes pinning the generator alone insufficient.
|
|
65
|
+
#
|
|
66
|
+
# The generator's own metadata only asks for `ruff<0.13,>=0.2`, so a fresh
|
|
67
|
+
# `pip install openapi-python-client==0.25.3` resolves 0.12.x — nine minor versions above
|
|
68
|
+
# the version that actually produced the committed tree. Left unpinned, the reproducibility
|
|
69
|
+
# gate (ci/scripts/check-sdk-python-regen.sh) would red a CORRECT tree, and no regen would
|
|
70
|
+
# stably fix it. 0.3.7 is measured to reproduce all 221 committed modules byte-for-byte.
|
|
71
|
+
#
|
|
72
|
+
# Bumping this pin is a DELIBERATE, REVIEWED 221-file reformat — exactly like bumping the
|
|
73
|
+
# generator pin above — never an incidental upgrade. The gate reads this pin, so there is
|
|
74
|
+
# no second copy of the version to keep in sync.
|
|
75
|
+
"ruff==0.3.7",
|
|
60
76
|
# Read by scripts/prune-stale-api.py (parses filtered-openapi.yaml to derive which
|
|
61
77
|
# api/ group dirs the spec still produces) and by tests/conftest.py. Generation-time
|
|
62
78
|
# and test-time only — never a runtime dependency of the published client.
|
|
@@ -82,9 +98,23 @@ testpaths = ["tests"]
|
|
|
82
98
|
pythonpath = ["src"]
|
|
83
99
|
|
|
84
100
|
[tool.hatch.build.targets.sdist]
|
|
101
|
+
# The test tree was REMOVED from this allowlist in #2593 (the pre-merge grep gate asserts the
|
|
102
|
+
# glob appears zero times in this file, so a reintroduction is caught even inside a comment —
|
|
103
|
+
# hence the prose here names it in words). The shipped suite could not collect: 12 of 27 modules need
|
|
104
|
+
# `scripts/` (contributor-only codegen tooling) or the canonical `docs/api/openapi.yaml` (which
|
|
105
|
+
# lives two directories above this package), and three of them build distributions of this
|
|
106
|
+
# package — incoherent from inside an unpacked sdist. Verified from the built artifact:
|
|
107
|
+
# `FileNotFoundError: .../scripts/inject-handwritten.py` interrupted collection.
|
|
108
|
+
#
|
|
109
|
+
# Dropped rather than made self-contained: vendoring `scripts/` + a copy of the spec into a
|
|
110
|
+
# public distribution would breach the same published-content boundary that keeps CLAUDE.md out.
|
|
111
|
+
# A test tree that cannot run is worse than none — it reads as a promise to downstream packagers
|
|
112
|
+
# that running it validates the install. Pinned by tests/test_sdist_excludes_tests.
|
|
113
|
+
#
|
|
114
|
+
# The WHEEL is untouched (see [tool.hatch.build.targets.wheel] above): no importable module is
|
|
115
|
+
# removed from what users install.
|
|
85
116
|
include = [
|
|
86
117
|
"src/bytekit/**",
|
|
87
|
-
"tests/**",
|
|
88
118
|
"README.md",
|
|
89
119
|
"CHANGELOG.md",
|
|
90
120
|
"LICENSE",
|
|
@@ -7,6 +7,7 @@ from ... import errors
|
|
|
7
7
|
from ...client import AuthenticatedClient, Client
|
|
8
8
|
from ...models.account_bearer_response import AccountBearerResponse
|
|
9
9
|
from ...models.account_session_response import AccountSessionResponse
|
|
10
|
+
from ...models.error import Error
|
|
10
11
|
from ...types import Response
|
|
11
12
|
|
|
12
13
|
|
|
@@ -21,7 +22,7 @@ def _get_kwargs() -> dict[str, Any]:
|
|
|
21
22
|
|
|
22
23
|
def _parse_response(
|
|
23
24
|
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
|
24
|
-
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
25
|
+
) -> Optional[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
25
26
|
if response.status_code == 200:
|
|
26
27
|
|
|
27
28
|
def _parse_response_200(
|
|
@@ -44,6 +45,10 @@ def _parse_response(
|
|
|
44
45
|
response_200 = errors.bytekit_parse(_parse_response_200, client=client, response=response)
|
|
45
46
|
|
|
46
47
|
return response_200
|
|
48
|
+
if response.status_code == 429:
|
|
49
|
+
response_429 = errors.bytekit_parse(Error.from_dict, client=client, response=response)
|
|
50
|
+
|
|
51
|
+
return response_429
|
|
47
52
|
if client.raise_on_unexpected_status:
|
|
48
53
|
raise errors.bytekit_unexpected(response) # BYTEKIT-OP-GUARD
|
|
49
54
|
else:
|
|
@@ -52,7 +57,7 @@ def _parse_response(
|
|
|
52
57
|
|
|
53
58
|
def _build_response(
|
|
54
59
|
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
|
55
|
-
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
60
|
+
) -> Response[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
56
61
|
return Response(
|
|
57
62
|
status_code=HTTPStatus(response.status_code),
|
|
58
63
|
content=response.content,
|
|
@@ -64,7 +69,7 @@ def _build_response(
|
|
|
64
69
|
def sync_detailed(
|
|
65
70
|
*,
|
|
66
71
|
client: AuthenticatedClient,
|
|
67
|
-
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
72
|
+
) -> Response[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
68
73
|
"""Get account details
|
|
69
74
|
|
|
70
75
|
Returns account, plan, and current API key details, including the
|
|
@@ -75,7 +80,7 @@ def sync_detailed(
|
|
|
75
80
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
76
81
|
|
|
77
82
|
Returns:
|
|
78
|
-
Response[Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
83
|
+
Response[Union[Error, Union['AccountBearerResponse', 'AccountSessionResponse']]]
|
|
79
84
|
"""
|
|
80
85
|
|
|
81
86
|
kwargs = _get_kwargs()
|
|
@@ -90,7 +95,7 @@ def sync_detailed(
|
|
|
90
95
|
def sync(
|
|
91
96
|
*,
|
|
92
97
|
client: AuthenticatedClient,
|
|
93
|
-
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
98
|
+
) -> Optional[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
94
99
|
"""Get account details
|
|
95
100
|
|
|
96
101
|
Returns account, plan, and current API key details, including the
|
|
@@ -101,7 +106,7 @@ def sync(
|
|
|
101
106
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
102
107
|
|
|
103
108
|
Returns:
|
|
104
|
-
Union['AccountBearerResponse', 'AccountSessionResponse']
|
|
109
|
+
Union[Error, Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
105
110
|
"""
|
|
106
111
|
|
|
107
112
|
return sync_detailed(
|
|
@@ -112,7 +117,7 @@ def sync(
|
|
|
112
117
|
async def asyncio_detailed(
|
|
113
118
|
*,
|
|
114
119
|
client: AuthenticatedClient,
|
|
115
|
-
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
120
|
+
) -> Response[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
116
121
|
"""Get account details
|
|
117
122
|
|
|
118
123
|
Returns account, plan, and current API key details, including the
|
|
@@ -123,7 +128,7 @@ async def asyncio_detailed(
|
|
|
123
128
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
124
129
|
|
|
125
130
|
Returns:
|
|
126
|
-
Response[Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
131
|
+
Response[Union[Error, Union['AccountBearerResponse', 'AccountSessionResponse']]]
|
|
127
132
|
"""
|
|
128
133
|
|
|
129
134
|
kwargs = _get_kwargs()
|
|
@@ -136,7 +141,7 @@ async def asyncio_detailed(
|
|
|
136
141
|
async def asyncio(
|
|
137
142
|
*,
|
|
138
143
|
client: AuthenticatedClient,
|
|
139
|
-
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
144
|
+
) -> Optional[Union[Error, Union["AccountBearerResponse", "AccountSessionResponse"]]]:
|
|
140
145
|
"""Get account details
|
|
141
146
|
|
|
142
147
|
Returns account, plan, and current API key details, including the
|
|
@@ -147,7 +152,7 @@ async def asyncio(
|
|
|
147
152
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
148
153
|
|
|
149
154
|
Returns:
|
|
150
|
-
Union['AccountBearerResponse', 'AccountSessionResponse']
|
|
155
|
+
Union[Error, Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
151
156
|
"""
|
|
152
157
|
|
|
153
158
|
return (
|
|
@@ -74,12 +74,38 @@ def sync_detailed(
|
|
|
74
74
|
Webhook deliveries include `X-ByteKit-Event: bulk.completed` so
|
|
75
75
|
receivers can dispatch on the header without parsing the body shape.
|
|
76
76
|
|
|
77
|
+
**Limits:** request bodies are guarded in a two-tier shape. A streamed body
|
|
78
|
+
with no `Content-Length` header is capped at 4 MB before your API key
|
|
79
|
+
is checked; a body that declares `Content-Length` is instead bounded
|
|
80
|
+
there by a 32 MB fail-safe (not the real limit — see below), since
|
|
81
|
+
that branch reads nothing until your key is verified. Once your key
|
|
82
|
+
is verified, a second check re-gates the body against your account's
|
|
83
|
+
own `max_bulk_size` (at this endpoint's richer per-item override
|
|
84
|
+
budget), which reaches 28.7 MB for the largest documented account. A
|
|
85
|
+
standard-plan account's effective ceiling is 4 MB; either tier's
|
|
86
|
+
overrun returns a `400` with error code `request_too_large`.
|
|
87
|
+
|
|
77
88
|
Args:
|
|
78
89
|
body (CreateBulkBody): Provide `urls` (simple list) OR `items` (per-item config), not
|
|
79
90
|
both. `type` selects the capture kind per entry — only
|
|
80
91
|
`screenshot` and `scrape` are accepted (`recording` is
|
|
81
92
|
deactivated). Behaviour fields may be set per item or via
|
|
82
93
|
`defaults`; a per-item value overrides the matching default.
|
|
94
|
+
This includes `type`: an entry with no `type` of its own
|
|
95
|
+
inherits `defaults.type`, falling back to `screenshot` only
|
|
96
|
+
when neither is set.
|
|
97
|
+
|
|
98
|
+
The top-level object, each `items[]` entry, and `defaults`
|
|
99
|
+
each reject unrecognized keys with a 422 `validation_error`
|
|
100
|
+
(the offending key name appears in the error's `details`
|
|
101
|
+
message text) rather than silently discarding them.
|
|
102
|
+
`items[]` and `defaults` do not share one field set:
|
|
103
|
+
`device_scale_factor` is accepted only under `defaults` (a
|
|
104
|
+
per-item value 422s), and `duration`/`scenario` are accepted
|
|
105
|
+
only per item (a `defaults` value 422s). `metadata` is
|
|
106
|
+
different from those three: it is valid both at the top
|
|
107
|
+
level of the body and per item, but rejected with a 422 if
|
|
108
|
+
placed under `defaults`. See the `422` response below.
|
|
83
109
|
|
|
84
110
|
Raises:
|
|
85
111
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
@@ -112,12 +138,38 @@ def sync(
|
|
|
112
138
|
Webhook deliveries include `X-ByteKit-Event: bulk.completed` so
|
|
113
139
|
receivers can dispatch on the header without parsing the body shape.
|
|
114
140
|
|
|
141
|
+
**Limits:** request bodies are guarded in a two-tier shape. A streamed body
|
|
142
|
+
with no `Content-Length` header is capped at 4 MB before your API key
|
|
143
|
+
is checked; a body that declares `Content-Length` is instead bounded
|
|
144
|
+
there by a 32 MB fail-safe (not the real limit — see below), since
|
|
145
|
+
that branch reads nothing until your key is verified. Once your key
|
|
146
|
+
is verified, a second check re-gates the body against your account's
|
|
147
|
+
own `max_bulk_size` (at this endpoint's richer per-item override
|
|
148
|
+
budget), which reaches 28.7 MB for the largest documented account. A
|
|
149
|
+
standard-plan account's effective ceiling is 4 MB; either tier's
|
|
150
|
+
overrun returns a `400` with error code `request_too_large`.
|
|
151
|
+
|
|
115
152
|
Args:
|
|
116
153
|
body (CreateBulkBody): Provide `urls` (simple list) OR `items` (per-item config), not
|
|
117
154
|
both. `type` selects the capture kind per entry — only
|
|
118
155
|
`screenshot` and `scrape` are accepted (`recording` is
|
|
119
156
|
deactivated). Behaviour fields may be set per item or via
|
|
120
157
|
`defaults`; a per-item value overrides the matching default.
|
|
158
|
+
This includes `type`: an entry with no `type` of its own
|
|
159
|
+
inherits `defaults.type`, falling back to `screenshot` only
|
|
160
|
+
when neither is set.
|
|
161
|
+
|
|
162
|
+
The top-level object, each `items[]` entry, and `defaults`
|
|
163
|
+
each reject unrecognized keys with a 422 `validation_error`
|
|
164
|
+
(the offending key name appears in the error's `details`
|
|
165
|
+
message text) rather than silently discarding them.
|
|
166
|
+
`items[]` and `defaults` do not share one field set:
|
|
167
|
+
`device_scale_factor` is accepted only under `defaults` (a
|
|
168
|
+
per-item value 422s), and `duration`/`scenario` are accepted
|
|
169
|
+
only per item (a `defaults` value 422s). `metadata` is
|
|
170
|
+
different from those three: it is valid both at the top
|
|
171
|
+
level of the body and per item, but rejected with a 422 if
|
|
172
|
+
placed under `defaults`. See the `422` response below.
|
|
121
173
|
|
|
122
174
|
Raises:
|
|
123
175
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
@@ -145,12 +197,38 @@ async def asyncio_detailed(
|
|
|
145
197
|
Webhook deliveries include `X-ByteKit-Event: bulk.completed` so
|
|
146
198
|
receivers can dispatch on the header without parsing the body shape.
|
|
147
199
|
|
|
200
|
+
**Limits:** request bodies are guarded in a two-tier shape. A streamed body
|
|
201
|
+
with no `Content-Length` header is capped at 4 MB before your API key
|
|
202
|
+
is checked; a body that declares `Content-Length` is instead bounded
|
|
203
|
+
there by a 32 MB fail-safe (not the real limit — see below), since
|
|
204
|
+
that branch reads nothing until your key is verified. Once your key
|
|
205
|
+
is verified, a second check re-gates the body against your account's
|
|
206
|
+
own `max_bulk_size` (at this endpoint's richer per-item override
|
|
207
|
+
budget), which reaches 28.7 MB for the largest documented account. A
|
|
208
|
+
standard-plan account's effective ceiling is 4 MB; either tier's
|
|
209
|
+
overrun returns a `400` with error code `request_too_large`.
|
|
210
|
+
|
|
148
211
|
Args:
|
|
149
212
|
body (CreateBulkBody): Provide `urls` (simple list) OR `items` (per-item config), not
|
|
150
213
|
both. `type` selects the capture kind per entry — only
|
|
151
214
|
`screenshot` and `scrape` are accepted (`recording` is
|
|
152
215
|
deactivated). Behaviour fields may be set per item or via
|
|
153
216
|
`defaults`; a per-item value overrides the matching default.
|
|
217
|
+
This includes `type`: an entry with no `type` of its own
|
|
218
|
+
inherits `defaults.type`, falling back to `screenshot` only
|
|
219
|
+
when neither is set.
|
|
220
|
+
|
|
221
|
+
The top-level object, each `items[]` entry, and `defaults`
|
|
222
|
+
each reject unrecognized keys with a 422 `validation_error`
|
|
223
|
+
(the offending key name appears in the error's `details`
|
|
224
|
+
message text) rather than silently discarding them.
|
|
225
|
+
`items[]` and `defaults` do not share one field set:
|
|
226
|
+
`device_scale_factor` is accepted only under `defaults` (a
|
|
227
|
+
per-item value 422s), and `duration`/`scenario` are accepted
|
|
228
|
+
only per item (a `defaults` value 422s). `metadata` is
|
|
229
|
+
different from those three: it is valid both at the top
|
|
230
|
+
level of the body and per item, but rejected with a 422 if
|
|
231
|
+
placed under `defaults`. See the `422` response below.
|
|
154
232
|
|
|
155
233
|
Raises:
|
|
156
234
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
@@ -181,12 +259,38 @@ async def asyncio(
|
|
|
181
259
|
Webhook deliveries include `X-ByteKit-Event: bulk.completed` so
|
|
182
260
|
receivers can dispatch on the header without parsing the body shape.
|
|
183
261
|
|
|
262
|
+
**Limits:** request bodies are guarded in a two-tier shape. A streamed body
|
|
263
|
+
with no `Content-Length` header is capped at 4 MB before your API key
|
|
264
|
+
is checked; a body that declares `Content-Length` is instead bounded
|
|
265
|
+
there by a 32 MB fail-safe (not the real limit — see below), since
|
|
266
|
+
that branch reads nothing until your key is verified. Once your key
|
|
267
|
+
is verified, a second check re-gates the body against your account's
|
|
268
|
+
own `max_bulk_size` (at this endpoint's richer per-item override
|
|
269
|
+
budget), which reaches 28.7 MB for the largest documented account. A
|
|
270
|
+
standard-plan account's effective ceiling is 4 MB; either tier's
|
|
271
|
+
overrun returns a `400` with error code `request_too_large`.
|
|
272
|
+
|
|
184
273
|
Args:
|
|
185
274
|
body (CreateBulkBody): Provide `urls` (simple list) OR `items` (per-item config), not
|
|
186
275
|
both. `type` selects the capture kind per entry — only
|
|
187
276
|
`screenshot` and `scrape` are accepted (`recording` is
|
|
188
277
|
deactivated). Behaviour fields may be set per item or via
|
|
189
278
|
`defaults`; a per-item value overrides the matching default.
|
|
279
|
+
This includes `type`: an entry with no `type` of its own
|
|
280
|
+
inherits `defaults.type`, falling back to `screenshot` only
|
|
281
|
+
when neither is set.
|
|
282
|
+
|
|
283
|
+
The top-level object, each `items[]` entry, and `defaults`
|
|
284
|
+
each reject unrecognized keys with a 422 `validation_error`
|
|
285
|
+
(the offending key name appears in the error's `details`
|
|
286
|
+
message text) rather than silently discarding them.
|
|
287
|
+
`items[]` and `defaults` do not share one field set:
|
|
288
|
+
`device_scale_factor` is accepted only under `defaults` (a
|
|
289
|
+
per-item value 422s), and `duration`/`scenario` are accepted
|
|
290
|
+
only per item (a `defaults` value 422s). `metadata` is
|
|
291
|
+
different from those three: it is valid both at the top
|
|
292
|
+
level of the body and per item, but rejected with a 422 if
|
|
293
|
+
placed under `defaults`. See the `422` response below.
|
|
190
294
|
|
|
191
295
|
Raises:
|
|
192
296
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|