eggfetch 0.1.1__tar.gz → 0.1.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.
- {eggfetch-0.1.1 → eggfetch-0.1.4}/Cargo.lock +36 -16
- {eggfetch-0.1.1 → eggfetch-0.1.4}/Cargo.toml +2 -1
- eggfetch-0.1.4/PKG-INFO +240 -0
- eggfetch-0.1.4/README.md +215 -0
- eggfetch-0.1.4/crates/eggfetch-core/Cargo.toml +95 -0
- eggfetch-0.1.4/crates/eggfetch-core/README.md +215 -0
- eggfetch-0.1.4/crates/eggfetch-core/examples/quickstart.rs +75 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/body.rs +447 -11
- eggfetch-0.1.4/crates/eggfetch-core/src/client.rs +1719 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/compression.rs +1400 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/cookie.rs +416 -119
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/error.rs +32 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/headers.rs +158 -6
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/http_version.rs +1 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/lib.rs +16 -3
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/limits.rs +87 -7
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/multipart.rs +294 -38
- eggfetch-0.1.4/crates/eggfetch-core/src/network_stream.rs +620 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/pipeline.rs +2476 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/pool.rs +494 -89
- eggfetch-0.1.4/crates/eggfetch-core/src/proxy.rs +1801 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/redact.rs +8 -10
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/redirect.rs +128 -30
- eggfetch-0.1.4/crates/eggfetch-core/src/request.rs +983 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/response.rs +1008 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/response_decode.rs +170 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/retry.rs +158 -41
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/stream/read_timeout.rs +39 -10
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/stream/write_timeout.rs +70 -12
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/timeout.rs +8 -7
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/tls.rs +552 -107
- eggfetch-0.1.4/crates/eggfetch-core/src/trace.rs +368 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/alt_svc.rs +1131 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/connect.rs +578 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/direct.rs +498 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/direct_connector.rs +669 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/http3.rs +1559 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/metrics.rs +543 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/mod.rs +68 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/proxy.rs +1323 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/socks.rs +784 -0
- eggfetch-0.1.4/crates/eggfetch-core/src/transport/uds.rs +295 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/adverse_tests.rs +17 -12
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/cross_feature_tests.rs +52 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/direct_transport_tests.rs +641 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/h3_alt_svc_discovery.rs +935 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/h3_hardening.rs +536 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/h3_integration.rs +1 -1
- eggfetch-0.1.4/crates/eggfetch-core/tests/h3_interop_qualification.rs +937 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/http2_tests.rs +35 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/integration.rs +1 -1
- eggfetch-0.1.4/crates/eggfetch-core/tests/native_json.rs +273 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/network_stream_tests.rs +695 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/pool_tests.rs +50 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/proxy_tests.rs +691 -8
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/retry_integration.rs +135 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/tls_fixtures.rs +13 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/tls_integration.rs +67 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/trailer_tests.rs +208 -0
- eggfetch-0.1.4/crates/eggfetch-core/tests/transport_metrics_tests.rs +254 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/Cargo.toml +10 -3
- eggfetch-0.1.4/crates/eggfetch-python/README.md +215 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/async_client.rs +213 -56
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/client.rs +315 -66
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/conversion.rs +191 -42
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/cookies.rs +14 -2
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/errors.rs +9 -0
- eggfetch-0.1.4/crates/eggfetch-python/src/extensions.rs +158 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/headers.rs +22 -30
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/lib.rs +16 -8
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/limits.rs +9 -2
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/multipart.rs +1 -1
- eggfetch-0.1.4/crates/eggfetch-python/src/network_stream.rs +847 -0
- eggfetch-0.1.4/crates/eggfetch-python/src/proxy.rs +177 -0
- eggfetch-0.1.4/crates/eggfetch-python/src/response.rs +577 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/retry.rs +14 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/streaming.rs +345 -163
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/timeout.rs +18 -6
- eggfetch-0.1.4/crates/eggfetch-python/src/tls.rs +270 -0
- eggfetch-0.1.4/crates/eggfetch-python/src/trace_bridge.rs +253 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/fixtures.py +8 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/native_fixtures.py +935 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_auth.py +87 -7
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_auth_input_normalization.py +184 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_client.py +4 -1
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_client_mutability_and_state.py +318 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_client_stream_overrides.py +142 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_config_objects.py +98 -4
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_cookie_scope_parity.py +273 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_cookies.py +40 -17
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_corrective_01_tls_and_proxy_trust_safety.py +449 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_corrective_01_tls_network_proof.py +368 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_corrective_02_extensions_and_wire_metadata.py +364 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_corrective_03_network_stream_upgrade.py +798 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_corrective_kernel.py +375 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_environment.py +56 -5
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_exceptions.py +56 -10
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_extensions.py +84 -22
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_h2_differential.py +647 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_headers.py +92 -2
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_hook_auth_ordering.py +70 -30
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_hook_cookie_auth_ordering.py +230 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_hooks.py +91 -6
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_httpx2_api_parity.py +186 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_httpx2_behavior.py +96 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_httpx2_sse.py +119 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_httpx2_websocket.py +209 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_httpx_reference_pinning.py +173 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_lossy_conversions.py +13 -4
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_merge_matrix.py +4 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_mounts.py +175 -12
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_multihop_cleanup.py +178 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_native_proxy_tls.py +255 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_native_timeout_classification.py +37 -42
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_no_proxy_differential.py +429 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_protocol_and_unsupported_options.py +169 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_proxy_differential.py +153 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_proxy_phase05_tracks.py +461 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_raw_stream_httpx_differential.py +638 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_raw_stream_lifecycle.py +102 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_redirect_state_machine_parity.py +477 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_request.py +7 -6
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_request_construction_parity.py +215 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_request_stream_state.py +138 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_request_streaming.py +5 -3
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_response.py +50 -4
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_response_encoding_parity.py +70 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_response_metadata_parity.py +111 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_response_status_and_redirect_state.py +151 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_response_stream_state_parity.py +199 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_response_streaming.py +5 -6
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_socks_transport.py +301 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_ssl_context_network_proof.py +672 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_ssl_context_translation.py +412 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_stream_resources.py +28 -2
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_timeout_proxysis.py +13 -12
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_timeout_reference_differential.py +119 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_top_level_helpers_parity.py +366 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_trace_detection.py +131 -0
- eggfetch-0.1.4/crates/eggfetch-python/tests/compat/test_uds_transport.py +233 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_url_query.py +104 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_async.py +7 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_http2.py +8 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_response_compat.py +3 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_retry.py +14 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_sync.py +60 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/pyproject.toml +7 -3
- eggfetch-0.1.4/python/eggfetch/compat/httpx/__init__.py +651 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_asgi.py +2 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_auth.py +19 -14
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_client.py +2622 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_cookies.py +265 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_diagnostics.py +14 -1
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_exceptions.py +15 -3
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_headers.py +34 -13
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_mock.py +8 -3
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_proxy.py +113 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_request.py +443 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_response.py +782 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_ssl_context.py +531 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_status_codes.py +74 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_stream.py +25 -19
- eggfetch-0.1.4/python/eggfetch/compat/httpx/_timeout.py +166 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_transports.py +86 -62
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_urls.py +38 -5
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_wsgi.py +2 -1
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/__init__.py +257 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_alias.py +79 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_api.py +220 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_asgi.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_auth.py +40 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_client.py +279 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_config.py +49 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_cookies.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_exceptions.py +80 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_headers.py +51 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_mock.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_request.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_response.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_sse.py +214 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_status_codes.py +108 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_stream.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_transports.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_urls.py +75 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/_wsgi.py +7 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/websockets/__init__.py +57 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/websockets/_api.py +1664 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/websockets/_exceptions.py +55 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/websockets/_ping.py +43 -0
- eggfetch-0.1.4/python/eggfetch/compat/httpx2/websockets/_transport.py +289 -0
- eggfetch-0.1.1/PKG-INFO +0 -302
- eggfetch-0.1.1/README.md +0 -280
- eggfetch-0.1.1/crates/eggfetch-core/Cargo.toml +0 -68
- eggfetch-0.1.1/crates/eggfetch-core/README.md +0 -280
- eggfetch-0.1.1/crates/eggfetch-core/src/client.rs +0 -911
- eggfetch-0.1.1/crates/eggfetch-core/src/compression.rs +0 -875
- eggfetch-0.1.1/crates/eggfetch-core/src/pipeline.rs +0 -872
- eggfetch-0.1.1/crates/eggfetch-core/src/proxy.rs +0 -986
- eggfetch-0.1.1/crates/eggfetch-core/src/request.rs +0 -469
- eggfetch-0.1.1/crates/eggfetch-core/src/response.rs +0 -472
- eggfetch-0.1.1/crates/eggfetch-core/src/response_decode.rs +0 -54
- eggfetch-0.1.1/crates/eggfetch-core/src/transport/connect.rs +0 -284
- eggfetch-0.1.1/crates/eggfetch-core/src/transport/direct.rs +0 -139
- eggfetch-0.1.1/crates/eggfetch-core/src/transport/http3.rs +0 -261
- eggfetch-0.1.1/crates/eggfetch-core/src/transport/mod.rs +0 -33
- eggfetch-0.1.1/crates/eggfetch-core/src/transport/proxy.rs +0 -418
- eggfetch-0.1.1/crates/eggfetch-python/README.md +0 -280
- eggfetch-0.1.1/crates/eggfetch-python/src/proxy.rs +0 -63
- eggfetch-0.1.1/crates/eggfetch-python/src/response.rs +0 -354
- eggfetch-0.1.1/crates/eggfetch-python/src/tls.rs +0 -54
- eggfetch-0.1.1/crates/eggfetch-python/tests/compat/native_fixtures.py +0 -354
- eggfetch-0.1.1/python/eggfetch/compat/httpx/__init__.py +0 -231
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_client.py +0 -1168
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_cookies.py +0 -121
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_proxy.py +0 -70
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_request.py +0 -292
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_response.py +0 -497
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_status_codes.py +0 -80
- eggfetch-0.1.1/python/eggfetch/compat/httpx/_timeout.py +0 -124
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/auth.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/config.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/h2_headers.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/stream/mod.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/src/transport/connect_timeout.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/http3_tests.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/resource_stabilization.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/test_server.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-core/tests/timeout_tests.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/src/auth.rs +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/__init__.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/conftest.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_asgi.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_auth_replay.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_backends.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_behavior_cases.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_downstream_portfolio.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_downstream_runner_negative.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_httpx_extras.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_httpx_required.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_imports.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_lifecycle.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_merge_lossless.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_mock_transport.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_oracle_negative.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_resource_assertions.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_shutdown.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_soak.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_timeout_integration.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_transports.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/compat/test_wsgi.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/conftest.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_auth.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_close_races.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_cookie_auth.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_cookies.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_differential.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_interpreter_shutdown.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_parity.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_proxy.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_redirects.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/crates/eggfetch-python/tests/test_streaming.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/__init__.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/__init__.py +0 -0
- {eggfetch-0.1.1 → eggfetch-0.1.4}/python/eggfetch/compat/httpx/_limits.py +0 -0
|
@@ -509,7 +509,7 @@ dependencies = [
|
|
|
509
509
|
|
|
510
510
|
[[package]]
|
|
511
511
|
name = "eggfetch-cli"
|
|
512
|
-
version = "0.1.
|
|
512
|
+
version = "0.1.4"
|
|
513
513
|
dependencies = [
|
|
514
514
|
"anyhow",
|
|
515
515
|
"bytes",
|
|
@@ -526,10 +526,11 @@ dependencies = [
|
|
|
526
526
|
|
|
527
527
|
[[package]]
|
|
528
528
|
name = "eggfetch-core"
|
|
529
|
-
version = "0.1.
|
|
529
|
+
version = "0.1.4"
|
|
530
530
|
dependencies = [
|
|
531
531
|
"async-compression",
|
|
532
532
|
"base64",
|
|
533
|
+
"brotli",
|
|
533
534
|
"bytes",
|
|
534
535
|
"cookie",
|
|
535
536
|
"dashmap",
|
|
@@ -537,35 +538,41 @@ dependencies = [
|
|
|
537
538
|
"futures-core",
|
|
538
539
|
"futures-util",
|
|
539
540
|
"getrandom 0.2.17",
|
|
541
|
+
"h2",
|
|
540
542
|
"h3",
|
|
541
543
|
"h3-quinn",
|
|
542
544
|
"http",
|
|
543
545
|
"http-body",
|
|
544
546
|
"http-body-util",
|
|
545
|
-
"httparse",
|
|
546
547
|
"httpdate",
|
|
547
548
|
"hyper",
|
|
548
549
|
"hyper-rustls",
|
|
549
550
|
"hyper-util",
|
|
550
551
|
"pem-rfc7468",
|
|
552
|
+
"percent-encoding",
|
|
551
553
|
"pin-project-lite",
|
|
552
554
|
"proptest",
|
|
553
555
|
"quinn",
|
|
554
556
|
"rcgen",
|
|
555
557
|
"rustls",
|
|
558
|
+
"rustls-native-certs",
|
|
559
|
+
"serde",
|
|
560
|
+
"serde_json",
|
|
556
561
|
"tempfile",
|
|
557
562
|
"thiserror",
|
|
558
563
|
"tokio",
|
|
559
564
|
"tokio-rustls",
|
|
560
565
|
"tokio-util",
|
|
561
566
|
"tower-service",
|
|
567
|
+
"tracing",
|
|
562
568
|
"url",
|
|
563
569
|
"webpki-roots 0.26.11",
|
|
570
|
+
"zstd",
|
|
564
571
|
]
|
|
565
572
|
|
|
566
573
|
[[package]]
|
|
567
574
|
name = "eggfetch-ffi"
|
|
568
|
-
version = "0.1.
|
|
575
|
+
version = "0.1.4"
|
|
569
576
|
dependencies = [
|
|
570
577
|
"bytes",
|
|
571
578
|
"eggfetch-core",
|
|
@@ -577,7 +584,7 @@ dependencies = [
|
|
|
577
584
|
|
|
578
585
|
[[package]]
|
|
579
586
|
name = "eggfetch-node"
|
|
580
|
-
version = "0.1.
|
|
587
|
+
version = "0.1.4"
|
|
581
588
|
dependencies = [
|
|
582
589
|
"eggfetch-ffi",
|
|
583
590
|
"napi",
|
|
@@ -589,7 +596,7 @@ dependencies = [
|
|
|
589
596
|
|
|
590
597
|
[[package]]
|
|
591
598
|
name = "eggfetch-python"
|
|
592
|
-
version = "0.1.
|
|
599
|
+
version = "0.1.4"
|
|
593
600
|
dependencies = [
|
|
594
601
|
"bytes",
|
|
595
602
|
"eggfetch-core",
|
|
@@ -599,8 +606,11 @@ dependencies = [
|
|
|
599
606
|
"pyo3",
|
|
600
607
|
"pyo3-async-runtimes",
|
|
601
608
|
"pyo3-build-config",
|
|
609
|
+
"rustls",
|
|
602
610
|
"tokio",
|
|
611
|
+
"tokio-rustls",
|
|
603
612
|
"url",
|
|
613
|
+
"webpki-roots 0.26.11",
|
|
604
614
|
]
|
|
605
615
|
|
|
606
616
|
[[package]]
|
|
@@ -631,7 +641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
631
641
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
|
632
642
|
dependencies = [
|
|
633
643
|
"libc",
|
|
634
|
-
"windows-sys 0.
|
|
644
|
+
"windows-sys 0.52.0",
|
|
635
645
|
]
|
|
636
646
|
|
|
637
647
|
[[package]]
|
|
@@ -788,9 +798,9 @@ dependencies = [
|
|
|
788
798
|
|
|
789
799
|
[[package]]
|
|
790
800
|
name = "h2"
|
|
791
|
-
version = "0.4.
|
|
801
|
+
version = "0.4.16"
|
|
792
802
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
793
|
-
checksum = "
|
|
803
|
+
checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27"
|
|
794
804
|
dependencies = [
|
|
795
805
|
"atomic-waker",
|
|
796
806
|
"bytes",
|
|
@@ -945,11 +955,9 @@ dependencies = [
|
|
|
945
955
|
"hyper-util",
|
|
946
956
|
"log",
|
|
947
957
|
"rustls",
|
|
948
|
-
"rustls-native-certs",
|
|
949
958
|
"tokio",
|
|
950
959
|
"tokio-rustls",
|
|
951
960
|
"tower-service",
|
|
952
|
-
"webpki-roots 1.0.8",
|
|
953
961
|
]
|
|
954
962
|
|
|
955
963
|
[[package]]
|
|
@@ -1102,7 +1110,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
|
|
1102
1110
|
dependencies = [
|
|
1103
1111
|
"hermit-abi",
|
|
1104
1112
|
"libc",
|
|
1105
|
-
"windows-sys 0.
|
|
1113
|
+
"windows-sys 0.52.0",
|
|
1106
1114
|
]
|
|
1107
1115
|
|
|
1108
1116
|
[[package]]
|
|
@@ -1617,7 +1625,7 @@ dependencies = [
|
|
|
1617
1625
|
"once_cell",
|
|
1618
1626
|
"socket2",
|
|
1619
1627
|
"tracing",
|
|
1620
|
-
"windows-sys 0.
|
|
1628
|
+
"windows-sys 0.52.0",
|
|
1621
1629
|
]
|
|
1622
1630
|
|
|
1623
1631
|
[[package]]
|
|
@@ -1801,7 +1809,7 @@ dependencies = [
|
|
|
1801
1809
|
"errno",
|
|
1802
1810
|
"libc",
|
|
1803
1811
|
"linux-raw-sys",
|
|
1804
|
-
"windows-sys 0.
|
|
1812
|
+
"windows-sys 0.52.0",
|
|
1805
1813
|
]
|
|
1806
1814
|
|
|
1807
1815
|
[[package]]
|
|
@@ -2066,7 +2074,7 @@ dependencies = [
|
|
|
2066
2074
|
"getrandom 0.4.3",
|
|
2067
2075
|
"once_cell",
|
|
2068
2076
|
"rustix",
|
|
2069
|
-
"windows-sys 0.
|
|
2077
|
+
"windows-sys 0.52.0",
|
|
2070
2078
|
]
|
|
2071
2079
|
|
|
2072
2080
|
[[package]]
|
|
@@ -2227,9 +2235,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
2227
2235
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
|
2228
2236
|
dependencies = [
|
|
2229
2237
|
"pin-project-lite",
|
|
2238
|
+
"tracing-attributes",
|
|
2230
2239
|
"tracing-core",
|
|
2231
2240
|
]
|
|
2232
2241
|
|
|
2242
|
+
[[package]]
|
|
2243
|
+
name = "tracing-attributes"
|
|
2244
|
+
version = "0.1.31"
|
|
2245
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2246
|
+
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
|
2247
|
+
dependencies = [
|
|
2248
|
+
"proc-macro2",
|
|
2249
|
+
"quote",
|
|
2250
|
+
"syn",
|
|
2251
|
+
]
|
|
2252
|
+
|
|
2233
2253
|
[[package]]
|
|
2234
2254
|
name = "tracing-core"
|
|
2235
2255
|
version = "0.1.36"
|
|
@@ -2428,7 +2448,7 @@ version = "0.1.11"
|
|
|
2428
2448
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2429
2449
|
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
|
2430
2450
|
dependencies = [
|
|
2431
|
-
"windows-sys 0.
|
|
2451
|
+
"windows-sys 0.52.0",
|
|
2432
2452
|
]
|
|
2433
2453
|
|
|
2434
2454
|
[[package]]
|
|
@@ -5,8 +5,9 @@ members = ["crates/eggfetch-core", "crates/eggfetch-python"]
|
|
|
5
5
|
[workspace.package]
|
|
6
6
|
edition = "2021"
|
|
7
7
|
rust-version = "1.80"
|
|
8
|
-
license = "MIT
|
|
8
|
+
license = "MIT"
|
|
9
9
|
repository = "https://github.com/eggstack/eggfetch"
|
|
10
|
+
homepage = "https://github.com/eggstack/eggfetch"
|
|
10
11
|
readme = "README.md"
|
|
11
12
|
|
|
12
13
|
[workspace.lints.rust]
|
eggfetch-0.1.4/PKG-INFO
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eggfetch
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Rust
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Requires-Dist: pytest>=8.4 ; extra == 'test'
|
|
13
|
+
Requires-Dist: pytest-asyncio>=1.0 ; extra == 'test'
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Summary: Python bindings for eggfetch
|
|
16
|
+
Keywords: http,client,httpx,async,rust
|
|
17
|
+
Home-Page: https://github.com/eggstack/eggfetch
|
|
18
|
+
Author: eggfetch contributors
|
|
19
|
+
License: MIT
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
22
|
+
Project-URL: Homepage, https://github.com/eggstack/eggfetch
|
|
23
|
+
Project-URL: Repository, https://github.com/eggstack/eggfetch
|
|
24
|
+
|
|
25
|
+
# eggfetch
|
|
26
|
+
|
|
27
|
+
[](https://github.com/eggstack/eggfetch/actions/workflows/ci.yml)
|
|
28
|
+
[](https://crates.io/crates/eggfetch-core)
|
|
29
|
+
[](https://crates.io/crates/eggfetch-core)
|
|
30
|
+
[](https://pypi.org/project/eggfetch/)
|
|
31
|
+
[](https://pepy.tech/projects/eggfetch)
|
|
32
|
+
[](LICENSE-MIT)
|
|
33
|
+
|
|
34
|
+
eggfetch is a Rust-native async HTTP client engine (tokio + hyper) with Python bindings and a CLI. There is exactly one networking implementation, living entirely in `eggfetch-core`; the Python sync API blocks on the async engine while releasing the GIL, and the async API integrates with asyncio.
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **HTTP/1.1, HTTP/2, HTTP/3** — ALPN negotiation; HTTP/3 over QUIC stays experimental ([graduation gate](docs/architecture/core-tls-proxy-protocols.md))
|
|
39
|
+
- **Streaming** — request/response bodies without eager buffering (`bytes_stream()`, `text_lines()`); trailers via `Response::trailers()` ([guide](docs/rust/guide.md))
|
|
40
|
+
- **Pooling, timeouts, observability** — per-origin in-flight limits, phase-aware timeouts (pool/connect/write/read/total), connector/DNS/TLS and H3 transport metrics ([pool/timeouts](docs/architecture/core-timeout-pool.md))
|
|
41
|
+
- **TLS** — rustls with custom CA bundles, mTLS client certs, version policy, verification toggle ([TLS](docs/concepts/tls.md))
|
|
42
|
+
- **Proxy** — HTTP forwarding, HTTPS CONNECT, proxy auth, per-request override, `NO_PROXY`; SOCKS5 and UDS routes ([proxy](docs/concepts/proxy.md))
|
|
43
|
+
- **Cookies, auth, multipart** — RFC 6265 jar, Basic/Bearer with redaction, streaming multipart uploads ([cookies](docs/concepts/cookies.md))
|
|
44
|
+
- **Retries and redirects** — policy-driven backoff with `Retry-After`, replayable-body redirect handling ([retry](docs/concepts/retry.md))
|
|
45
|
+
- **Compression** — feature-gated streaming gzip/brotli/zstd/deflate with zip-bomb limits ([compression](docs/concepts/compression.md))
|
|
46
|
+
- **Native Rust JSON (opt-in)** — replayable `RequestBuilder::json()`, single-consumption `Response::json()` via the `json` feature ([guide](docs/rust/guide.md))
|
|
47
|
+
- **Python API** — requests/HTTPX-compatible sync and async interfaces ([guide](docs/python/guide.md)), plus versioned `eggfetch.compat.httpx` (0.28.1) and `eggfetch.compat.httpx2` (2.12.0) facades ([compatibility](#httpx-compatibility))
|
|
48
|
+
- **Upgrades** — 101 responses expose an owned `network_stream` (WebSocket/SSE building blocks); CONNECT tunnels stay body-iterator only
|
|
49
|
+
- **CLI** — streaming output, machine-readable formats, shell completions ([guide](docs/cli/guide.md))
|
|
50
|
+
- **C ABI and Node.js prototype** — opaque-handle FFI plus an experimental N-API wrapper ([ffi-and-node](docs/architecture/ffi-and-node.md))
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
**Python:**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install eggfetch
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Rust:**
|
|
61
|
+
|
|
62
|
+
```toml
|
|
63
|
+
[dependencies]
|
|
64
|
+
eggfetch-core = { version = "0.1", features = ["http1", "tls-rustls", "tls-native-roots"] }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
See the [feature profile matrix](docs/architecture/feature-flags.md#supported-core-profiles) for minimal, deterministic, and embedded recipes.
|
|
68
|
+
|
|
69
|
+
**CLI:**
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cargo install eggfetch-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage -- Python
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import eggfetch
|
|
79
|
+
|
|
80
|
+
r = eggfetch.get("https://httpbin.org/get")
|
|
81
|
+
print(r.status_code)
|
|
82
|
+
print(r.text)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import eggfetch
|
|
87
|
+
|
|
88
|
+
with eggfetch.Client(headers={"User-Agent": "my-app/1.0"}) as client:
|
|
89
|
+
r = client.get("https://httpbin.org/get")
|
|
90
|
+
print(r.json())
|
|
91
|
+
|
|
92
|
+
r = client.post("https://httpbin.org/post", json={"key": "value"})
|
|
93
|
+
print(r.status_code)
|
|
94
|
+
|
|
95
|
+
with client.stream("GET", "https://httpbin.org/stream-bytes/10000") as r:
|
|
96
|
+
for chunk in r.iter_bytes():
|
|
97
|
+
print(f"chunk: {len(chunk)} bytes")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import asyncio
|
|
102
|
+
import eggfetch
|
|
103
|
+
|
|
104
|
+
async def main():
|
|
105
|
+
async with eggfetch.AsyncClient() as client:
|
|
106
|
+
r = await client.get("https://httpbin.org/get")
|
|
107
|
+
print(r.status_code)
|
|
108
|
+
|
|
109
|
+
responses = await asyncio.gather(
|
|
110
|
+
client.get("https://httpbin.org/get"),
|
|
111
|
+
client.get("https://httpbin.org/ip"),
|
|
112
|
+
)
|
|
113
|
+
for resp in responses:
|
|
114
|
+
print(resp.json())
|
|
115
|
+
|
|
116
|
+
asyncio.run(main())
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import eggfetch
|
|
121
|
+
|
|
122
|
+
client = eggfetch.Client(
|
|
123
|
+
timeout=10.0,
|
|
124
|
+
headers={"User-Agent": "my-app/1.0"},
|
|
125
|
+
limits=eggfetch.Limits(max_connections=100),
|
|
126
|
+
verify="/path/to/ca-bundle.pem", # custom CA bundle
|
|
127
|
+
cert=("/path/to/cert.pem", "/path/to/key.pem"), # mTLS
|
|
128
|
+
proxy="http://proxy:8080",
|
|
129
|
+
http2=True,
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Versioned HTTPX-compatible facades over the same engine:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from eggfetch.compat.httpx import Client # HTTPX 0.28.1 surface
|
|
137
|
+
from eggfetch.compat.httpx2 import Client as H2Client # httpx2 2.12.0 surface
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
See [`docs/python/guide.md`](docs/python/guide.md) for the full Python API reference.
|
|
141
|
+
|
|
142
|
+
## Usage -- Rust
|
|
143
|
+
|
|
144
|
+
```rust
|
|
145
|
+
use eggfetch_core::Client;
|
|
146
|
+
use futures_util::StreamExt;
|
|
147
|
+
|
|
148
|
+
#[tokio::main]
|
|
149
|
+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
150
|
+
let client = Client::builder()
|
|
151
|
+
.timeout(eggfetch_core::Timeout::from_secs(30))
|
|
152
|
+
.follow_redirects(true)
|
|
153
|
+
.user_agent("my-app/1.0")
|
|
154
|
+
.build();
|
|
155
|
+
|
|
156
|
+
let mut resp = client.get("https://httpbin.org/get").send().await?;
|
|
157
|
+
println!("Status: {}", resp.status());
|
|
158
|
+
println!("Body: {}", resp.text().await?);
|
|
159
|
+
|
|
160
|
+
// Streaming body
|
|
161
|
+
let mut resp = client.get("https://httpbin.org/stream/3").send().await?;
|
|
162
|
+
let mut stream = resp.bytes_stream()?;
|
|
163
|
+
while let Some(chunk) = stream.next().await {
|
|
164
|
+
println!("chunk: {} bytes", chunk?.len());
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Ok(())
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The opt-in `json` feature adds `RequestBuilder::json()` / `Response::json()` Serde helpers, and `resolved_addresses()` pins caller-validated destinations without a second DNS lookup. See [`docs/rust/guide.md`](docs/rust/guide.md) for the full Rust API reference.
|
|
172
|
+
|
|
173
|
+
## Usage -- CLI
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# GET request
|
|
177
|
+
eggfetch https://httpbin.org/get
|
|
178
|
+
|
|
179
|
+
# POST JSON
|
|
180
|
+
eggfetch -X POST https://httpbin.org/post --json '{"key": "value"}'
|
|
181
|
+
|
|
182
|
+
# With authentication
|
|
183
|
+
eggfetch --auth user:pass https://httpbin.org/basic-auth/user/pass
|
|
184
|
+
|
|
185
|
+
# Streaming download
|
|
186
|
+
eggfetch --output file.bin https://httpbin.org/stream-bytes/10000
|
|
187
|
+
|
|
188
|
+
# Machine-readable output
|
|
189
|
+
eggfetch --json-output https://httpbin.org/get
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
See [`docs/cli/guide.md`](docs/cli/guide.md) for the full CLI reference.
|
|
193
|
+
|
|
194
|
+
## Examples
|
|
195
|
+
|
|
196
|
+
Runnable starting points (each takes an optional base URL argument, default `https://httpbin.org`):
|
|
197
|
+
|
|
198
|
+
- [`crates/eggfetch-core/examples/quickstart.rs`](crates/eggfetch-core/examples/quickstart.rs) — core client: configured GET/POST, timeout override, auth, streaming (`cargo run -p eggfetch-core --example quickstart`)
|
|
199
|
+
- [`examples/python_sync.py`](examples/python_sync.py) — sync client, JSON POST, streaming download
|
|
200
|
+
- [`examples/python_async.py`](examples/python_async.py) — async client with concurrent requests
|
|
201
|
+
|
|
202
|
+
More patterns are in [`docs/cookbook/`](docs/cookbook/).
|
|
203
|
+
|
|
204
|
+
## HTTPX Compatibility
|
|
205
|
+
|
|
206
|
+
Two versioned, independent facades over the single Rust engine — `eggfetch.compat.httpx` (0.28.1) and `eggfetch.compat.httpx2` (2.12.0, adds `FunctionAuth`, `Origin`/`URL.origin`, `QUERY`, SSE, optional WebSocket). Both are Stage C qualified on frozen executable SHA `22a6f5c0dc0207c1356b6143c0eda3d4075063b0`; HTTPX 1.0 preview under `compat/httpx/1.0-preview/` is reconnaissance only.
|
|
207
|
+
|
|
208
|
+
See [`docs/reference/compatibility.md`](docs/reference/compatibility.md) for the full feature matrix and retained differences.
|
|
209
|
+
|
|
210
|
+
## Documentation
|
|
211
|
+
|
|
212
|
+
| Section | Description |
|
|
213
|
+
|---------|-------------|
|
|
214
|
+
| [getting-started/](docs/getting-started/) | Installation and quickstart guide |
|
|
215
|
+
| [concepts/](docs/concepts/) | Architecture, lifecycle, timeouts, streaming, cookies, auth, proxy, TLS |
|
|
216
|
+
| [rust/guide.md](docs/rust/guide.md) | Rust API guide with examples |
|
|
217
|
+
| [python/guide.md](docs/python/guide.md) | Python sync/async API guide |
|
|
218
|
+
| [cli/guide.md](docs/cli/guide.md) | CLI reference and usage guide |
|
|
219
|
+
| [migration/](docs/migration/) | Migration guides from requests and HTTPX |
|
|
220
|
+
| [cookbook/](docs/cookbook/) | Practical runnable examples |
|
|
221
|
+
| [reference/](docs/reference/) | Compatibility matrix, feature matrix, error reference |
|
|
222
|
+
| [security/](docs/security/) | Security guidelines and troubleshooting |
|
|
223
|
+
| [architecture/](docs/architecture/) | Internal architecture documentation |
|
|
224
|
+
| [ffi/](docs/ffi/) | C ABI and FFI binding guide |
|
|
225
|
+
|
|
226
|
+
## Security
|
|
227
|
+
|
|
228
|
+
- **Dependency auditing:** `cargo-deny` configured in `deny.toml`
|
|
229
|
+
- **Secret redaction:** all `Debug`/`Display`/error output redacts credentials, cookies, bearer tokens, and proxy passwords
|
|
230
|
+
- **Threat model:** see [docs/architecture/threat-model.md](docs/architecture/threat-model.md)
|
|
231
|
+
- **Vulnerability reporting:** see [SECURITY.md](SECURITY.md)
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
eggfetch is licensed under the [MIT License](LICENSE-MIT).
|
|
236
|
+
|
|
237
|
+
## MSRV
|
|
238
|
+
|
|
239
|
+
The minimum supported Rust version is **1.80**, declared in `workspace.package.rust-version` and checked in extended validation. `rust-toolchain.toml` pins the stable channel for development.
|
|
240
|
+
|
eggfetch-0.1.4/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# eggfetch
|
|
2
|
+
|
|
3
|
+
[](https://github.com/eggstack/eggfetch/actions/workflows/ci.yml)
|
|
4
|
+
[](https://crates.io/crates/eggfetch-core)
|
|
5
|
+
[](https://crates.io/crates/eggfetch-core)
|
|
6
|
+
[](https://pypi.org/project/eggfetch/)
|
|
7
|
+
[](https://pepy.tech/projects/eggfetch)
|
|
8
|
+
[](LICENSE-MIT)
|
|
9
|
+
|
|
10
|
+
eggfetch is a Rust-native async HTTP client engine (tokio + hyper) with Python bindings and a CLI. There is exactly one networking implementation, living entirely in `eggfetch-core`; the Python sync API blocks on the async engine while releasing the GIL, and the async API integrates with asyncio.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **HTTP/1.1, HTTP/2, HTTP/3** — ALPN negotiation; HTTP/3 over QUIC stays experimental ([graduation gate](docs/architecture/core-tls-proxy-protocols.md))
|
|
15
|
+
- **Streaming** — request/response bodies without eager buffering (`bytes_stream()`, `text_lines()`); trailers via `Response::trailers()` ([guide](docs/rust/guide.md))
|
|
16
|
+
- **Pooling, timeouts, observability** — per-origin in-flight limits, phase-aware timeouts (pool/connect/write/read/total), connector/DNS/TLS and H3 transport metrics ([pool/timeouts](docs/architecture/core-timeout-pool.md))
|
|
17
|
+
- **TLS** — rustls with custom CA bundles, mTLS client certs, version policy, verification toggle ([TLS](docs/concepts/tls.md))
|
|
18
|
+
- **Proxy** — HTTP forwarding, HTTPS CONNECT, proxy auth, per-request override, `NO_PROXY`; SOCKS5 and UDS routes ([proxy](docs/concepts/proxy.md))
|
|
19
|
+
- **Cookies, auth, multipart** — RFC 6265 jar, Basic/Bearer with redaction, streaming multipart uploads ([cookies](docs/concepts/cookies.md))
|
|
20
|
+
- **Retries and redirects** — policy-driven backoff with `Retry-After`, replayable-body redirect handling ([retry](docs/concepts/retry.md))
|
|
21
|
+
- **Compression** — feature-gated streaming gzip/brotli/zstd/deflate with zip-bomb limits ([compression](docs/concepts/compression.md))
|
|
22
|
+
- **Native Rust JSON (opt-in)** — replayable `RequestBuilder::json()`, single-consumption `Response::json()` via the `json` feature ([guide](docs/rust/guide.md))
|
|
23
|
+
- **Python API** — requests/HTTPX-compatible sync and async interfaces ([guide](docs/python/guide.md)), plus versioned `eggfetch.compat.httpx` (0.28.1) and `eggfetch.compat.httpx2` (2.12.0) facades ([compatibility](#httpx-compatibility))
|
|
24
|
+
- **Upgrades** — 101 responses expose an owned `network_stream` (WebSocket/SSE building blocks); CONNECT tunnels stay body-iterator only
|
|
25
|
+
- **CLI** — streaming output, machine-readable formats, shell completions ([guide](docs/cli/guide.md))
|
|
26
|
+
- **C ABI and Node.js prototype** — opaque-handle FFI plus an experimental N-API wrapper ([ffi-and-node](docs/architecture/ffi-and-node.md))
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
**Python:**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install eggfetch
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Rust:**
|
|
37
|
+
|
|
38
|
+
```toml
|
|
39
|
+
[dependencies]
|
|
40
|
+
eggfetch-core = { version = "0.1", features = ["http1", "tls-rustls", "tls-native-roots"] }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
See the [feature profile matrix](docs/architecture/feature-flags.md#supported-core-profiles) for minimal, deterministic, and embedded recipes.
|
|
44
|
+
|
|
45
|
+
**CLI:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cargo install eggfetch-cli
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage -- Python
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import eggfetch
|
|
55
|
+
|
|
56
|
+
r = eggfetch.get("https://httpbin.org/get")
|
|
57
|
+
print(r.status_code)
|
|
58
|
+
print(r.text)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import eggfetch
|
|
63
|
+
|
|
64
|
+
with eggfetch.Client(headers={"User-Agent": "my-app/1.0"}) as client:
|
|
65
|
+
r = client.get("https://httpbin.org/get")
|
|
66
|
+
print(r.json())
|
|
67
|
+
|
|
68
|
+
r = client.post("https://httpbin.org/post", json={"key": "value"})
|
|
69
|
+
print(r.status_code)
|
|
70
|
+
|
|
71
|
+
with client.stream("GET", "https://httpbin.org/stream-bytes/10000") as r:
|
|
72
|
+
for chunk in r.iter_bytes():
|
|
73
|
+
print(f"chunk: {len(chunk)} bytes")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import asyncio
|
|
78
|
+
import eggfetch
|
|
79
|
+
|
|
80
|
+
async def main():
|
|
81
|
+
async with eggfetch.AsyncClient() as client:
|
|
82
|
+
r = await client.get("https://httpbin.org/get")
|
|
83
|
+
print(r.status_code)
|
|
84
|
+
|
|
85
|
+
responses = await asyncio.gather(
|
|
86
|
+
client.get("https://httpbin.org/get"),
|
|
87
|
+
client.get("https://httpbin.org/ip"),
|
|
88
|
+
)
|
|
89
|
+
for resp in responses:
|
|
90
|
+
print(resp.json())
|
|
91
|
+
|
|
92
|
+
asyncio.run(main())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import eggfetch
|
|
97
|
+
|
|
98
|
+
client = eggfetch.Client(
|
|
99
|
+
timeout=10.0,
|
|
100
|
+
headers={"User-Agent": "my-app/1.0"},
|
|
101
|
+
limits=eggfetch.Limits(max_connections=100),
|
|
102
|
+
verify="/path/to/ca-bundle.pem", # custom CA bundle
|
|
103
|
+
cert=("/path/to/cert.pem", "/path/to/key.pem"), # mTLS
|
|
104
|
+
proxy="http://proxy:8080",
|
|
105
|
+
http2=True,
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Versioned HTTPX-compatible facades over the same engine:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from eggfetch.compat.httpx import Client # HTTPX 0.28.1 surface
|
|
113
|
+
from eggfetch.compat.httpx2 import Client as H2Client # httpx2 2.12.0 surface
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
See [`docs/python/guide.md`](docs/python/guide.md) for the full Python API reference.
|
|
117
|
+
|
|
118
|
+
## Usage -- Rust
|
|
119
|
+
|
|
120
|
+
```rust
|
|
121
|
+
use eggfetch_core::Client;
|
|
122
|
+
use futures_util::StreamExt;
|
|
123
|
+
|
|
124
|
+
#[tokio::main]
|
|
125
|
+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
126
|
+
let client = Client::builder()
|
|
127
|
+
.timeout(eggfetch_core::Timeout::from_secs(30))
|
|
128
|
+
.follow_redirects(true)
|
|
129
|
+
.user_agent("my-app/1.0")
|
|
130
|
+
.build();
|
|
131
|
+
|
|
132
|
+
let mut resp = client.get("https://httpbin.org/get").send().await?;
|
|
133
|
+
println!("Status: {}", resp.status());
|
|
134
|
+
println!("Body: {}", resp.text().await?);
|
|
135
|
+
|
|
136
|
+
// Streaming body
|
|
137
|
+
let mut resp = client.get("https://httpbin.org/stream/3").send().await?;
|
|
138
|
+
let mut stream = resp.bytes_stream()?;
|
|
139
|
+
while let Some(chunk) = stream.next().await {
|
|
140
|
+
println!("chunk: {} bytes", chunk?.len());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Ok(())
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The opt-in `json` feature adds `RequestBuilder::json()` / `Response::json()` Serde helpers, and `resolved_addresses()` pins caller-validated destinations without a second DNS lookup. See [`docs/rust/guide.md`](docs/rust/guide.md) for the full Rust API reference.
|
|
148
|
+
|
|
149
|
+
## Usage -- CLI
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# GET request
|
|
153
|
+
eggfetch https://httpbin.org/get
|
|
154
|
+
|
|
155
|
+
# POST JSON
|
|
156
|
+
eggfetch -X POST https://httpbin.org/post --json '{"key": "value"}'
|
|
157
|
+
|
|
158
|
+
# With authentication
|
|
159
|
+
eggfetch --auth user:pass https://httpbin.org/basic-auth/user/pass
|
|
160
|
+
|
|
161
|
+
# Streaming download
|
|
162
|
+
eggfetch --output file.bin https://httpbin.org/stream-bytes/10000
|
|
163
|
+
|
|
164
|
+
# Machine-readable output
|
|
165
|
+
eggfetch --json-output https://httpbin.org/get
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
See [`docs/cli/guide.md`](docs/cli/guide.md) for the full CLI reference.
|
|
169
|
+
|
|
170
|
+
## Examples
|
|
171
|
+
|
|
172
|
+
Runnable starting points (each takes an optional base URL argument, default `https://httpbin.org`):
|
|
173
|
+
|
|
174
|
+
- [`crates/eggfetch-core/examples/quickstart.rs`](crates/eggfetch-core/examples/quickstart.rs) — core client: configured GET/POST, timeout override, auth, streaming (`cargo run -p eggfetch-core --example quickstart`)
|
|
175
|
+
- [`examples/python_sync.py`](examples/python_sync.py) — sync client, JSON POST, streaming download
|
|
176
|
+
- [`examples/python_async.py`](examples/python_async.py) — async client with concurrent requests
|
|
177
|
+
|
|
178
|
+
More patterns are in [`docs/cookbook/`](docs/cookbook/).
|
|
179
|
+
|
|
180
|
+
## HTTPX Compatibility
|
|
181
|
+
|
|
182
|
+
Two versioned, independent facades over the single Rust engine — `eggfetch.compat.httpx` (0.28.1) and `eggfetch.compat.httpx2` (2.12.0, adds `FunctionAuth`, `Origin`/`URL.origin`, `QUERY`, SSE, optional WebSocket). Both are Stage C qualified on frozen executable SHA `22a6f5c0dc0207c1356b6143c0eda3d4075063b0`; HTTPX 1.0 preview under `compat/httpx/1.0-preview/` is reconnaissance only.
|
|
183
|
+
|
|
184
|
+
See [`docs/reference/compatibility.md`](docs/reference/compatibility.md) for the full feature matrix and retained differences.
|
|
185
|
+
|
|
186
|
+
## Documentation
|
|
187
|
+
|
|
188
|
+
| Section | Description |
|
|
189
|
+
|---------|-------------|
|
|
190
|
+
| [getting-started/](docs/getting-started/) | Installation and quickstart guide |
|
|
191
|
+
| [concepts/](docs/concepts/) | Architecture, lifecycle, timeouts, streaming, cookies, auth, proxy, TLS |
|
|
192
|
+
| [rust/guide.md](docs/rust/guide.md) | Rust API guide with examples |
|
|
193
|
+
| [python/guide.md](docs/python/guide.md) | Python sync/async API guide |
|
|
194
|
+
| [cli/guide.md](docs/cli/guide.md) | CLI reference and usage guide |
|
|
195
|
+
| [migration/](docs/migration/) | Migration guides from requests and HTTPX |
|
|
196
|
+
| [cookbook/](docs/cookbook/) | Practical runnable examples |
|
|
197
|
+
| [reference/](docs/reference/) | Compatibility matrix, feature matrix, error reference |
|
|
198
|
+
| [security/](docs/security/) | Security guidelines and troubleshooting |
|
|
199
|
+
| [architecture/](docs/architecture/) | Internal architecture documentation |
|
|
200
|
+
| [ffi/](docs/ffi/) | C ABI and FFI binding guide |
|
|
201
|
+
|
|
202
|
+
## Security
|
|
203
|
+
|
|
204
|
+
- **Dependency auditing:** `cargo-deny` configured in `deny.toml`
|
|
205
|
+
- **Secret redaction:** all `Debug`/`Display`/error output redacts credentials, cookies, bearer tokens, and proxy passwords
|
|
206
|
+
- **Threat model:** see [docs/architecture/threat-model.md](docs/architecture/threat-model.md)
|
|
207
|
+
- **Vulnerability reporting:** see [SECURITY.md](SECURITY.md)
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
eggfetch is licensed under the [MIT License](LICENSE-MIT).
|
|
212
|
+
|
|
213
|
+
## MSRV
|
|
214
|
+
|
|
215
|
+
The minimum supported Rust version is **1.80**, declared in `workspace.package.rust-version` and checked in extended validation. `rust-toolchain.toml` pins the stable channel for development.
|