@lovrozagar/honey 0.6.5 → 0.7.0
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.
- package/README.md +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +410 -149
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +776 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1893 -1761
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +271 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +562 -424
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import inspect
|
|
5
|
+
import re
|
|
4
6
|
import threading
|
|
5
7
|
import time
|
|
8
|
+
import unicodedata
|
|
6
9
|
import uuid
|
|
10
|
+
from contextlib import asynccontextmanager
|
|
7
11
|
from dataclasses import dataclass, field
|
|
8
|
-
from
|
|
12
|
+
from decimal import Decimal
|
|
13
|
+
from typing import Any, AsyncIterator, Awaitable, Callable, Generic, TypeVar
|
|
14
|
+
from urllib.parse import quote, urlsplit, urlunsplit
|
|
9
15
|
|
|
10
16
|
import httpx
|
|
11
17
|
|
|
@@ -15,6 +21,7 @@ from ._invalidation import _RequestMeta
|
|
|
15
21
|
T = TypeVar("T")
|
|
16
22
|
|
|
17
23
|
DEFAULT_TIMEOUT = 30.0
|
|
24
|
+
MAX_ERROR_MESSAGE = 512
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
@dataclass
|
|
@@ -59,12 +66,22 @@ class InvalidationConfig:
|
|
|
59
66
|
|
|
60
67
|
@dataclass(frozen=True)
|
|
61
68
|
class ClientConfig:
|
|
69
|
+
"""SDK configuration.
|
|
70
|
+
|
|
71
|
+
``timeout`` (seconds) bounds a whole regular request; ``None`` disables it.
|
|
72
|
+
Streams (SSE, WebSocket, realtime) are not bounded by it.
|
|
73
|
+
|
|
74
|
+
``on_auth_expired`` may be a coroutine function or a plain function; it
|
|
75
|
+
returns the new token (or ``None`` to give up). The SDK keeps the refreshed
|
|
76
|
+
token for later calls and refreshes once for concurrent 401s.
|
|
77
|
+
"""
|
|
78
|
+
|
|
62
79
|
base_url: str
|
|
63
80
|
bearer_token: str | None = None
|
|
64
81
|
headers: dict[str, str] = field(default_factory=dict)
|
|
65
82
|
timeout: float | None = DEFAULT_TIMEOUT
|
|
66
83
|
throw_on_error: bool = True
|
|
67
|
-
on_auth_expired: Callable[[], Awaitable[str | None]] | None = None
|
|
84
|
+
on_auth_expired: Callable[[], Awaitable[str | None] | str | None] | None = None
|
|
68
85
|
auth_header_name: str | None = None
|
|
69
86
|
auth_header_prefix: str | None = None
|
|
70
87
|
transport: httpx.AsyncBaseTransport | None = None
|
|
@@ -83,7 +100,7 @@ def _emit_log(config: ClientConfig, entry: LogEntry) -> None:
|
|
|
83
100
|
try:
|
|
84
101
|
config.on_log(entry)
|
|
85
102
|
except Exception:
|
|
86
|
-
|
|
103
|
+
# logger must never break the request path
|
|
87
104
|
pass
|
|
88
105
|
|
|
89
106
|
|
|
@@ -104,6 +121,75 @@ class SDKResult(Generic[T]):
|
|
|
104
121
|
response: httpx.Response
|
|
105
122
|
|
|
106
123
|
|
|
124
|
+
class _AuthState:
|
|
125
|
+
"""Current bearer token plus a refresh guard, shared by one SDK instance."""
|
|
126
|
+
|
|
127
|
+
def __init__(self, token: str | None) -> None:
|
|
128
|
+
self.token = token
|
|
129
|
+
self._async_lock: asyncio.Lock | None = None
|
|
130
|
+
self._thread_lock = threading.Lock()
|
|
131
|
+
|
|
132
|
+
async def refresh(self, config: ClientConfig, rejected: str | None) -> str | None:
|
|
133
|
+
if self._async_lock is None:
|
|
134
|
+
self._async_lock = asyncio.Lock()
|
|
135
|
+
async with self._async_lock:
|
|
136
|
+
if self.token != rejected:
|
|
137
|
+
return self.token
|
|
138
|
+
token = await _call_auth_hook(config)
|
|
139
|
+
if token is not None:
|
|
140
|
+
self.token = token
|
|
141
|
+
return token
|
|
142
|
+
|
|
143
|
+
def refresh_sync(self, config: ClientConfig, rejected: str | None) -> str | None:
|
|
144
|
+
with self._thread_lock:
|
|
145
|
+
if self.token != rejected:
|
|
146
|
+
return self.token
|
|
147
|
+
token = _call_auth_hook_sync(config)
|
|
148
|
+
if token is not None:
|
|
149
|
+
self.token = token
|
|
150
|
+
return token
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
async def _call_auth_hook(config: ClientConfig) -> str | None:
|
|
154
|
+
assert config.on_auth_expired is not None
|
|
155
|
+
result = config.on_auth_expired()
|
|
156
|
+
if inspect.isawaitable(result):
|
|
157
|
+
return await result
|
|
158
|
+
return result
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _call_auth_hook_sync(config: ClientConfig) -> str | None:
|
|
162
|
+
assert config.on_auth_expired is not None
|
|
163
|
+
result = config.on_auth_expired()
|
|
164
|
+
if not inspect.isawaitable(result):
|
|
165
|
+
return result
|
|
166
|
+
try:
|
|
167
|
+
asyncio.get_running_loop()
|
|
168
|
+
except RuntimeError:
|
|
169
|
+
return asyncio.run(_await(result))
|
|
170
|
+
# called from inside a running loop (sync SDK used in async code): run the
|
|
171
|
+
# coroutine on its own loop in a worker thread instead of failing silently
|
|
172
|
+
out: list[Any] = []
|
|
173
|
+
errors: list[BaseException] = []
|
|
174
|
+
|
|
175
|
+
def _worker() -> None:
|
|
176
|
+
try:
|
|
177
|
+
out.append(asyncio.run(_await(result)))
|
|
178
|
+
except BaseException as exc: # re-raised in the caller's thread
|
|
179
|
+
errors.append(exc)
|
|
180
|
+
|
|
181
|
+
thread = threading.Thread(target=_worker)
|
|
182
|
+
thread.start()
|
|
183
|
+
thread.join()
|
|
184
|
+
if errors:
|
|
185
|
+
raise errors[0]
|
|
186
|
+
return out[0]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def _await(value: Awaitable[T]) -> T:
|
|
190
|
+
return await value
|
|
191
|
+
|
|
192
|
+
|
|
107
193
|
def _auth_header_name(config: ClientConfig) -> str:
|
|
108
194
|
return config.auth_header_name or "Authorization"
|
|
109
195
|
|
|
@@ -113,12 +199,24 @@ def _has_header(headers: dict[str, str], name: str) -> bool:
|
|
|
113
199
|
return any(k.lower() == target for k in headers)
|
|
114
200
|
|
|
115
201
|
|
|
202
|
+
def _set_header(headers: dict[str, str], name: str, value: str) -> None:
|
|
203
|
+
"""Set *name* replacing any existing casing of it."""
|
|
204
|
+
target = name.lower()
|
|
205
|
+
for key in [k for k in headers if k.lower() == target]:
|
|
206
|
+
del headers[key]
|
|
207
|
+
headers[name] = value
|
|
208
|
+
|
|
209
|
+
|
|
116
210
|
def _build_headers(
|
|
117
211
|
config: ClientConfig,
|
|
118
212
|
extra: dict[str, str] | None = None,
|
|
119
213
|
bearer_token: str | None = None,
|
|
120
214
|
) -> dict[str, str]:
|
|
121
|
-
|
|
215
|
+
"""Config headers, then the auth header, then per-call headers. Merging is
|
|
216
|
+
case-insensitive and later wins, so exactly one of each header is sent."""
|
|
217
|
+
merged: dict[str, str] = {}
|
|
218
|
+
for key, value in config.headers.items():
|
|
219
|
+
_set_header(merged, key, value)
|
|
122
220
|
token = bearer_token if bearer_token is not None else config.bearer_token
|
|
123
221
|
if token:
|
|
124
222
|
prefix = (
|
|
@@ -126,42 +224,273 @@ def _build_headers(
|
|
|
126
224
|
if config.auth_header_prefix is not None
|
|
127
225
|
else "Bearer "
|
|
128
226
|
)
|
|
129
|
-
merged
|
|
130
|
-
|
|
131
|
-
|
|
227
|
+
_set_header(merged, _auth_header_name(config), f"{prefix}{token}")
|
|
228
|
+
for key, value in (extra or {}).items():
|
|
229
|
+
if value is None:
|
|
230
|
+
continue
|
|
231
|
+
_set_header(merged, key, str(value))
|
|
132
232
|
# auto correlation id — config/extra win; on_request hooks may overwrite
|
|
133
233
|
if not _has_header(merged, "x-request-id"):
|
|
134
234
|
merged["x-request-id"] = str(uuid.uuid4())
|
|
135
235
|
return merged
|
|
136
236
|
|
|
137
237
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
238
|
+
class PathParamError(ValueError):
|
|
239
|
+
"""A path parameter that is missing, or that a URL parser would collapse
|
|
240
|
+
("", "." or "..")."""
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _escape_segment(value: str) -> str:
|
|
244
|
+
# encodeURIComponent's safe set: every SDK language and the TS client send
|
|
245
|
+
# the same bytes
|
|
246
|
+
return quote(value, safe="!~*'()")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _escape_query(value: str) -> str:
|
|
250
|
+
# URLSearchParams encoding: space becomes "+"
|
|
251
|
+
return quote(value, safe="*").replace("%20", "+").replace("~", "%7E")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _encode_segment_value(name: str, value: str) -> str:
|
|
255
|
+
if value in ("", ".", ".."):
|
|
256
|
+
raise PathParamError(
|
|
257
|
+
f"Invalid path param {name!r}: {value!r} is not a path segment"
|
|
143
258
|
)
|
|
144
|
-
|
|
145
|
-
|
|
259
|
+
return _escape_segment(value)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _expand_path(template: str, params: dict[str, Any]) -> str:
|
|
263
|
+
"""Fill a path template with the TS client's grammar: ``:name`` / ``:name?``
|
|
264
|
+
take a whole segment, a final ``*name`` takes the rest, ``{name}`` may sit
|
|
265
|
+
inside a segment. Values are encoded; "", "." and ".." are rejected."""
|
|
266
|
+
segments = template.split("/")
|
|
267
|
+
out: list[str] = []
|
|
268
|
+
for i, seg in enumerate(segments):
|
|
269
|
+
if len(seg) > 1 and seg[0] == ":":
|
|
270
|
+
optional = seg.endswith("?")
|
|
271
|
+
name = seg[1:-1] if optional else seg[1:]
|
|
272
|
+
if params.get(name) is None:
|
|
273
|
+
if optional:
|
|
274
|
+
continue
|
|
275
|
+
raise PathParamError(f"Missing path param: {name}")
|
|
276
|
+
out.append(_encode_segment_value(name, _format_value(params[name])))
|
|
277
|
+
elif seg[:1] == "*" and i == len(segments) - 1:
|
|
278
|
+
name = seg[1:] or "*"
|
|
279
|
+
if params.get(name) is None:
|
|
280
|
+
if seg == "*":
|
|
281
|
+
out.append("")
|
|
282
|
+
continue
|
|
283
|
+
raise PathParamError(f"Missing path param: {name}")
|
|
284
|
+
value = _format_value(params[name])
|
|
285
|
+
out.append(
|
|
286
|
+
""
|
|
287
|
+
if value == ""
|
|
288
|
+
else "/".join(_encode_segment_value(name, p) for p in value.split("/"))
|
|
289
|
+
)
|
|
290
|
+
else:
|
|
291
|
+
|
|
292
|
+
def _sub(match: re.Match[str]) -> str:
|
|
293
|
+
name = match.group(1)
|
|
294
|
+
if params.get(name) is None:
|
|
295
|
+
raise PathParamError(f"Missing path param: {name}")
|
|
296
|
+
return _encode_segment_value(name, _format_value(params[name]))
|
|
297
|
+
|
|
298
|
+
out.append(_BRACE_RE.sub(_sub, seg))
|
|
299
|
+
return "/".join(out)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
_BRACE_RE = re.compile(r"\{([^{}/]+)\}")
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def _format_float(value: float) -> str:
|
|
306
|
+
"""JavaScript Number#toString formatting, shared by every SDK language."""
|
|
307
|
+
if value != value:
|
|
308
|
+
return "NaN"
|
|
309
|
+
if value in (float("inf"), float("-inf")):
|
|
310
|
+
return "Infinity" if value > 0 else "-Infinity"
|
|
311
|
+
if value == 0:
|
|
312
|
+
return "0"
|
|
313
|
+
magnitude = abs(value)
|
|
314
|
+
if 1e-6 <= magnitude < 1e21:
|
|
315
|
+
text = format(Decimal(repr(value)), "f")
|
|
316
|
+
if "." in text:
|
|
317
|
+
text = text.rstrip("0").rstrip(".")
|
|
318
|
+
return text
|
|
319
|
+
mantissa, _, exponent = repr(value).partition("e")
|
|
320
|
+
if not exponent:
|
|
321
|
+
mantissa, _, exponent = f"{value:e}".partition("e")
|
|
322
|
+
mantissa = mantissa.rstrip("0").rstrip(".") if "." in mantissa else mantissa
|
|
323
|
+
exp = int(exponent)
|
|
324
|
+
return f"{mantissa}e{'+' if exp > 0 else '-'}{abs(exp)}"
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def _format_value(value: Any) -> str:
|
|
328
|
+
if isinstance(value, bool):
|
|
329
|
+
return "true" if value else "false"
|
|
330
|
+
if isinstance(value, int):
|
|
331
|
+
return str(value)
|
|
332
|
+
if isinstance(value, float):
|
|
333
|
+
return _format_float(value)
|
|
334
|
+
if isinstance(value, str):
|
|
335
|
+
return value
|
|
336
|
+
if hasattr(value, "value") and isinstance(getattr(value, "value"), (str, int)):
|
|
337
|
+
return _format_value(value.value)
|
|
338
|
+
import json as _json
|
|
339
|
+
|
|
340
|
+
return _json.dumps(value, separators=(",", ":"))
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _query_pairs(params: dict[str, Any] | None) -> list[tuple[str, str]]:
|
|
344
|
+
"""Flatten params in order: None skipped, lists and tuples repeat the key."""
|
|
345
|
+
pairs: list[tuple[str, str]] = []
|
|
346
|
+
for key, value in (params or {}).items():
|
|
347
|
+
if value is None:
|
|
348
|
+
continue
|
|
349
|
+
if isinstance(value, (list, tuple)):
|
|
350
|
+
pairs.extend((key, _format_value(v)) for v in value if v is not None)
|
|
351
|
+
else:
|
|
352
|
+
pairs.append((key, _format_value(value)))
|
|
353
|
+
return pairs
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _encode_query(pairs: list[tuple[str, str]]) -> str:
|
|
357
|
+
return "&".join(f"{_escape_query(k)}={_escape_query(v)}" for k, v in pairs)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _build_url(base_url: str, path: str, params: dict[str, Any] | None = None) -> str:
|
|
361
|
+
"""Join *base_url* and an escaped *path*, keeping the base path and query,
|
|
362
|
+
then append *params* (lists repeat the key)."""
|
|
363
|
+
parts = urlsplit(base_url)
|
|
364
|
+
if not parts.scheme or not parts.netloc:
|
|
365
|
+
raise ValueError(f"base_url {base_url!r} needs a scheme and host")
|
|
366
|
+
if not path.startswith("/"):
|
|
367
|
+
path = "/" + path
|
|
368
|
+
joined_path = parts.path.rstrip("/") + path
|
|
369
|
+
query = parts.query
|
|
370
|
+
extra = _encode_query(_query_pairs(params))
|
|
371
|
+
if extra:
|
|
372
|
+
query = f"{query}&{extra}" if query else extra
|
|
373
|
+
return urlunsplit((parts.scheme, parts.netloc, joined_path, query, ""))
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def _append_query(url: str, params: dict[str, Any] | None) -> str:
|
|
377
|
+
extra = _encode_query(_query_pairs(params))
|
|
378
|
+
if not extra:
|
|
379
|
+
return url
|
|
380
|
+
return f"{url}{'&' if '?' in url else '?'}{extra}"
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
# One multipart file: raw bytes, a binary file object, or a
|
|
384
|
+
# (filename, content[, content_type]) tuple.
|
|
385
|
+
FileInput = Any
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def _form_content(body: Any) -> bytes:
|
|
389
|
+
"""application/x-www-form-urlencoded bytes; lists repeat the key."""
|
|
390
|
+
return _encode_query(_query_pairs(dict(body or {}))).encode()
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def _multipart_parts(
|
|
394
|
+
body: Any,
|
|
395
|
+
files: list[str],
|
|
396
|
+
list_files: list[str],
|
|
397
|
+
) -> tuple[None, list[tuple[str, Any]]]:
|
|
398
|
+
"""Encode a multipart body as httpx ``files`` entries (``data`` is always ``None``).
|
|
399
|
+
|
|
400
|
+
httpx 0.28 cannot combine a list of ``data`` tuples with ``files`` (a text
|
|
401
|
+
field raises ``TypeError``, and an empty list sends an empty body), so text
|
|
402
|
+
fields go in as ``(None, value)`` parts: same wire format, and repeated keys
|
|
403
|
+
keep their order.
|
|
404
|
+
"""
|
|
405
|
+
out_files: list[tuple[str, Any]] = []
|
|
406
|
+
for key, value in dict(body or {}).items():
|
|
407
|
+
if value is None:
|
|
408
|
+
continue
|
|
409
|
+
if key in files:
|
|
410
|
+
out_files.append((key, value))
|
|
411
|
+
elif key in list_files:
|
|
412
|
+
out_files.extend((key, item) for item in value)
|
|
413
|
+
elif isinstance(value, (list, tuple)):
|
|
414
|
+
out_files.extend((key, (None, _format_value(v))) for v in value)
|
|
415
|
+
else:
|
|
416
|
+
out_files.append((key, (None, _format_value(value))))
|
|
417
|
+
return None, out_files
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _body_args(
|
|
421
|
+
content: Any,
|
|
422
|
+
data: Any,
|
|
423
|
+
files: Any,
|
|
424
|
+
headers: dict[str, str],
|
|
425
|
+
) -> tuple[Any, Any, Any, dict[str, str]]:
|
|
426
|
+
"""httpx sends ``files=[]`` as no body at all. A multipart operation called
|
|
427
|
+
with no fields still sends a multipart body: the empty one, a lone closing
|
|
428
|
+
boundary."""
|
|
429
|
+
if files is not None and len(files) == 0 and content is None and not data:
|
|
430
|
+
boundary = uuid.uuid4().hex
|
|
431
|
+
out = dict(headers)
|
|
432
|
+
_set_header(out, "Content-Type", f"multipart/form-data; boundary={boundary}")
|
|
433
|
+
return f"--{boundary}--\r\n".encode(), None, None, out
|
|
434
|
+
return content, data, files, headers
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def _to_ws_url(url: str) -> str:
|
|
438
|
+
"""Swap only the scheme; a URL inside the query string is untouched."""
|
|
439
|
+
if url.startswith("https://"):
|
|
440
|
+
return "wss://" + url[len("https://") :]
|
|
441
|
+
if url.startswith("http://"):
|
|
442
|
+
return "ws://" + url[len("http://") :]
|
|
146
443
|
return url
|
|
147
444
|
|
|
148
445
|
|
|
149
|
-
def
|
|
446
|
+
def _is_json_media(content_type: str) -> bool:
|
|
447
|
+
essence = content_type.split(";", 1)[0].strip().lower()
|
|
448
|
+
return essence == "application/json" or essence.endswith("+json")
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _parse_body(response: httpx.Response, kind: str = "json") -> Any:
|
|
452
|
+
"""Decode a response per the operation's declared success kind.
|
|
453
|
+
|
|
454
|
+
``binary`` returns bytes, ``text`` returns str, ``none`` returns None; JSON
|
|
455
|
+
(including ``+json`` media types) is decoded, anything else is returned as
|
|
456
|
+
text.
|
|
457
|
+
"""
|
|
458
|
+
if kind == "binary":
|
|
459
|
+
return response.content
|
|
460
|
+
if kind == "none":
|
|
461
|
+
return None
|
|
150
462
|
content_type = response.headers.get("content-type", "")
|
|
151
|
-
if "
|
|
463
|
+
if kind == "text":
|
|
464
|
+
return response.text
|
|
465
|
+
if _is_json_media(content_type):
|
|
466
|
+
if not response.content:
|
|
467
|
+
return None
|
|
152
468
|
try:
|
|
153
469
|
return response.json()
|
|
154
470
|
except Exception:
|
|
155
471
|
return None
|
|
472
|
+
if not response.content:
|
|
473
|
+
return None
|
|
156
474
|
return response.text
|
|
157
475
|
|
|
158
476
|
|
|
477
|
+
def _clean_message(text: str) -> str:
|
|
478
|
+
cleaned = "".join(
|
|
479
|
+
ch for ch in text if ch in " " or unicodedata.category(ch)[0] != "C"
|
|
480
|
+
)
|
|
481
|
+
if len(cleaned) > MAX_ERROR_MESSAGE:
|
|
482
|
+
cleaned = cleaned[:MAX_ERROR_MESSAGE] + "…"
|
|
483
|
+
return cleaned
|
|
484
|
+
|
|
485
|
+
|
|
159
486
|
def _raise_for_status(response: httpx.Response, body: Any = None) -> None:
|
|
160
|
-
|
|
487
|
+
"""Raise the typed error for any non-2xx status. A 3xx counts: the SDK does
|
|
488
|
+
not follow redirects, so a redirect is not a successful response."""
|
|
489
|
+
status = response.status_code
|
|
490
|
+
if 200 <= status < 300:
|
|
161
491
|
return
|
|
162
492
|
parsed = body if body is not None else _parse_body(response)
|
|
163
493
|
raw = response.content
|
|
164
|
-
status = response.status_code
|
|
165
494
|
msg_val = parsed.get("message") if isinstance(parsed, dict) else None
|
|
166
495
|
if isinstance(msg_val, str):
|
|
167
496
|
message = msg_val
|
|
@@ -177,7 +506,7 @@ def _raise_for_status(response: httpx.Response, body: Any = None) -> None:
|
|
|
177
506
|
body=raw,
|
|
178
507
|
data=parsed,
|
|
179
508
|
response=response,
|
|
180
|
-
message=message
|
|
509
|
+
message=_clean_message(message) or f"HTTP {status}",
|
|
181
510
|
)
|
|
182
511
|
|
|
183
512
|
|
|
@@ -190,7 +519,8 @@ def _apply_meta_to_request_ctx(ctx: RequestContext, meta: _RequestMeta | None) -
|
|
|
190
519
|
|
|
191
520
|
|
|
192
521
|
def _apply_meta_to_response_ctx(
|
|
193
|
-
ctx: ResponseContext,
|
|
522
|
+
ctx: ResponseContext,
|
|
523
|
+
meta: _RequestMeta | None,
|
|
194
524
|
) -> None:
|
|
195
525
|
if meta is None:
|
|
196
526
|
return
|
|
@@ -199,6 +529,15 @@ def _apply_meta_to_response_ctx(
|
|
|
199
529
|
ctx.invalidated_by = meta.invalidated_by
|
|
200
530
|
|
|
201
531
|
|
|
532
|
+
def _replayable(content: Any) -> bool:
|
|
533
|
+
"""A body can be sent again after an auth refresh unless it is a one-shot stream."""
|
|
534
|
+
return content is None or isinstance(content, (bytes, bytearray, str))
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def _timeout(value: float | None) -> httpx.Timeout:
|
|
538
|
+
return httpx.Timeout(value)
|
|
539
|
+
|
|
540
|
+
|
|
202
541
|
async def _do_request_async(
|
|
203
542
|
client: httpx.AsyncClient,
|
|
204
543
|
config: ClientConfig,
|
|
@@ -212,11 +551,15 @@ async def _do_request_async(
|
|
|
212
551
|
cancel_token: threading.Event | None = None,
|
|
213
552
|
operation: str = "",
|
|
214
553
|
request_meta: _RequestMeta | None = None,
|
|
554
|
+
data: Any = None,
|
|
555
|
+
files: Any = None,
|
|
556
|
+
auth: _AuthState | None = None,
|
|
215
557
|
) -> httpx.Response:
|
|
216
558
|
if cancel_token is not None and cancel_token.is_set():
|
|
217
559
|
raise asyncio.CancelledError()
|
|
218
560
|
timeout_val = timeout if timeout is not None else config.timeout
|
|
219
561
|
start = time.monotonic()
|
|
562
|
+
url = _append_query(url, params)
|
|
220
563
|
|
|
221
564
|
req_ctx = RequestContext(method=method, url=url, headers=dict(headers), body=json)
|
|
222
565
|
_apply_meta_to_request_ctx(req_ctx, request_meta)
|
|
@@ -227,51 +570,66 @@ async def _do_request_async(
|
|
|
227
570
|
_emit_log(
|
|
228
571
|
config,
|
|
229
572
|
LogEntry(
|
|
230
|
-
level="debug",
|
|
231
|
-
event="request_start",
|
|
232
|
-
operation=operation,
|
|
233
|
-
duration_ms=0,
|
|
573
|
+
level="debug", event="request_start", operation=operation, duration_ms=0
|
|
234
574
|
),
|
|
235
575
|
)
|
|
236
576
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
577
|
+
async def _send(ctx: RequestContext) -> httpx.Response:
|
|
578
|
+
b_content, b_data, b_files, b_headers = _body_args(
|
|
579
|
+
content, data, files, ctx.headers
|
|
580
|
+
)
|
|
581
|
+
return await client.request(
|
|
582
|
+
ctx.method,
|
|
583
|
+
ctx.url,
|
|
584
|
+
headers=b_headers,
|
|
585
|
+
json=ctx.body
|
|
586
|
+
if content is None and data is None and files is None
|
|
587
|
+
else None,
|
|
588
|
+
content=b_content,
|
|
589
|
+
data=b_data,
|
|
590
|
+
files=b_files,
|
|
591
|
+
timeout=_timeout(timeout_val),
|
|
246
592
|
)
|
|
247
593
|
|
|
594
|
+
async def _observe(response: httpx.Response, is_retry: bool) -> None:
|
|
248
595
|
if config.on_response:
|
|
249
596
|
raw = response.content
|
|
250
597
|
parsed = _parse_body(response)
|
|
251
|
-
resp_ctx = ResponseContext(
|
|
598
|
+
resp_ctx = ResponseContext(
|
|
599
|
+
response=response, body=raw, parsed=parsed, is_retry=is_retry
|
|
600
|
+
)
|
|
252
601
|
_apply_meta_to_response_ctx(resp_ctx, request_meta)
|
|
253
602
|
for hook in config.on_response:
|
|
254
603
|
await hook(resp_ctx)
|
|
255
604
|
|
|
256
|
-
|
|
257
|
-
|
|
605
|
+
try:
|
|
606
|
+
response = await _send(req_ctx)
|
|
607
|
+
await _observe(response, False)
|
|
608
|
+
|
|
609
|
+
if (
|
|
610
|
+
response.status_code == 401
|
|
611
|
+
and config.on_auth_expired is not None
|
|
612
|
+
and _replayable(content)
|
|
613
|
+
):
|
|
614
|
+
rejected = auth.token if auth is not None else config.bearer_token
|
|
615
|
+
new_token = (
|
|
616
|
+
await auth.refresh(config, rejected)
|
|
617
|
+
if auth is not None
|
|
618
|
+
else await _call_auth_hook(config)
|
|
619
|
+
)
|
|
258
620
|
if new_token is not None:
|
|
259
621
|
current_auth_name = _auth_header_name(config).lower()
|
|
260
622
|
extra_no_auth = {
|
|
261
|
-
k: v
|
|
623
|
+
k: v
|
|
624
|
+
for k, v in req_ctx.headers.items()
|
|
262
625
|
if k.lower() != current_auth_name
|
|
263
626
|
}
|
|
264
|
-
retry_headers = _build_headers(
|
|
265
|
-
config, extra=extra_no_auth or None, bearer_token=new_token,
|
|
266
|
-
)
|
|
267
|
-
retry_params = {
|
|
268
|
-
k: v for k, v in (params or {}).items() if v is not None
|
|
269
|
-
} or None
|
|
270
|
-
|
|
271
627
|
retry_ctx = RequestContext(
|
|
272
628
|
method=req_ctx.method,
|
|
273
629
|
url=req_ctx.url,
|
|
274
|
-
headers=
|
|
630
|
+
headers=_build_headers(
|
|
631
|
+
config, extra=extra_no_auth or None, bearer_token=new_token
|
|
632
|
+
),
|
|
275
633
|
body=req_ctx.body,
|
|
276
634
|
is_retry=True,
|
|
277
635
|
)
|
|
@@ -279,27 +637,8 @@ async def _do_request_async(
|
|
|
279
637
|
if config.on_request:
|
|
280
638
|
for hook in config.on_request:
|
|
281
639
|
await hook(retry_ctx)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
retry_ctx.method,
|
|
285
|
-
retry_ctx.url,
|
|
286
|
-
headers=retry_ctx.headers,
|
|
287
|
-
json=retry_ctx.body,
|
|
288
|
-
params=retry_params,
|
|
289
|
-
timeout=(
|
|
290
|
-
httpx.Timeout(timeout_val) if timeout_val is not None else None
|
|
291
|
-
),
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
if config.on_response:
|
|
295
|
-
raw = response.content
|
|
296
|
-
parsed = _parse_body(response)
|
|
297
|
-
resp_ctx = ResponseContext(
|
|
298
|
-
response=response, body=raw, parsed=parsed, is_retry=True,
|
|
299
|
-
)
|
|
300
|
-
_apply_meta_to_response_ctx(resp_ctx, request_meta)
|
|
301
|
-
for hook in config.on_response:
|
|
302
|
-
await hook(resp_ctx)
|
|
640
|
+
response = await _send(retry_ctx)
|
|
641
|
+
await _observe(response, True)
|
|
303
642
|
|
|
304
643
|
_emit_log(
|
|
305
644
|
config,
|
|
@@ -340,11 +679,15 @@ def _do_request_sync(
|
|
|
340
679
|
cancel_token: threading.Event | None = None,
|
|
341
680
|
operation: str = "",
|
|
342
681
|
request_meta: _RequestMeta | None = None,
|
|
682
|
+
data: Any = None,
|
|
683
|
+
files: Any = None,
|
|
684
|
+
auth: _AuthState | None = None,
|
|
343
685
|
) -> httpx.Response:
|
|
344
686
|
if cancel_token is not None and cancel_token.is_set():
|
|
345
687
|
raise asyncio.CancelledError()
|
|
346
688
|
timeout_val = timeout if timeout is not None else config.timeout
|
|
347
689
|
start = time.monotonic()
|
|
690
|
+
url = _append_query(url, params)
|
|
348
691
|
|
|
349
692
|
req_ctx = RequestContext(method=method, url=url, headers=dict(headers), body=json)
|
|
350
693
|
_apply_meta_to_request_ctx(req_ctx, request_meta)
|
|
@@ -355,58 +698,66 @@ def _do_request_sync(
|
|
|
355
698
|
_emit_log(
|
|
356
699
|
config,
|
|
357
700
|
LogEntry(
|
|
358
|
-
level="debug",
|
|
359
|
-
event="request_start",
|
|
360
|
-
operation=operation,
|
|
361
|
-
duration_ms=0,
|
|
701
|
+
level="debug", event="request_start", operation=operation, duration_ms=0
|
|
362
702
|
),
|
|
363
703
|
)
|
|
364
704
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
705
|
+
def _send(ctx: RequestContext) -> httpx.Response:
|
|
706
|
+
b_content, b_data, b_files, b_headers = _body_args(
|
|
707
|
+
content, data, files, ctx.headers
|
|
708
|
+
)
|
|
709
|
+
return client.request(
|
|
710
|
+
ctx.method,
|
|
711
|
+
ctx.url,
|
|
712
|
+
headers=b_headers,
|
|
713
|
+
json=ctx.body
|
|
714
|
+
if content is None and data is None and files is None
|
|
715
|
+
else None,
|
|
716
|
+
content=b_content,
|
|
717
|
+
data=b_data,
|
|
718
|
+
files=b_files,
|
|
719
|
+
timeout=_timeout(timeout_val),
|
|
374
720
|
)
|
|
375
721
|
|
|
722
|
+
def _observe(response: httpx.Response, is_retry: bool) -> None:
|
|
376
723
|
if config.on_response_sync:
|
|
377
724
|
raw = response.content
|
|
378
725
|
parsed = _parse_body(response)
|
|
379
|
-
resp_ctx = ResponseContext(
|
|
726
|
+
resp_ctx = ResponseContext(
|
|
727
|
+
response=response, body=raw, parsed=parsed, is_retry=is_retry
|
|
728
|
+
)
|
|
380
729
|
_apply_meta_to_response_ctx(resp_ctx, request_meta)
|
|
381
730
|
for hook in config.on_response_sync:
|
|
382
731
|
hook(resp_ctx)
|
|
383
732
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
733
|
+
try:
|
|
734
|
+
response = _send(req_ctx)
|
|
735
|
+
_observe(response, False)
|
|
736
|
+
|
|
737
|
+
if (
|
|
738
|
+
response.status_code == 401
|
|
739
|
+
and config.on_auth_expired is not None
|
|
740
|
+
and _replayable(content)
|
|
741
|
+
):
|
|
742
|
+
rejected = auth.token if auth is not None else config.bearer_token
|
|
743
|
+
new_token = (
|
|
744
|
+
auth.refresh_sync(config, rejected)
|
|
745
|
+
if auth is not None
|
|
746
|
+
else _call_auth_hook_sync(config)
|
|
747
|
+
)
|
|
393
748
|
if new_token is not None:
|
|
394
749
|
current_auth_name = _auth_header_name(config).lower()
|
|
395
750
|
extra_no_auth = {
|
|
396
|
-
k: v
|
|
751
|
+
k: v
|
|
752
|
+
for k, v in req_ctx.headers.items()
|
|
397
753
|
if k.lower() != current_auth_name
|
|
398
754
|
}
|
|
399
|
-
retry_headers = _build_headers(
|
|
400
|
-
config, extra=extra_no_auth or None, bearer_token=new_token,
|
|
401
|
-
)
|
|
402
|
-
retry_params = {
|
|
403
|
-
k: v for k, v in (params or {}).items() if v is not None
|
|
404
|
-
} or None
|
|
405
|
-
|
|
406
755
|
retry_ctx = RequestContext(
|
|
407
756
|
method=req_ctx.method,
|
|
408
757
|
url=req_ctx.url,
|
|
409
|
-
headers=
|
|
758
|
+
headers=_build_headers(
|
|
759
|
+
config, extra=extra_no_auth or None, bearer_token=new_token
|
|
760
|
+
),
|
|
410
761
|
body=req_ctx.body,
|
|
411
762
|
is_retry=True,
|
|
412
763
|
)
|
|
@@ -414,27 +765,8 @@ def _do_request_sync(
|
|
|
414
765
|
if config.on_request_sync:
|
|
415
766
|
for hook in config.on_request_sync:
|
|
416
767
|
hook(retry_ctx)
|
|
417
|
-
|
|
418
|
-
response
|
|
419
|
-
retry_ctx.method,
|
|
420
|
-
retry_ctx.url,
|
|
421
|
-
headers=retry_ctx.headers,
|
|
422
|
-
json=retry_ctx.body,
|
|
423
|
-
params=retry_params,
|
|
424
|
-
timeout=(
|
|
425
|
-
httpx.Timeout(timeout_val) if timeout_val is not None else None
|
|
426
|
-
),
|
|
427
|
-
)
|
|
428
|
-
|
|
429
|
-
if config.on_response_sync:
|
|
430
|
-
raw = response.content
|
|
431
|
-
parsed = _parse_body(response)
|
|
432
|
-
resp_ctx = ResponseContext(
|
|
433
|
-
response=response, body=raw, parsed=parsed, is_retry=True,
|
|
434
|
-
)
|
|
435
|
-
_apply_meta_to_response_ctx(resp_ctx, request_meta)
|
|
436
|
-
for hook in config.on_response_sync:
|
|
437
|
-
hook(resp_ctx)
|
|
768
|
+
response = _send(retry_ctx)
|
|
769
|
+
_observe(response, True)
|
|
438
770
|
|
|
439
771
|
_emit_log(
|
|
440
772
|
config,
|
|
@@ -462,17 +794,67 @@ def _do_request_sync(
|
|
|
462
794
|
raise
|
|
463
795
|
|
|
464
796
|
|
|
797
|
+
@asynccontextmanager
|
|
798
|
+
async def _open_stream(
|
|
799
|
+
client: httpx.AsyncClient,
|
|
800
|
+
config: ClientConfig,
|
|
801
|
+
method: str,
|
|
802
|
+
url: str,
|
|
803
|
+
headers: dict[str, str],
|
|
804
|
+
json: Any = None,
|
|
805
|
+
content: Any = None,
|
|
806
|
+
data: Any = None,
|
|
807
|
+
files: Any = None,
|
|
808
|
+
) -> AsyncIterator[httpx.Response]:
|
|
809
|
+
"""Open a streaming response through the request hooks. The read timeout is
|
|
810
|
+
disabled (a stream may idle), connect/write/pool use the config timeout. The
|
|
811
|
+
response is closed on every exit path, including a raised status error."""
|
|
812
|
+
req_ctx = RequestContext(method=method, url=url, headers=dict(headers), body=json)
|
|
813
|
+
if config.on_request:
|
|
814
|
+
for hook in config.on_request:
|
|
815
|
+
await hook(req_ctx)
|
|
816
|
+
timeout = httpx.Timeout(config.timeout, read=None)
|
|
817
|
+
b_content, b_data, b_files, b_headers = _body_args(
|
|
818
|
+
content, data, files, req_ctx.headers
|
|
819
|
+
)
|
|
820
|
+
request = client.build_request(
|
|
821
|
+
req_ctx.method,
|
|
822
|
+
req_ctx.url,
|
|
823
|
+
headers=b_headers,
|
|
824
|
+
json=req_ctx.body
|
|
825
|
+
if content is None and data is None and files is None
|
|
826
|
+
else None,
|
|
827
|
+
content=b_content,
|
|
828
|
+
data=b_data,
|
|
829
|
+
files=b_files,
|
|
830
|
+
timeout=timeout,
|
|
831
|
+
)
|
|
832
|
+
response = await client.send(request, stream=True)
|
|
833
|
+
try:
|
|
834
|
+
if not 200 <= response.status_code < 300:
|
|
835
|
+
await response.aread()
|
|
836
|
+
_raise_for_status(response)
|
|
837
|
+
yield response
|
|
838
|
+
finally:
|
|
839
|
+
await response.aclose()
|
|
840
|
+
|
|
841
|
+
|
|
465
842
|
__all__ = [
|
|
466
843
|
"ClientConfig",
|
|
844
|
+
"FileInput",
|
|
467
845
|
"InvalidationConfig",
|
|
468
846
|
"LogEntry",
|
|
847
|
+
"PathParamError",
|
|
469
848
|
"RequestContext",
|
|
470
849
|
"ResponseContext",
|
|
471
850
|
"SDKResult",
|
|
851
|
+
"_AuthState",
|
|
472
852
|
"_build_headers",
|
|
473
853
|
"_build_url",
|
|
474
854
|
"_do_request_async",
|
|
475
855
|
"_do_request_sync",
|
|
856
|
+
"_expand_path",
|
|
857
|
+
"_open_stream",
|
|
476
858
|
"_parse_body",
|
|
477
859
|
"_raise_for_status",
|
|
478
860
|
]
|