Skip to content

Conversation

@lukeocodes
Copy link
Contributor

Summary

  • Adds deepgram.proxy module with DeepgramProxy class that keeps API keys server-side while proxying REST and WebSocket requests to Deepgram
  • Supports scoped JWT authentication (HMAC-SHA256 signed with the API key) so clients only get access to permitted endpoints
  • Includes framework adapters for FastAPI, Flask, and Django with both REST and WebSocket support
  • 57 unit tests covering scopes, JWT, engine, and end-to-end FastAPI integration

Usage

from deepgram.proxy import DeepgramProxy, Scope

proxy = DeepgramProxy(api_key="dg-xxx")
token = proxy.create_token(scopes=[Scope.LISTEN, Scope.SPEAK], expires_in=3600)

# FastAPI
from deepgram.proxy.adapters.fastapi import create_deepgram_router
app.include_router(create_deepgram_router(proxy), prefix="/deepgram")

Test plan

  • pytest tests/custom/test_proxy_*.py — 57 tests passing
  • ruff check src/deepgram/proxy/ — clean
  • mypy src/deepgram/proxy/ --ignore-missing-imports — clean
  • Manual test with real Deepgram API key and FastAPI app
  • Verify pip install -e ".[proxy]" after pyproject.toml update (documented in TODO.md)

🤖 Generated with Claude Code

Adds a proxy module that keeps Deepgram API keys server-side while
providing scoped JWT auth and REST/WebSocket forwarding. Includes
adapters for FastAPI, Flask, and Django with 57 tests covering scopes,
JWT, engine, and end-to-end FastAPI integration.
Copilot AI review requested due to automatic review settings February 8, 2026 15:26
@lukeocodes lukeocodes changed the base branch from main to lo/v5-5-regen February 8, 2026 15:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new deepgram.proxy module to provide drop-in REST/WebSocket proxy middleware with scoped JWT auth, while also incorporating substantial Fern regeneration output (types/requests), client base URL refactors, CI/release workflow updates, and an examples overhaul.

Changes:

  • Introduces proxy scope matching + JWT management, plus FastAPI end-to-end tests.
  • Refactors client environment/base URL handling and updates generated models/requests/types.
  • Reworks examples/docs and adjusts GitHub Actions release/publish configuration.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/integrations/conftest.py Removes integration-test shared fixtures
tests/integrations/init.py Removes integration-test package marker
tests/custom/test_proxy_scopes.py Adds unit tests for proxy scope/path matching
tests/custom/test_proxy_fastapi.py Adds FastAPI end-to-end proxy adapter tests
src/deepgram/types/speak_v1sample_rate.py Removes generated type alias
src/deepgram/types/speak_v1response.py Changes TTS response type from str to bytes
src/deepgram/types/speak_v1model.py Removes generated type alias
src/deepgram/types/speak_v1mip_opt_out.py Removes generated type alias
src/deepgram/types/speak_v1encoding.py Removes generated type alias
src/deepgram/types/project_request_response.py Tightens response dict typing
src/deepgram/types/listen_v2tag.py Removes generated type alias
src/deepgram/types/listen_v2sample_rate.py Removes generated type alias
src/deepgram/types/listen_v2model.py Removes generated type alias
src/deepgram/types/listen_v2mip_opt_out.py Removes generated type alias
src/deepgram/types/listen_v2keyterm.py Removes generated type alias
src/deepgram/types/listen_v2eot_timeout_ms.py Removes generated type alias
src/deepgram/types/listen_v2eot_threshold.py Removes generated type alias
src/deepgram/types/listen_v2encoding.py Removes generated type alias
src/deepgram/types/listen_v2eager_eot_threshold.py Removes generated type alias
src/deepgram/types/listen_v1version.py Removes generated type alias
src/deepgram/types/listen_v1vad_events.py Removes generated type alias
src/deepgram/types/listen_v1utterance_end_ms.py Removes generated type alias
src/deepgram/types/listen_v1tag.py Removes generated type alias
src/deepgram/types/listen_v1smart_format.py Removes generated type alias
src/deepgram/types/listen_v1search.py Removes generated type alias
src/deepgram/types/listen_v1sample_rate.py Removes generated type alias
src/deepgram/types/listen_v1response_results_channels_item_alternatives_item_entities_item.py Adds new entities model type
src/deepgram/types/listen_v1response_results_channels_item_alternatives_item.py Wires entities into alternatives model
src/deepgram/types/listen_v1response_metadata.py Tightens model_info typing
src/deepgram/types/listen_v1request_file.py Changes request file type from str to bytes
src/deepgram/types/listen_v1replace.py Removes generated type alias
src/deepgram/types/listen_v1redact.py Removes generated type alias
src/deepgram/types/listen_v1punctuate.py Removes generated type alias
src/deepgram/types/listen_v1profanity_filter.py Removes generated type alias
src/deepgram/types/listen_v1numerals.py Removes generated type alias
src/deepgram/types/listen_v1multichannel.py Removes generated type alias
src/deepgram/types/listen_v1model.py Removes generated model literal union
src/deepgram/types/listen_v1mip_opt_out.py Removes generated type alias
src/deepgram/types/listen_v1language.py Removes generated type alias
src/deepgram/types/listen_v1keywords.py Removes generated type alias
src/deepgram/types/listen_v1keyterm.py Removes generated type alias
src/deepgram/types/listen_v1interim_results.py Removes generated type alias
src/deepgram/types/listen_v1extra.py Removes generated type alias
src/deepgram/types/listen_v1endpointing.py Removes generated type alias
src/deepgram/types/listen_v1encoding.py Removes generated type alias
src/deepgram/types/listen_v1dictation.py Removes generated type alias
src/deepgram/types/listen_v1diarize.py Removes generated type alias
src/deepgram/types/listen_v1channels.py Removes generated type alias
src/deepgram/types/listen_v1callback_method.py Removes generated type alias
src/deepgram/types/list_models_v1response_tts_models.py Makes uuid_ a Field alias explicitly
src/deepgram/types/list_models_v1response_stt_models.py Makes uuid_ a Field alias explicitly
src/deepgram/types/get_model_v1response_metadata.py Makes uuid_ a Field alias explicitly
src/deepgram/types/get_model_v1response_batch.py Makes uuid_ a Field alias explicitly
src/deepgram/types/create_key_v1request_one.py Changes optional payload alias to Any
src/deepgram/speak/v1/audio/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/speak/raw_client.py Removes raw client wrapper
src/deepgram/speak/client.py Removes with_raw_response wrapper
src/deepgram/self_hosted/v1/raw_client.py Removes raw client wrapper
src/deepgram/self_hosted/v1/client.py Removes with_raw_response wrapper
src/deepgram/self_hosted/raw_client.py Removes raw client wrapper
src/deepgram/self_hosted/client.py Removes with_raw_response wrapper
src/deepgram/requests/project_request_response.py Tightens response dict typing
src/deepgram/requests/listen_v2keyterm.py Removes generated param alias
src/deepgram/requests/listen_v1response_results_channels_item_alternatives_item_entities_item.py Adds request TypedDict for entities
src/deepgram/requests/listen_v1response_results_channels_item_alternatives_item.py Wires entities into TypedDict
src/deepgram/requests/listen_v1response_metadata.py Tightens model_info typing
src/deepgram/requests/init.py Exports new entities params, removes ListenV2KeytermParams
src/deepgram/read/v1/text/types/text_analyze_request_summarize.py Removes "v1" summarize option literal
src/deepgram/read/v1/text/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/read/v1/text/client.py Expands docstring examples with more params
src/deepgram/read/v1/raw_client.py Removes raw client wrapper
src/deepgram/read/v1/client.py Removes with_raw_response wrapper
src/deepgram/read/raw_client.py Removes raw client wrapper
src/deepgram/read/client.py Removes with_raw_response wrapper
src/deepgram/proxy/scopes.py Adds scope definitions + path routing
src/deepgram/proxy/jwt.py Adds JWT creation/validation with PyJWT
src/deepgram/proxy/errors.py Adds proxy-specific exceptions
src/deepgram/proxy/adapters/init.py Adds adapters package initializer
src/deepgram/proxy/init.py Exports DeepgramProxy and Scope
src/deepgram/manage/v1/raw_client.py Removes raw client wrapper
src/deepgram/manage/v1/projects/usage/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/usage/fields/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/usage/fields/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/usage/breakdown/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/requests/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/requests/client.py Expands docstring examples (datetime + filters)
src/deepgram/manage/v1/projects/models/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/models/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/members/scopes/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/members/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/keys/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/billing/raw_client.py Removes raw client wrapper
src/deepgram/manage/v1/projects/billing/purchases/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/billing/purchases/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/billing/fields/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/billing/fields/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/billing/client.py Removes with_raw_response wrapper
src/deepgram/manage/v1/projects/billing/breakdown/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/projects/billing/breakdown/client.py Expands docstring examples with params
src/deepgram/manage/v1/projects/billing/balances/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/models/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/manage/v1/models/client.py Expands docstring examples with params
src/deepgram/manage/v1/client.py Removes with_raw_response wrapper
src/deepgram/manage/raw_client.py Removes raw client wrapper
src/deepgram/manage/client.py Removes with_raw_response wrapper
src/deepgram/listen/v2/init.py Removes v2 init file
src/deepgram/listen/v1/media/types/media_transcribe_request_summarize.py Removes "v1" summarize option literal
src/deepgram/listen/v1/media/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/listen/v1/media/client.py Expands docstring examples with params
src/deepgram/listen/raw_client.py Removes raw client wrapper
src/deepgram/listen/client.py Removes v2 surface + raw-response wrapper
src/deepgram/listen/init.py Removes lazy import/export of v2
src/deepgram/extensions/types/sockets/speak_v1_warning_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/speak_v1_text_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/speak_v1_metadata_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/speak_v1_control_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/speak_v1_control_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/speak_v1_audio_chunk_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/listen_v2_turn_info_event.py Removes generated socket event type
src/deepgram/extensions/types/sockets/listen_v2_media_message.py Removes generated socket message type
src/deepgram/extensions/types/sockets/listen_v2_fatal_error_event.py Removes generated socket event type
src/deepgram/extensions/types/sockets/listen_v2_control_message.py Removes generated socket control type
src/deepgram/extensions/types/sockets/listen_v2_connected_event.py Removes generated socket event type
src/deepgram/extensions/types/sockets/listen_v1_utterance_end_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/listen_v1_speech_started_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/listen_v1_metadata_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/listen_v1_media_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/listen_v1_control_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_welcome_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_warning_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_user_started_speaking_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_update_speak_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_update_prompt_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_speak_updated_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_settings_applied_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_prompt_updated_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_media_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_injection_refused_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_inject_user_message_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_inject_agent_message_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_function_call_response_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_function_call_request_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_error_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_conversation_text_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_control_message.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_audio_chunk_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_agent_thinking_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_agent_started_speaking_event.py Removes protected socket type
src/deepgram/extensions/types/sockets/agent_v1_agent_audio_done_event.py Removes protected socket type
src/deepgram/extensions/telemetry/handler.py Removes telemetry handler interface
src/deepgram/extensions/telemetry/init.py Removes telemetry package initializer
src/deepgram/errors/bad_request_error.py Changes BadRequestError body typing to Any
src/deepgram/environment.py Replaces environment class with Enum containing base URLs
src/deepgram/core/jsonable_encoder.py Adds Ellipsis (“OMIT”) filtering rules
src/deepgram/core/http_sse/_models.py Adds SSE event model
src/deepgram/core/http_sse/_exceptions.py Replaces alias with SSEError exception
src/deepgram/core/http_sse/_decoders.py Adds SSE line decoder implementation
src/deepgram/core/http_sse/init.py Adds SSE package lazy exports
src/deepgram/base_client.py Adds base_url parameter + resolves environment to base URL
src/deepgram/auth/v1/tokens/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/auth/v1/raw_client.py Removes raw client wrapper
src/deepgram/auth/v1/client.py Removes with_raw_response wrapper
src/deepgram/auth/raw_client.py Removes raw client wrapper
src/deepgram/auth/client.py Removes with_raw_response wrapper
src/deepgram/agent/v1/settings/think/raw_client.py Removes raw client wrapper
src/deepgram/agent/v1/settings/think/models/raw_client.py Removes explicit base_url arg and adjusts error-body typing
src/deepgram/agent/v1/settings/think/client.py Removes with_raw_response wrapper
src/deepgram/agent/v1/settings/raw_client.py Removes raw client wrapper
src/deepgram/agent/v1/settings/client.py Removes with_raw_response wrapper
src/deepgram/agent/raw_client.py Removes raw client wrapper
src/deepgram/agent/client.py Removes with_raw_response wrapper
pyproject.toml Version bump + Poetry config adjustments + dev deps updates
mypy.ini Removes mypy config file
examples/speak/v1/connect/with_raw_response.py Removes old example
examples/speak/v1/connect/with_auth_token.py Removes old example
examples/speak/v1/connect/main.py Removes old example
examples/speak/v1/connect/async.py Removes old example
examples/speak/v1/audio/generate/with_raw_response.py Removes old example
examples/speak/v1/audio/generate/with_auth_token.py Removes old example
examples/speak/v1/audio/generate/main.py Removes old example
examples/speak/v1/audio/generate/async.py Removes old example
examples/read/v1/text/analyze/with_raw_response.py Removes old example
examples/read/v1/text/analyze/with_auth_token.py Removes old example
examples/read/v1/text/analyze/main.py Removes old example
examples/read/v1/text/analyze/async.py Removes old example
examples/listen/v2/connect/with_raw_response.py Removes old example
examples/listen/v2/connect/with_auth_token.py Removes old example
examples/listen/v2/connect/main.py Removes old example
examples/listen/v2/connect/async.py Removes old example
examples/listen/v1/media/transcribe_url/with_raw_response.py Removes old example
examples/listen/v1/media/transcribe_url/with_auth_token.py Removes old example
examples/listen/v1/media/transcribe_url/main.py Removes old example
examples/listen/v1/media/transcribe_url/async.py Removes old example
examples/listen/v1/media/transcribe_file/with_raw_response.py Removes old example
examples/listen/v1/media/transcribe_file/with_auth_token.py Removes old example
examples/listen/v1/media/transcribe_file/main.py Removes old example
examples/listen/v1/media/transcribe_file/async.py Removes old example
examples/listen/v1/connect/with_raw_response.py Removes old example
examples/listen/v1/connect/with_auth_token.py Removes old example
examples/listen/v1/connect/main.py Removes old example
examples/listen/v1/connect/async.py Removes old example
examples/agent/v1/connect/with_raw_response.py Removes old example
examples/agent/v1/connect/with_auth_token.py Removes old example
examples/agent/v1/connect/async.py Removes old example
examples/26-transcription-live-websocket-v2.py Adds new numbered v2 WebSocket example
examples/24-error-handling.py Adds error-handling example
examples/23-request-options.py Adds request options example
examples/22-transcription-advanced-options.py Adds advanced transcription example
examples/20-onprem-credentials.py Adds self-hosted credentials example
examples/19-management-models.py Adds management models example
examples/18-management-billing.py Adds management billing example
examples/17-management-usage.py Adds management usage example
examples/16-management-invites.py Adds management invites example
examples/15-management-members.py Adds management members example
examples/14-management-keys.py Adds management keys example
examples/13-management-projects.py Adds management projects example
examples/12-text-intelligence.py Adds Read/Text Intelligence example
examples/11-text-to-speech-streaming.py Adds TTS WebSocket example
examples/10-text-to-speech-single.py Adds TTS REST streaming example
examples/07-transcription-live-websocket.py Adds v1 WebSocket example
examples/06-transcription-prerecorded-callback.py Adds callback transcription example
examples/05-transcription-prerecorded-file.py Adds file transcription example
examples/04-transcription-prerecorded-url.py Adds URL transcription example
examples/02-authentication-access-token.py Adds access token example
examples/01-authentication-api-key.py Adds API key example
docs/Migrating-v3-to-v5.md Appends trailing newline
docs/Migrating-v2-to-v3.md Appends trailing newline
TODO.md Adds follow-ups for proxy packaging deps/extras
LICENSE Updates copyright year
CONTRIBUTING.md Removes contributing guide
.github/workflows/tests-daily.yml Adds Docker availability check
.github/workflows/release-please.yml Switches publish method + adds Docker check + id-token
.github/workflows/pr-title-check.yml Appends trailing newline
.github/workflows/ci.yml Adds PATH fix, Docker check, and OIDC publish job
.github/workflows/changelog-log.yml Appends trailing newline
.github/ISSUE_TEMPLATE/feature_request.yml Removes issue template
.github/ISSUE_TEMPLATE/docs_improvement.yml Removes issue template
.github/CODEOWNERS Removes CODEOWNERS
.github/.release-please-manifest.json Adds trailing newline
.github/.commitlintrc.json Adds trailing newline
.fernignore Rewrites ignore list and comments
.fern/metadata.json Adds Fern generator metadata snapshot

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 9 to 10
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listen.v2 is removed from lazy imports and __all__, but the PR adds a new v2 WebSocket example (and previously supported v2 usage). Either restore the v2 export here (and corresponding client surface) or update/remove the new v2 example so the public API and examples stay consistent.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listen.v2 is removed from lazy imports and __all__, but the PR adds a new v2 WebSocket example (and previously supported v2 usage). Either restore the v2 export here (and corresponding client surface) or update/remove the new v2 example so the public API and examples stay consistent.

Copilot uses AI. Check for mistakes.
Comment on lines 14 to 20
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example imports/uses deepgram.listen.v2 and client.listen.v2, but the PR removes listen.v2 exports from src/deepgram/listen/__init__.py and removes the v2 surface from src/deepgram/listen/client.py. Update the example to match the supported API surface, or reintroduce v2 support so this example runs.

Copilot uses AI. Check for mistakes.
Comment on lines 16 to 37
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example imports/uses deepgram.listen.v2 and client.listen.v2, but the PR removes listen.v2 exports from src/deepgram/listen/__init__.py and removes the v2 surface from src/deepgram/listen/client.py. Update the example to match the supported API surface, or reintroduce v2 support so this example runs.

Suggested change
client = DeepgramClient()
try:
with client.listen.connect(model="flux-general-en", encoding="linear16", sample_rate="16000") as connection:
def on_message(message) -> None:
msg_type = getattr(message, "type", "Unknown")
print(f"Received {msg_type} event")
# Extract transcription-like information when available
if hasattr(message, "transcript"):
print(f"Turn transcript: {getattr(message, 'transcript', None)}")
print(f"Turn event: {getattr(message, 'event', None)}")
print(f"Turn index: {getattr(message, 'turn_index', None)}")

Copilot uses AI. Check for mistakes.
except ImportError:
raise ImportError(
"PyJWT is required for proxy JWT support. "
"Install it with: pip install 'deepgram-sdk[proxy]' or pip install PyJWT"
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message instructs users to install deepgram-sdk[proxy], but this PR does not add a proxy extra to pyproject.toml (and TODO.md indicates it’s still pending). Either add the Poetry extra and optional dependency now, or adjust this message to only recommend pip install PyJWT until the extra exists.

Suggested change
"Install it with: pip install 'deepgram-sdk[proxy]' or pip install PyJWT"
"Install it with: pip install PyJWT"

Copilot uses AI. Check for mistakes.
)

proxy._async_client = httpx.AsyncClient(transport=httpx.MockTransport(mock_handler))

Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test creates an httpx.AsyncClient but never closes it, which can cause resource warnings and flaky test behavior. Consider closing it via a fixture finalizer (yield fixture) or wiring an app shutdown handler that calls await proxy._async_client.aclose().

Suggested change
async def close_client() -> None:
async_client = getattr(proxy, "_async_client", None)
if async_client is not None:
await async_client.aclose()
application.add_event_handler("shutdown", close_client)

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says Ellipsis/OMIT values should be excluded, but at the top-level this returns None, which can serialize to JSON null (and still be sent) depending on the caller. Prefer a strategy that truly omits the value (e.g., raising to force callers to filter, or returning a sentinel that upstream serializers drop) to avoid accidentally sending null for omitted fields.

Suggested change
raise ValueError(
"Top-level Ellipsis/OMIT values cannot be JSON-encoded. "
"Callers should omit these values instead of passing them to jsonable_encoder."
)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant