bytekit-sdk 0.3.0__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.0/.gitignore +102 -0
- bytekit_sdk-0.3.0/CHANGELOG.md +33 -0
- bytekit_sdk-0.3.0/PKG-INFO +141 -0
- bytekit_sdk-0.3.0/README.md +116 -0
- bytekit_sdk-0.3.0/pyproject.toml +94 -0
- bytekit_sdk-0.3.0/src/bytekit/__init__.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/api/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/account/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/account/get_account.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/bulk/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/bulk/create_bulk.py +204 -0
- bytekit_sdk-0.3.0/src/bytekit/api/bulk/delete_bulk.py +177 -0
- bytekit_sdk-0.3.0/src/bytekit/api/bulk/get_bulk.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/bulk/list_bulk_screenshots.py +152 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch/get_fetch.py +254 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch/post_fetch.py +178 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch_bulk/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch_bulk/create_fetch_bulk.py +180 -0
- bytekit_sdk-0.3.0/src/bytekit/api/fetch_bulk/get_fetch_bulk.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/create_monitor.py +180 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/delete_monitor.py +155 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/get_monitor.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/list_monitor_captures.py +188 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/list_monitors.py +193 -0
- bytekit_sdk-0.3.0/src/bytekit/api/monitors/update_monitor.py +191 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape/create_scrape.py +197 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape/get_scrape.py +231 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape_bulk/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape_bulk/create_scrape_bulk.py +188 -0
- bytekit_sdk-0.3.0/src/bytekit/api/scrape_bulk/get_scrape_bulk.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/screenshots/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/screenshots/create_screenshot.py +208 -0
- bytekit_sdk-0.3.0/src/bytekit/api/screenshots/get_screenshot.py +177 -0
- bytekit_sdk-0.3.0/src/bytekit/api/search/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/search/create_search.py +225 -0
- bytekit_sdk-0.3.0/src/bytekit/api/sitemap/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/sitemap/create_sitemap.py +192 -0
- bytekit_sdk-0.3.0/src/bytekit/api/sitemap/get_sitemap.py +157 -0
- bytekit_sdk-0.3.0/src/bytekit/api/usage/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/usage/get_usage.py +126 -0
- bytekit_sdk-0.3.0/src/bytekit/api/usage/get_usage_by_endpoint.py +215 -0
- bytekit_sdk-0.3.0/src/bytekit/api/usage/get_usage_daily.py +203 -0
- bytekit_sdk-0.3.0/src/bytekit/api/webhooks/__init__.py +1 -0
- bytekit_sdk-0.3.0/src/bytekit/api/webhooks/list_webhook_deliveries.py +214 -0
- bytekit_sdk-0.3.0/src/bytekit/api/webhooks/retry_webhook_delivery.py +165 -0
- bytekit_sdk-0.3.0/src/bytekit/client.py +418 -0
- bytekit_sdk-0.3.0/src/bytekit/errors.py +18 -0
- bytekit_sdk-0.3.0/src/bytekit/models/__init__.py +401 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response.py +207 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_api_key.py +134 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_api_key_environment.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_auto_topup.py +83 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_plan.py +150 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_subscription.py +85 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_subscription_plan.py +99 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_bearer_response_subscription_status.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_session_response.py +164 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_session_response_notifications.py +51 -0
- bytekit_sdk-0.3.0/src/bytekit/models/account_session_response_plan.py +150 -0
- bytekit_sdk-0.3.0/src/bytekit/models/bandwidth_balance.py +91 -0
- bytekit_sdk-0.3.0/src/bytekit/models/capture_response.py +216 -0
- bytekit_sdk-0.3.0/src/bytekit/models/capture_response_outcome.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/clip.py +83 -0
- bytekit_sdk-0.3.0/src/bytekit/models/cookie.py +90 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body.py +155 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults.py +423 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_device.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_2_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_device_scale_factor_type_3_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_formats_item.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_type.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_viewport_type_0.py +67 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_defaults_wait_until.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item.py +380 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_device.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_formats_item.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_scenario.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_type.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_viewport_type_0.py +67 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_body_items_item_wait_until.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_response_202.py +164 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_bulk_response_202_status.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body.py +161 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body_defaults.py +91 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body_defaults_format.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body_metadata.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body_urls_item_type_1.py +102 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_body_urls_item_type_1_format.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_fetch_bulk_response_202.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body.py +179 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_custom.py +52 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_defaults.py +167 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_defaults_formats_item.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_defaults_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_items_item.py +226 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_items_item_custom.py +50 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_items_item_formats_item.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_items_item_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_body_items_item_metadata.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_response_202.py +166 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_scrape_bulk_response_202_status.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_body.py +140 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_body_date_range.py +13 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_body_type.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_response_200.py +119 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_response_200_results_item.py +161 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_response_200_results_item_image.py +113 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_response_502.py +46 -0
- bytekit_sdk-0.3.0/src/bytekit/models/create_search_response_502_error.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/credit_balance.py +91 -0
- bytekit_sdk-0.3.0/src/bytekit/models/delete_bulk_response_200.py +164 -0
- bytekit_sdk-0.3.0/src/bytekit/models/delete_bulk_response_200_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/error.py +83 -0
- bytekit_sdk-0.3.0/src/bytekit/models/error_error.py +100 -0
- bytekit_sdk-0.3.0/src/bytekit/models/error_status.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request.py +276 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_cache_ttl_type_1.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_custom.py +48 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_format.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_markdown_images.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_markdown_links.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/fetch_request_markdown_mode.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_bulk_response_200.py +164 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_bulk_response_200_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_fetch_bulk_response_200.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_fetch_cache_ttl_type_1.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_fetch_format.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_scrape_bulk_response_200.py +164 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_scrape_bulk_response_200_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_by_endpoint_response_200.py +114 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_by_endpoint_response_200_rows_item.py +90 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_by_endpoint_response_200_rows_item_endpoint.py +17 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_by_endpoint_response_200_totals.py +67 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_daily_response_200.py +97 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_daily_response_200_data_item.py +219 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_response_200.py +344 -0
- bytekit_sdk-0.3.0/src/bytekit/models/get_usage_response_200_plan_type.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_bulk_screenshots_response_200.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_monitor_captures_response_200.py +101 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_monitors_response_200.py +101 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_monitors_status.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_webhook_deliveries_response_200.py +101 -0
- bytekit_sdk-0.3.0/src/bytekit/models/list_webhook_deliveries_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/metadata.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request.py +219 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_interval_type.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_notify_on.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_options.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_scrape_options.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_type.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_request_webhook_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_create_response.py +423 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response.py +411 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response_interval_type.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response_metadata_type_0.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response_status.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response_type.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_response_webhook_headers_type_0.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request.py +223 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_interval_type.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_notify_on.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_options.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_scrape_options.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_status.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/monitor_update_request_webhook_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_error_envelope.py +113 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_error_envelope_error.py +93 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_error_envelope_error_code.py +18 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_error_envelope_schema_version.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_error_envelope_status.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_formats.py +183 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_markdown_tokens.py +75 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_metadata.py +262 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_queued_envelope.py +124 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_queued_envelope_schema_version.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_queued_envelope_status.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request.py +485 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_cache_ttl_type_1.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_custom.py +48 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_events_item.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_formats_item.py +12 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_markdown_images.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_markdown_links.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_markdown_mode.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_token_encoding.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_request_x_internal_scrape_path.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_scored_image.py +128 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_scored_link.py +94 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_stats.py +75 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_success_envelope.py +345 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_success_envelope_cache.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_success_envelope_custom.py +48 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_success_envelope_schema_version.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_success_envelope_status.py +8 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_table.py +96 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_table_kind.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_warning.py +88 -0
- bytekit_sdk-0.3.0/src/bytekit/models/scrape_warning_code.py +17 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request.py +445 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_device.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_device_scale_factor_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_device_scale_factor_type_2_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_device_scale_factor_type_3_type_1.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_format.py +9 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_headers.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_request_wait_until.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_response.py +264 -0
- bytekit_sdk-0.3.0/src/bytekit/models/screenshot_response_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_request.py +210 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_request_process_type_0.py +90 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_request_process_type_0_options.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_request_strategy.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response.py +418 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response_cache.py +10 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response_metadata_type_0.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response_process_type_0.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response_sources_type_0.py +44 -0
- bytekit_sdk-0.3.0/src/bytekit/models/sitemap_response_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/models/viewport.py +67 -0
- bytekit_sdk-0.3.0/src/bytekit/models/webhook_delivery_response.py +270 -0
- bytekit_sdk-0.3.0/src/bytekit/models/webhook_delivery_response_event_type.py +14 -0
- bytekit_sdk-0.3.0/src/bytekit/models/webhook_delivery_response_status.py +11 -0
- bytekit_sdk-0.3.0/src/bytekit/py.typed +0 -0
- bytekit_sdk-0.3.0/src/bytekit/types.py +54 -0
- bytekit_sdk-0.3.0/tests/__init__.py +0 -0
- bytekit_sdk-0.3.0/tests/conftest.py +97 -0
- bytekit_sdk-0.3.0/tests/fixtures/unpatched_client.py.snapshot +365 -0
- bytekit_sdk-0.3.0/tests/fixtures/unpatched_errors.py.snapshot +16 -0
- bytekit_sdk-0.3.0/tests/test_bulk_delete.py +33 -0
- bytekit_sdk-0.3.0/tests/test_client.py +121 -0
- bytekit_sdk-0.3.0/tests/test_client_defaults.py +122 -0
- bytekit_sdk-0.3.0/tests/test_deactivated_resources.py +108 -0
- bytekit_sdk-0.3.0/tests/test_generate_docs.py +285 -0
- bytekit_sdk-0.3.0/tests/test_models.py +178 -0
- bytekit_sdk-0.3.0/tests/test_no_materialized_defaults.py +31 -0
- bytekit_sdk-0.3.0/tests/test_package_identity.py +24 -0
- bytekit_sdk-0.3.0/tests/test_patch_functions.py +93 -0
- bytekit_sdk-0.3.0/tests/test_prune_stale_api.py +458 -0
- bytekit_sdk-0.3.0/tests/test_publish_metadata.py +179 -0
- bytekit_sdk-0.3.0/tests/test_regen_durability.py +36 -0
- bytekit_sdk-0.3.0/tests/test_removed_surface.py +50 -0
- bytekit_sdk-0.3.0/tests/test_scrape_markdown_opts.py +157 -0
- bytekit_sdk-0.3.0/tests/test_scrape_scored_formats.py +135 -0
- bytekit_sdk-0.3.0/tests/test_sdist_contents.py +155 -0
- bytekit_sdk-0.3.0/tests/test_search.py +209 -0
- bytekit_sdk-0.3.0/tests/test_search_errors.py +97 -0
- bytekit_sdk-0.3.0/tests/test_spec_field_parity.py +106 -0
- bytekit_sdk-0.3.0/tests/test_usage.py +80 -0
- bytekit_sdk-0.3.0/tests/test_webhook_deliveries.py +59 -0
- bytekit_sdk-0.3.0/tests/test_wheel_contents.py +109 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
# Sublime Text project/workspace files (user-specific, incl. editor _backup copies)
|
|
3
|
+
*.sublime-project
|
|
4
|
+
*.sublime-workspace
|
|
5
|
+
*.sublime-project_backup
|
|
6
|
+
*.sublime-workspace_backup
|
|
7
|
+
node_modules/
|
|
8
|
+
.env
|
|
9
|
+
.env.*
|
|
10
|
+
# Woodpecker CI secret bootstrap (ci/scripts/load-secrets.ts) — never commit.
|
|
11
|
+
.ci-secrets.env
|
|
12
|
+
.dev.vars
|
|
13
|
+
dist/
|
|
14
|
+
# Package-manager debug logs — never meant to be committed.
|
|
15
|
+
npm-debug.log*
|
|
16
|
+
pnpm-debug.log*
|
|
17
|
+
yarn-debug.log*
|
|
18
|
+
yarn-error.log*
|
|
19
|
+
.claude/pipeline-output/
|
|
20
|
+
.claude/worktrees/
|
|
21
|
+
.claude/scheduled_tasks.lock
|
|
22
|
+
# local-CI pre-push gate: freshness stamp written by the PreToolUse hook in .claude/settings.json
|
|
23
|
+
.claude/.local-ci-pass
|
|
24
|
+
# Generated cache + dev-server logs/pids — regenerable, never commit.
|
|
25
|
+
.claude/cache/
|
|
26
|
+
.claude/stack/dev-server-logs/
|
|
27
|
+
.worktrees/
|
|
28
|
+
# Operational pipeline state — never committed.
|
|
29
|
+
.pipeline/.state/
|
|
30
|
+
.pipeline/.candidates/
|
|
31
|
+
.wrangler/
|
|
32
|
+
*.tsbuildinfo
|
|
33
|
+
# Turbo per-package run metadata (#1840). The shared content-addressed cache lives on the CI
|
|
34
|
+
# agent volume /cache/turbo, never in the repo; .turbo/ is local run state and must stay untracked.
|
|
35
|
+
.turbo/
|
|
36
|
+
# pnpm content-addressable store, created when pnpm's store-dir is pointed at the repo (default is
|
|
37
|
+
# ~/.local/share/pnpm/store). Local package cache like node_modules — must stay untracked.
|
|
38
|
+
.pnpm-store/
|
|
39
|
+
coverage/
|
|
40
|
+
tests/e2e/results.json
|
|
41
|
+
tests/e2e/.sweep/
|
|
42
|
+
.playwright-mcp/
|
|
43
|
+
# Local Playwright persistent context for ux-design/markup-verification (Chromium profile + Clerk session)
|
|
44
|
+
/.cache/
|
|
45
|
+
packages/http-fetcher/ja3check
|
|
46
|
+
packages/http-fetcher/server
|
|
47
|
+
packages/http-fetcher/browserforge-bench
|
|
48
|
+
__pycache__/
|
|
49
|
+
*.pyc
|
|
50
|
+
# Generated artifact — reproduced via `pnpm --filter @rapidcrawl/sdk-python generate`
|
|
51
|
+
packages/sdk-python/filtered-openapi.yaml
|
|
52
|
+
# NOTE: the MCP server's generated docs JSON (see packages/mcp-server/src) is intentionally
|
|
53
|
+
# TRACKED (#2469). Coolify builds the gateway image from a git checkout, so this prebuild-generated
|
|
54
|
+
# file must be committed for the hosted MCP docs tools to work. Regenerate with:
|
|
55
|
+
# pnpm --filter @hunt-labs/bytekit-mcp prebuild
|
|
56
|
+
# Generated by @tanstack/router-plugin/vite — reproduced on every dev/build
|
|
57
|
+
packages/app/src/routeTree.gen.ts
|
|
58
|
+
packages/app/.tanstack/
|
|
59
|
+
# CloakBrowser spike result directories — contain raw trial data, not committed
|
|
60
|
+
docs/plans/spike-cloakbrowser-results-*/
|
|
61
|
+
# Skill-output scratch (lean/, code-review artifacts, baseline-rot diagnostics)
|
|
62
|
+
.build/
|
|
63
|
+
# External Claude Code plugin source — e.g. the ux-design workflow plugin at
|
|
64
|
+
# ~/.claude/plugins/ux-design/. Prevent accidental re-add if someone copies
|
|
65
|
+
# the source back into the tree. See .claude/stack/ux-design.md for the
|
|
66
|
+
# invocation contract.
|
|
67
|
+
ux-design/plugin/
|
|
68
|
+
# Per-issue scratch notes
|
|
69
|
+
.issues/
|
|
70
|
+
# Per-ticket scratch (raw artifacts from `ticket` command runs)
|
|
71
|
+
docs/tickets/
|
|
72
|
+
.superpowers/
|
|
73
|
+
# Build outputs (webrtc-probe, etc.) — anywhere in tree
|
|
74
|
+
out/
|
|
75
|
+
# Graphify generated artifacts (cache, graph.json, wiki/, GRAPH_REPORT.md)
|
|
76
|
+
graphify-out/
|
|
77
|
+
# Graphify raw run state (transcripts of individual analyses)
|
|
78
|
+
.claude/learnings/raw/
|
|
79
|
+
|
|
80
|
+
# Claude Design extracted bundle — bulk that's regenerable from each re-export
|
|
81
|
+
# Keep the high-signal CSS / JSX / HTML / chats / README; drop the bulk.
|
|
82
|
+
ux-design/claude-design/marketing/bundle/project/fonts/*.woff
|
|
83
|
+
ux-design/claude-design/marketing/bundle/project/uploads/
|
|
84
|
+
ux-design/claude-design/marketing/bundle/project/screenshots/
|
|
85
|
+
ux-design/claude-design/marketing/bundle/project/verify/
|
|
86
|
+
# Root-level project/*.jsx files are vestigial canvas-iteration artifacts that
|
|
87
|
+
# Claude Design's export pipeline keeps including despite the files not existing
|
|
88
|
+
# in live project state (snapshot-staleness pattern verified syncs 8, 13, 14).
|
|
89
|
+
# Pattern matches root-level only (gitignore * doesn't recurse) — nested
|
|
90
|
+
# project/X/*.jsx files (homepage, vs/firecrawl/, features/anti-bot/, etc.) stay tracked.
|
|
91
|
+
ux-design/claude-design/marketing/bundle/project/*.jsx
|
|
92
|
+
ux-design/screens/playground-sitemap/.auth-state.json
|
|
93
|
+
# v2 verify saves a Clerk session storageState per screen — never commit (token).
|
|
94
|
+
ux-design/screens/**/.auth-state.json
|
|
95
|
+
# v2 verify scratch — OTP code + run log per screen, never commit.
|
|
96
|
+
ux-design/screens/**/.verify-code
|
|
97
|
+
ux-design/screens/**/.verify-run.log
|
|
98
|
+
.ci-deploy-uuids
|
|
99
|
+
|
|
100
|
+
# Astro types cache generated when astro runs from repo root (the package-level
|
|
101
|
+
# caches are already ignored via the package pattern).
|
|
102
|
+
/.astro/
|
|
@@ -0,0 +1,33 @@
|
|
|
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.0
|
|
7
|
+
|
|
8
|
+
### Breaking
|
|
9
|
+
|
|
10
|
+
- **PyPI distribution renamed `bytekit` -> `bytekit-sdk`.** PyPI administratively
|
|
11
|
+
denylists the bare name `bytekit`, so the package installs as
|
|
12
|
+
`pip install bytekit-sdk`. The **import name is unchanged** — `import bytekit`
|
|
13
|
+
still works, and no module path moved. Nothing was ever published under the old
|
|
14
|
+
distribution name, so there is no migration for existing installs.
|
|
15
|
+
- **`raise_on_unexpected_status` now defaults to `True`.** Undocumented response
|
|
16
|
+
statuses now raise `errors.UnexpectedStatus` instead of silently returning `None`.
|
|
17
|
+
Callers that relied on the old `None`-return behavior must pass
|
|
18
|
+
`raise_on_unexpected_status=False` explicitly to opt out.
|
|
19
|
+
- **`base_url` is now a keyword-only argument.** It gained a default
|
|
20
|
+
(`https://api.bytekit.com`), and to satisfy attrs field ordering it became
|
|
21
|
+
keyword-only. Any caller passing `base_url` positionally must switch to the
|
|
22
|
+
`base_url=` keyword form. (`base_url=` was already the documented usage.)
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `AuthenticatedClient(token=...)` now works out of the box against production:
|
|
27
|
+
`base_url` defaults to `https://api.bytekit.com`.
|
|
28
|
+
- Finite default request timeout of `120s` (`httpx.Timeout(120.0)`) — requests no
|
|
29
|
+
longer hang indefinitely. Override with `timeout=`.
|
|
30
|
+
- `errors.UnexpectedStatus` now carries optional `.code` / `.message` attributes.
|
|
31
|
+
The `AuthenticatedClient.search()` wrapper populates them from the documented
|
|
32
|
+
`Error` envelope, and safely raises a typed error (never a bare
|
|
33
|
+
`json.JSONDecodeError`) on a non-JSON documented-status body such as an HTML 502.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bytekit-sdk
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Official Python SDK for the ByteKit API
|
|
5
|
+
Project-URL: Homepage, https://bytekit.com
|
|
6
|
+
Project-URL: Repository, https://github.com/Hunt-Labs-Inc/ByteKit
|
|
7
|
+
Project-URL: Documentation, https://bytekit.com/docs
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: api,bytekit,crawler,llm,markdown,scraping,screenshots,sdk,web-scraping
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: attrs>=23.1.0
|
|
22
|
+
Requires-Dist: httpx>=0.24.0
|
|
23
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# bytekit-sdk
|
|
27
|
+
|
|
28
|
+
Official Python SDK for the [ByteKit API](https://bytekit.com).
|
|
29
|
+
|
|
30
|
+
The PyPI **distribution** is `bytekit-sdk`; the **import** name is `bytekit`.
|
|
31
|
+
|
|
32
|
+
Generated from the OpenAPI spec using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client), filtered to the stable v0.1 operations.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install bytekit-sdk
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from bytekit import AuthenticatedClient
|
|
44
|
+
from bytekit.api.scrape import create_scrape
|
|
45
|
+
from bytekit.errors import UnexpectedStatus
|
|
46
|
+
from bytekit.models.scrape_request import ScrapeRequest
|
|
47
|
+
|
|
48
|
+
# base_url defaults to https://api.bytekit.com, so only the token is required.
|
|
49
|
+
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
50
|
+
|
|
51
|
+
body = ScrapeRequest(url="https://example.com")
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
response = create_scrape.sync(client=client, body=body)
|
|
55
|
+
# response.formats.markdown is str | Unset — only present when "markdown" was requested
|
|
56
|
+
print(response.formats.markdown)
|
|
57
|
+
except UnexpectedStatus as err:
|
|
58
|
+
# Errors now raise loudly by default instead of returning None.
|
|
59
|
+
print(f"request failed with status {err.status_code}: {err.code} {err.message}")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Defaults
|
|
63
|
+
|
|
64
|
+
The client ships with production-ready defaults so `AuthenticatedClient(token=...)` works out of the box:
|
|
65
|
+
|
|
66
|
+
| Setting | Default | Notes |
|
|
67
|
+
| ---------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `base_url` | `https://api.bytekit.com` | Pass `base_url=` to target staging or a proxy. |
|
|
69
|
+
| `timeout` | `120s` (`httpx.Timeout(120.0)`) | Finite by default — requests no longer hang indefinitely. Pass `timeout=` to override. |
|
|
70
|
+
| `raise_on_unexpected_status` | `True` | Undocumented statuses raise `errors.UnexpectedStatus` instead of silently returning `None`. Pass `raise_on_unexpected_status=False` to restore the old opt-out. |
|
|
71
|
+
|
|
72
|
+
Explicit constructor arguments always win over these defaults (explicit arg > default).
|
|
73
|
+
|
|
74
|
+
## Async usage
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import asyncio
|
|
78
|
+
from bytekit import AuthenticatedClient
|
|
79
|
+
from bytekit.api.screenshots import create_screenshot
|
|
80
|
+
from bytekit.models.screenshot_request import ScreenshotRequest
|
|
81
|
+
|
|
82
|
+
async def main():
|
|
83
|
+
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
84
|
+
body = ScreenshotRequest(url="https://example.com")
|
|
85
|
+
response = await create_screenshot.asyncio(client=client, body=body)
|
|
86
|
+
print(response)
|
|
87
|
+
|
|
88
|
+
asyncio.run(main())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Available operations
|
|
92
|
+
|
|
93
|
+
| Module | Method | Description |
|
|
94
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
95
|
+
| `api.scrape` | `create_scrape`, `get_scrape` | Web content extraction |
|
|
96
|
+
| `api.screenshots` | `create_screenshot`, `get_screenshot` | Page screenshots |
|
|
97
|
+
| `api.bulk` | `create_bulk`, `get_bulk`, `delete_bulk`, `list_bulk_screenshots` | Bulk screenshot jobs |
|
|
98
|
+
| `api.scrape_bulk` | `create_scrape_bulk`, `get_scrape_bulk` | Bulk scrape jobs |
|
|
99
|
+
| `api.fetch` | `get_fetch`, `post_fetch` | Raw HTTP fetch |
|
|
100
|
+
| `api.fetch_bulk` | `create_fetch_bulk`, `get_fetch_bulk` | Bulk fetch jobs |
|
|
101
|
+
| `api.monitors` | `create_monitor`, `list_monitors`, `get_monitor`, `update_monitor`, `delete_monitor`, `list_monitor_captures` | Page-change monitors (screenshot + scrape) |
|
|
102
|
+
| `api.sitemap` | `create_sitemap`, `get_sitemap` | Sitemap crawl |
|
|
103
|
+
| `api.search` | `create_search` (or the `AuthenticatedClient.search(...)` convenience method) | Web search |
|
|
104
|
+
| `api.usage` | `get_usage`, `get_usage_daily`, `get_usage_by_endpoint` | Account usage & billing |
|
|
105
|
+
| `api.webhooks` | `list_webhook_deliveries`, `retry_webhook_delivery` | Webhook delivery log & retry |
|
|
106
|
+
| `api.account` | `get_account` | Account details |
|
|
107
|
+
|
|
108
|
+
## Regenerating
|
|
109
|
+
|
|
110
|
+
To regenerate the client after API changes:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pnpm --filter @bytekit/sdk-python generate
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This runs `scripts/filter-spec.ts` to produce `filtered-openapi.yaml` (filtered to v0.1 operations), runs `scripts/prune-stale-api.py` to delete any `src/bytekit/api/<tag>/` directory the filtered spec no longer produces (`generate --overwrite` itself already rebuilds `api/` from scratch on every run, so this step is defense-in-depth for a standalone run of the prune script or a future generator version — the path that actually needs the guard is `pnpm generate:docs`, which enumerates `api/` on disk independent of `generate` and can otherwise resurrect a tag whose tracked files were `git rm`-ed but whose untracked `__pycache__/` survives; see `scripts/prune-stale-api.py`'s module docstring and `has_operations()` in `scripts/generate-docs.py`), invokes `openapi-python-client generate` to update `src/bytekit/`, then runs `scripts/inject-handwritten.py` to re-append hand-written fragments (e.g. the `AuthenticatedClient.search()` convenience method) from `scripts/hand_written/` and re-patch the generated `client.py`/`errors.py` with the runtime defaults and error enrichment described above — because `--overwrite` overwrites every file it emits, both the hand-written code and these patches are wiped on every regen and must be re-applied afterward.
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Run tests
|
|
122
|
+
cd packages/sdk-python
|
|
123
|
+
python3 -m pytest tests/ -v
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Publishing
|
|
127
|
+
|
|
128
|
+
PyPI publish is handled in [#2226](https://github.com/Hunt-Labs-Inc/ByteKit/issues/2226) —
|
|
129
|
+
`.woodpecker/publish.yaml`'s `publish-pypi` step, version-gated the same way as the npm
|
|
130
|
+
siblings (publishes only when the local `pyproject.toml` version differs from what's live on
|
|
131
|
+
PyPI).
|
|
132
|
+
|
|
133
|
+
**`bytekit-sdk` has never been published.** Before the commit that arms
|
|
134
|
+
`packages/sdk-python/pyproject.toml` in `publish.yaml`'s workflow-level `when.path.include` is
|
|
135
|
+
promoted from `staging` to `main`, an operator MUST publish `0.3.0` to PyPI manually and under
|
|
136
|
+
supervision. Reason: bytekit-sdk 404s on PyPI today, so the automatic version-compare gate's
|
|
137
|
+
`|| echo "0.0.0"` fallback always fires — the first time that arming reaches `main`, it would
|
|
138
|
+
trigger a real, irreversible first `twine upload` with no manual confirmation step in between.
|
|
139
|
+
Once the manual first release exists, PUBLISHED == CURRENT and every later automatic run at an
|
|
140
|
+
unchanged version is a no-op, same as the npm packages. See the comment at the armed
|
|
141
|
+
`when.path.include` entry in `.woodpecker/publish.yaml` for the mechanism.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# bytekit-sdk
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the [ByteKit API](https://bytekit.com).
|
|
4
|
+
|
|
5
|
+
The PyPI **distribution** is `bytekit-sdk`; the **import** name is `bytekit`.
|
|
6
|
+
|
|
7
|
+
Generated from the OpenAPI spec using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client), filtered to the stable v0.1 operations.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install bytekit-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from bytekit import AuthenticatedClient
|
|
19
|
+
from bytekit.api.scrape import create_scrape
|
|
20
|
+
from bytekit.errors import UnexpectedStatus
|
|
21
|
+
from bytekit.models.scrape_request import ScrapeRequest
|
|
22
|
+
|
|
23
|
+
# base_url defaults to https://api.bytekit.com, so only the token is required.
|
|
24
|
+
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
25
|
+
|
|
26
|
+
body = ScrapeRequest(url="https://example.com")
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
response = create_scrape.sync(client=client, body=body)
|
|
30
|
+
# response.formats.markdown is str | Unset — only present when "markdown" was requested
|
|
31
|
+
print(response.formats.markdown)
|
|
32
|
+
except UnexpectedStatus as err:
|
|
33
|
+
# Errors now raise loudly by default instead of returning None.
|
|
34
|
+
print(f"request failed with status {err.status_code}: {err.code} {err.message}")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Defaults
|
|
38
|
+
|
|
39
|
+
The client ships with production-ready defaults so `AuthenticatedClient(token=...)` works out of the box:
|
|
40
|
+
|
|
41
|
+
| Setting | Default | Notes |
|
|
42
|
+
| ---------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `base_url` | `https://api.bytekit.com` | Pass `base_url=` to target staging or a proxy. |
|
|
44
|
+
| `timeout` | `120s` (`httpx.Timeout(120.0)`) | Finite by default — requests no longer hang indefinitely. Pass `timeout=` to override. |
|
|
45
|
+
| `raise_on_unexpected_status` | `True` | Undocumented statuses raise `errors.UnexpectedStatus` instead of silently returning `None`. Pass `raise_on_unexpected_status=False` to restore the old opt-out. |
|
|
46
|
+
|
|
47
|
+
Explicit constructor arguments always win over these defaults (explicit arg > default).
|
|
48
|
+
|
|
49
|
+
## Async usage
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import asyncio
|
|
53
|
+
from bytekit import AuthenticatedClient
|
|
54
|
+
from bytekit.api.screenshots import create_screenshot
|
|
55
|
+
from bytekit.models.screenshot_request import ScreenshotRequest
|
|
56
|
+
|
|
57
|
+
async def main():
|
|
58
|
+
client = AuthenticatedClient(token="sk_live_your_api_key_here")
|
|
59
|
+
body = ScreenshotRequest(url="https://example.com")
|
|
60
|
+
response = await create_screenshot.asyncio(client=client, body=body)
|
|
61
|
+
print(response)
|
|
62
|
+
|
|
63
|
+
asyncio.run(main())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Available operations
|
|
67
|
+
|
|
68
|
+
| Module | Method | Description |
|
|
69
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
70
|
+
| `api.scrape` | `create_scrape`, `get_scrape` | Web content extraction |
|
|
71
|
+
| `api.screenshots` | `create_screenshot`, `get_screenshot` | Page screenshots |
|
|
72
|
+
| `api.bulk` | `create_bulk`, `get_bulk`, `delete_bulk`, `list_bulk_screenshots` | Bulk screenshot jobs |
|
|
73
|
+
| `api.scrape_bulk` | `create_scrape_bulk`, `get_scrape_bulk` | Bulk scrape jobs |
|
|
74
|
+
| `api.fetch` | `get_fetch`, `post_fetch` | Raw HTTP fetch |
|
|
75
|
+
| `api.fetch_bulk` | `create_fetch_bulk`, `get_fetch_bulk` | Bulk fetch jobs |
|
|
76
|
+
| `api.monitors` | `create_monitor`, `list_monitors`, `get_monitor`, `update_monitor`, `delete_monitor`, `list_monitor_captures` | Page-change monitors (screenshot + scrape) |
|
|
77
|
+
| `api.sitemap` | `create_sitemap`, `get_sitemap` | Sitemap crawl |
|
|
78
|
+
| `api.search` | `create_search` (or the `AuthenticatedClient.search(...)` convenience method) | Web search |
|
|
79
|
+
| `api.usage` | `get_usage`, `get_usage_daily`, `get_usage_by_endpoint` | Account usage & billing |
|
|
80
|
+
| `api.webhooks` | `list_webhook_deliveries`, `retry_webhook_delivery` | Webhook delivery log & retry |
|
|
81
|
+
| `api.account` | `get_account` | Account details |
|
|
82
|
+
|
|
83
|
+
## Regenerating
|
|
84
|
+
|
|
85
|
+
To regenerate the client after API changes:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pnpm --filter @bytekit/sdk-python generate
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This runs `scripts/filter-spec.ts` to produce `filtered-openapi.yaml` (filtered to v0.1 operations), runs `scripts/prune-stale-api.py` to delete any `src/bytekit/api/<tag>/` directory the filtered spec no longer produces (`generate --overwrite` itself already rebuilds `api/` from scratch on every run, so this step is defense-in-depth for a standalone run of the prune script or a future generator version — the path that actually needs the guard is `pnpm generate:docs`, which enumerates `api/` on disk independent of `generate` and can otherwise resurrect a tag whose tracked files were `git rm`-ed but whose untracked `__pycache__/` survives; see `scripts/prune-stale-api.py`'s module docstring and `has_operations()` in `scripts/generate-docs.py`), invokes `openapi-python-client generate` to update `src/bytekit/`, then runs `scripts/inject-handwritten.py` to re-append hand-written fragments (e.g. the `AuthenticatedClient.search()` convenience method) from `scripts/hand_written/` and re-patch the generated `client.py`/`errors.py` with the runtime defaults and error enrichment described above — because `--overwrite` overwrites every file it emits, both the hand-written code and these patches are wiped on every regen and must be re-applied afterward.
|
|
92
|
+
|
|
93
|
+
## Development
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Run tests
|
|
97
|
+
cd packages/sdk-python
|
|
98
|
+
python3 -m pytest tests/ -v
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Publishing
|
|
102
|
+
|
|
103
|
+
PyPI publish is handled in [#2226](https://github.com/Hunt-Labs-Inc/ByteKit/issues/2226) —
|
|
104
|
+
`.woodpecker/publish.yaml`'s `publish-pypi` step, version-gated the same way as the npm
|
|
105
|
+
siblings (publishes only when the local `pyproject.toml` version differs from what's live on
|
|
106
|
+
PyPI).
|
|
107
|
+
|
|
108
|
+
**`bytekit-sdk` has never been published.** Before the commit that arms
|
|
109
|
+
`packages/sdk-python/pyproject.toml` in `publish.yaml`'s workflow-level `when.path.include` is
|
|
110
|
+
promoted from `staging` to `main`, an operator MUST publish `0.3.0` to PyPI manually and under
|
|
111
|
+
supervision. Reason: bytekit-sdk 404s on PyPI today, so the automatic version-compare gate's
|
|
112
|
+
`|| echo "0.0.0"` fallback always fires — the first time that arming reaches `main`, it would
|
|
113
|
+
trigger a real, irreversible first `twine upload` with no manual confirmation step in between.
|
|
114
|
+
Once the manual first release exists, PUBLISHED == CURRENT and every later automatic run at an
|
|
115
|
+
unchanged version is a no-op, same as the npm packages. See the comment at the armed
|
|
116
|
+
`when.path.include` entry in `.woodpecker/publish.yaml` for the mechanism.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
# DISTRIBUTION name only. PyPI administratively denylists the bare name `bytekit`
|
|
3
|
+
# (`400 The name 'bytekit' isn't allowed.` — observed on the first real publish attempt,
|
|
4
|
+
# Woodpecker pipeline 2024/workflow 4, 2026-07-22; issue #2530), and no API can pre-check
|
|
5
|
+
# a name — only a real upload can. The IMPORT name is deliberately unchanged: the wheel
|
|
6
|
+
# still packages `src/bytekit` (see [tool.hatch.build.targets.wheel] below), so
|
|
7
|
+
# `pip install bytekit-sdk` yields a working `import bytekit`. Mirrors the npm sibling
|
|
8
|
+
# @hunt-labs/bytekit-sdk.
|
|
9
|
+
name = "bytekit-sdk"
|
|
10
|
+
version = "0.3.0"
|
|
11
|
+
description = "Official Python SDK for the ByteKit API"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
# SPDX expression (PEP 639), matching the npm siblings @hunt-labs/bytekit-sdk and
|
|
15
|
+
# @hunt-labs/bytekit-cli. Deliberately NOT paired with a legacy "License ::" trove
|
|
16
|
+
# classifier: PyPI rejects an upload that carries both a License-Expression and a
|
|
17
|
+
# License classifier, and that rejection would only surface at twine upload time.
|
|
18
|
+
license = "MIT"
|
|
19
|
+
keywords = [
|
|
20
|
+
"bytekit",
|
|
21
|
+
"scraping",
|
|
22
|
+
"web-scraping",
|
|
23
|
+
"crawler",
|
|
24
|
+
"screenshots",
|
|
25
|
+
"markdown",
|
|
26
|
+
"api",
|
|
27
|
+
"sdk",
|
|
28
|
+
"llm",
|
|
29
|
+
]
|
|
30
|
+
classifiers = [
|
|
31
|
+
"Development Status :: 4 - Beta",
|
|
32
|
+
"Intended Audience :: Developers",
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Programming Language :: Python :: 3.10",
|
|
35
|
+
"Programming Language :: Python :: 3.11",
|
|
36
|
+
"Programming Language :: Python :: 3.12",
|
|
37
|
+
"Programming Language :: Python :: 3.13",
|
|
38
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
39
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
40
|
+
"Typing :: Typed",
|
|
41
|
+
]
|
|
42
|
+
dependencies = [
|
|
43
|
+
"httpx>=0.24.0",
|
|
44
|
+
"attrs>=23.1.0",
|
|
45
|
+
"python-dateutil>=2.8.0",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://bytekit.com"
|
|
50
|
+
Repository = "https://github.com/Hunt-Labs-Inc/ByteKit"
|
|
51
|
+
Documentation = "https://bytekit.com/docs"
|
|
52
|
+
|
|
53
|
+
# Code-generation toolchain. Pinned to an exact version so `pnpm generate`
|
|
54
|
+
# reproduces the same client tree across machines and CI runs (E1/E5 idempotency).
|
|
55
|
+
# The generated style is version-sensitive, so bumping this pin is a deliberate,
|
|
56
|
+
# reviewed regeneration — never an incidental upgrade.
|
|
57
|
+
[dependency-groups]
|
|
58
|
+
dev = [
|
|
59
|
+
"openapi-python-client==0.25.3",
|
|
60
|
+
# Read by scripts/prune-stale-api.py (parses filtered-openapi.yaml to derive which
|
|
61
|
+
# api/ group dirs the spec still produces) and by tests/conftest.py. Generation-time
|
|
62
|
+
# and test-time only — never a runtime dependency of the published client.
|
|
63
|
+
"pyyaml>=6.0",
|
|
64
|
+
# tomllib is stdlib-only from Python 3.11; this package's declared floor is 3.10
|
|
65
|
+
# (see requires-python above), so tests/test_publish_metadata.py falls back to the
|
|
66
|
+
# tomli backport below 3.11. CI pins python:3.12 so this never installs there —
|
|
67
|
+
# it exists purely so a contributor running pytest locally on 3.10 isn't stuck
|
|
68
|
+
# with a collection-time ModuleNotFoundError (issue #2226 code review).
|
|
69
|
+
"tomli>=2.0.0; python_version < '3.11'",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[build-system]
|
|
73
|
+
requires = ["hatchling"]
|
|
74
|
+
build-backend = "hatchling.build"
|
|
75
|
+
|
|
76
|
+
[tool.hatch.build.targets.wheel]
|
|
77
|
+
# Source layout: generated client lives in src/bytekit/
|
|
78
|
+
packages = ["src/bytekit"]
|
|
79
|
+
|
|
80
|
+
[tool.pytest.ini_options]
|
|
81
|
+
testpaths = ["tests"]
|
|
82
|
+
pythonpath = ["src"]
|
|
83
|
+
|
|
84
|
+
[tool.hatch.build.targets.sdist]
|
|
85
|
+
include = [
|
|
86
|
+
"src/bytekit/**",
|
|
87
|
+
"tests/**",
|
|
88
|
+
"README.md",
|
|
89
|
+
"CHANGELOG.md",
|
|
90
|
+
]
|
|
91
|
+
exclude = [
|
|
92
|
+
"node_modules",
|
|
93
|
+
"**/node_modules",
|
|
94
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains methods for accessing the API"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains endpoint functions for accessing the API"""
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any, Optional, Union
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from ... import errors
|
|
7
|
+
from ...client import AuthenticatedClient, Client
|
|
8
|
+
from ...models.account_bearer_response import AccountBearerResponse
|
|
9
|
+
from ...models.account_session_response import AccountSessionResponse
|
|
10
|
+
from ...types import Response
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _get_kwargs() -> dict[str, Any]:
|
|
14
|
+
_kwargs: dict[str, Any] = {
|
|
15
|
+
"method": "get",
|
|
16
|
+
"url": "/v1/account",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return _kwargs
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _parse_response(
|
|
23
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
|
24
|
+
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
25
|
+
if response.status_code == 200:
|
|
26
|
+
|
|
27
|
+
def _parse_response_200(
|
|
28
|
+
data: object,
|
|
29
|
+
) -> Union["AccountBearerResponse", "AccountSessionResponse"]:
|
|
30
|
+
try:
|
|
31
|
+
if not isinstance(data, dict):
|
|
32
|
+
raise TypeError()
|
|
33
|
+
response_200_type_0 = AccountBearerResponse.from_dict(data)
|
|
34
|
+
|
|
35
|
+
return response_200_type_0
|
|
36
|
+
except: # noqa: E722
|
|
37
|
+
pass
|
|
38
|
+
if not isinstance(data, dict):
|
|
39
|
+
raise TypeError()
|
|
40
|
+
response_200_type_1 = AccountSessionResponse.from_dict(data)
|
|
41
|
+
|
|
42
|
+
return response_200_type_1
|
|
43
|
+
|
|
44
|
+
response_200 = _parse_response_200(response.json())
|
|
45
|
+
|
|
46
|
+
return response_200
|
|
47
|
+
if client.raise_on_unexpected_status:
|
|
48
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
49
|
+
else:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _build_response(
|
|
54
|
+
*, client: Union[AuthenticatedClient, Client], response: httpx.Response
|
|
55
|
+
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
56
|
+
return Response(
|
|
57
|
+
status_code=HTTPStatus(response.status_code),
|
|
58
|
+
content=response.content,
|
|
59
|
+
headers=response.headers,
|
|
60
|
+
parsed=_parse_response(client=client, response=response),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def sync_detailed(
|
|
65
|
+
*,
|
|
66
|
+
client: AuthenticatedClient,
|
|
67
|
+
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
68
|
+
"""Get account details
|
|
69
|
+
|
|
70
|
+
Returns account, plan, and current API key details, including the
|
|
71
|
+
`api_key` and `subscription` fields.
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
75
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Response[Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
kwargs = _get_kwargs()
|
|
82
|
+
|
|
83
|
+
response = client.get_httpx_client().request(
|
|
84
|
+
**kwargs,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return _build_response(client=client, response=response)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def sync(
|
|
91
|
+
*,
|
|
92
|
+
client: AuthenticatedClient,
|
|
93
|
+
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
94
|
+
"""Get account details
|
|
95
|
+
|
|
96
|
+
Returns account, plan, and current API key details, including the
|
|
97
|
+
`api_key` and `subscription` fields.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
101
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Union['AccountBearerResponse', 'AccountSessionResponse']
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
return sync_detailed(
|
|
108
|
+
client=client,
|
|
109
|
+
).parsed
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
async def asyncio_detailed(
|
|
113
|
+
*,
|
|
114
|
+
client: AuthenticatedClient,
|
|
115
|
+
) -> Response[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
116
|
+
"""Get account details
|
|
117
|
+
|
|
118
|
+
Returns account, plan, and current API key details, including the
|
|
119
|
+
`api_key` and `subscription` fields.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
123
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Response[Union['AccountBearerResponse', 'AccountSessionResponse']]
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
kwargs = _get_kwargs()
|
|
130
|
+
|
|
131
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
132
|
+
|
|
133
|
+
return _build_response(client=client, response=response)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
async def asyncio(
|
|
137
|
+
*,
|
|
138
|
+
client: AuthenticatedClient,
|
|
139
|
+
) -> Optional[Union["AccountBearerResponse", "AccountSessionResponse"]]:
|
|
140
|
+
"""Get account details
|
|
141
|
+
|
|
142
|
+
Returns account, plan, and current API key details, including the
|
|
143
|
+
`api_key` and `subscription` fields.
|
|
144
|
+
|
|
145
|
+
Raises:
|
|
146
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
147
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Union['AccountBearerResponse', 'AccountSessionResponse']
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
await asyncio_detailed(
|
|
155
|
+
client=client,
|
|
156
|
+
)
|
|
157
|
+
).parsed
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains endpoint functions for accessing the API"""
|