- Notifications
You must be signed in to change notification settings - Fork 109
feat(auth): adding token-based auth to the SDK so access tokens can be used in requests #543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis update introduces support for both API key and access token authentication in the Deepgram Python SDK, updating client initialization logic, configuration handling, and documentation. It adds comprehensive unit tests for authentication mechanisms, a bearer token authentication example, and a script to run all examples. The Changes
Sequence Diagram(s)sequenceDiagram participant User participant DeepgramClient participant DeepgramAPI User->>DeepgramClient: Initialize (api_key and/or access_token) alt access_token provided DeepgramClient->>DeepgramClient: Set Authorization header (Bearer) else api_key provided DeepgramClient->>DeepgramClient: Set Authorization header (Token) else DeepgramClient->>User: Warn/raise error (no credentials) end User->>DeepgramClient: Request grant_token (with API key) DeepgramClient->>DeepgramAPI: POST /auth/token DeepgramAPI-->>DeepgramClient: Return access_token User->>DeepgramClient: Initialize new client with access_token DeepgramClient->>DeepgramClient: Set Authorization header (Bearer) User->>DeepgramClient: Transcribe audio DeepgramClient->>DeepgramAPI: POST /listen (with Bearer token) DeepgramAPI-->>DeepgramClient: Return transcript DeepgramClient-->>User: Transcript result Possibly related PRs
Suggested labels
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Pylint (3.3.7)deepgram/client.pytests/unit_test/test_unit_authentication.pydeepgram/options.py✨ Finishing Touches
🧪 Generate Unit Tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
README.md (1)
125-125: Fix typo in the word "abstract".There's a typo in the word "abtract" which should be "abstract".
-This SDK aims to reduce complexity and abtract/hide some internal Deepgram details that clients shouldn't need to know about. However you can still tweak options and settings if you need. +This SDK aims to reduce complexity and abstract/hide some internal Deepgram details that clients shouldn't need to know about. However, you can still tweak options and settings if you need.examples/all.py (1)
140-142: Consider option to continue on failures for comprehensive testing.The script currently stops on the first failure, which might prevent discovering issues in other examples. Consider adding a
--continue-on-errorflag for comprehensive testing scenarios.# Add argument parsing for continue-on-error option import argparse def main(): parser = argparse.ArgumentParser() parser.add_argument('--continue-on-error', action='store_true', help='Continue running examples even if some fail') args = parser.parse_args() # Later in the loop: if not success and not args.continue_on_error: print(f"\n🛑 Stopping execution due to failure in: {script}") breakdeepgram/options.py (1)
141-142: Consider separating unrelated improvements.While these float conversions improve robustness, they're unrelated to the authentication feature. Consider keeping PRs focused on a single concern for easier review and git history.
Also applies to: 152-153
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.gitignore(1 hunks)README.md(3 hunks)deepgram/client.py(12 hunks)deepgram/options.py(11 hunks)examples/all.py(1 hunks)examples/auth/bearer_token_demo/main.py(1 hunks)tests/unit_test/test_unit_authentication.py(1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~78-~78: Loose punctuation mark.
Context: ...ronment variables: - DEEPGRAM_API_KEY: Your Deepgram API key - `DEEPGRAM_ACCES...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~125-~125: A comma may be missing after the conjunctive/linking adverb ‘However’.
Context: ...t clients shouldn't need to know about. However you can still tweak options and setting...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
🔇 Additional comments (12)
.gitignore (1)
28-30: LGTM - Appropriate test artifact exclusions.The addition of test audio artifacts to
.gitignoreis correct and prevents accidentally committing generated files from examples and tests.README.md (1)
32-82: Excellent authentication documentation.The new Authentication section clearly documents both authentication methods with comprehensive examples. The precedence rules are well explained, making it easy for users to understand how credentials are resolved.
examples/auth/bearer_token_demo/main.py (1)
23-65: Excellent authentication workflow demonstration.The example clearly demonstrates the complete API key to bearer token workflow with good error handling and informative logging. The 4-step process is well-documented and easy to follow.
examples/all.py (1)
19-94: Excellent example discovery and execution framework.The script provides a robust framework for discovering and running examples with smart filtering, real-time output streaming, and comprehensive error handling. The separation into well-named functions makes it maintainable and easy to understand.
deepgram/client.py (3)
417-417: Clear documentation updates for dual authentication.The docstring updates clearly reflect the new dual authentication support and error conditions.
Also applies to: 421-421
446-485: Excellent authentication credential resolution logic.The implementation correctly handles credential precedence with a clear waterfall approach:
- Explicit parameters (access_token preferred over api_key)
- Config object credentials
- Environment variables (DEEPGRAM_ACCESS_TOKEN before DEEPGRAM_API_KEY)
- Appropriate warnings for missing credentials
The code maintains backward compatibility while properly supporting the new authentication method.
463-465: ```shell
#!/bin/bash
grep -R "Neither API key nor access token is provided" -n deepgram/client.py || echo "Not found"</details> <details> <summary>deepgram/options.py (4)</summary> `25-61`: **Well-implemented authentication parameter additions.** The constructor changes properly handle the new `access_token` parameter with appropriate None checks and documentation. The custom header preservation logic is a thoughtful addition that ensures user-defined headers aren't lost during authentication updates. --- `84-96`: **Correct implementation of mutually exclusive authentication methods.** The `set_apikey` and `set_access_token` methods properly maintain mutual exclusivity by clearing the alternate credential. The symmetric implementation ensures consistent behavior. --- `103-127`: **Excellent header management with proper authentication priority.** The refactored `_update_headers` method correctly implements: - Custom header preservation for non-system headers - Access token priority over API key as documented - Proper Bearer/Token prefixes for different authentication types --- `199-212`: **Correct implementation of environment variable priority.** The credential loading logic properly implements the documented priority order with `DEEPGRAM_ACCESS_TOKEN` taking precedence over `DEEPGRAM_API_KEY`. The error handling ensures users provide at least one form of authentication. </details> <details> <summary>tests/unit_test/test_unit_authentication.py (1)</summary> `1-443`: **Excellent comprehensive test coverage for authentication features.** This test suite thoroughly validates all aspects of the new authentication functionality: - Correct Authorization header formats (Token/Bearer) - Credential priority across different initialization methods - Environment variable resolution and precedence - Dynamic credential switching behavior - Error handling scenarios - Complete API key to access token workflow The tests are well-organized, follow good naming conventions, and provide confidence in the implementation's correctness. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
README.md (4)
11-11: TOC: Remove unnecessary escaping in ‘V3. to V4’.*
The backslash before the asterisk is not needed and may break the Markdown link anchor.Apply:
- - [V3.\*\ to V4](#v3-to-v4) + - [V3.* to V4](#v3-to-v4)
83-85: Refine migration guide wording for clarity.
Change “on our docs” to “in our documentation” for formality and consistency:- We have published [a migration guide on our docs](…) + We have published [a migration guide in our documentation](…)
93-93: Installation prompt: simplify wording.
Consider dropping “available” for brevity:- To install the latest version available: + To install the latest version:
101-101: Conciseness: remove “of” in sentence.
Refactor for brevity:- All of the examples below will require `DeepgramClient`. + The examples below require `DeepgramClient`.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
README.md(4 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[duplication] ~10-~10: Possible typo: you repeated a word.
Context: ...ating-from-earlier-versions) - V2 to V3 - V3.*\ to V4 - [Requirements](...
(ENGLISH_WORD_REPEAT_RULE)
[grammar] ~31-~31: This phrase is duplicated. You should probably use “Projects Get” only once.
Context: ...ils) - Grant Token - Projects - Get Projects - Get Project - [Update Proj...
(PHRASE_REPETITION)
[style] ~100-~100: Consider removing “of” to be more concise
Context: ...ll deepgram-sdk ``` ## Initialization All of the examples below will require `DeepgramCl...
(ALL_OF_THE)
[uncategorized] ~112-~112: Possible missing comma found.
Context: ...g an API Key 🔑 To access the Deepgram API you will need a [free Deepgram API Key]...
(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~397-~397: This phrase is duplicated. You should probably use “environment variable” only once.
Context: ...arameter** 3. DEEPGRAM_ACCESS_TOKEN environment variable 4. DEEPGRAM_API_KEY environment variable (lowest priority) ### Environment Va...
(PHRASE_REPETITION)
[style] ~568-~568: Consider removing “of” to be more concise
Context: ... Members Retrieves account objects for all of the accounts in the specified project_id. ...
(ALL_OF_THE)
[style] ~778-~778: Consider a different adjective to strengthen your wording.
Context: ...ide) if you'd like to learn more. For a deeper understanding of how version numbers wo...
(DEEP_PROFOUND)
[uncategorized] ~780-~780: Possible missing comma found.
Context: ...ts.txtfile, you can pin to a specific version like this: ```sh deepgram-sdk==4.1.0...
(AI_HYDRA_LEO_MISSING_COMMA)
[style] ~794-~794: To make your writing clearer, consider a more direct alternative.
Context: ... ## Logging This SDK provides logging as a means to troubleshoot and debug issues encountered. By defaul...
(AS_A_MEANS_TO)
[style] ~794-~794: In American English, abbreviations like “etc.” require a period.
Context: ...ages and higher (ie Warning, Error, etc) when you initialize the library as fol...
(ETC_PERIOD)
[uncategorized] ~839-~839: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ... we will maintain backward compatibility so your code will continue to work without...
(COMMA_COMPOUND_SENTENCE_2)
[style] ~850-~850: Consider a more concise word here.
Context: ...G.md) guidelines for more information. In order to develop new features for the SDK itself...
(IN_ORDER_TO_PREMIUM)
🔇 Additional comments (7)
README.md (7)
3-3: Verify badge URLs and styling consistency.
Ensure the new Discord, CI, and PyPI badges render correctly and link to the intended resources.
9-10: TOC: Migrating section entries look good.
The new “Migrating from earlier versions” and its sub-entries correctly reflect the added section.
14-15: TOC: Initialization entries are correct.
Initialization and “Getting an API Key” links correctly point to the new section.
28-31: TOC: Authentication entries added.
The new “Authentication” section and its token sub-entries are now discoverable in the table of contents.
77-81: Add “Migrating from earlier versions” section.
The new headers and structure for V2→V3 and V3→V4 migrations match the PR objectives.
99-99: Initialization header placement.
The new “## Initialization” header correctly introduces the client setup examples.
104-104: Import statement for client initialization.
The samplefrom deepgram import DeepgramClientimport aligns with the new dual-auth API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
tests/daily_test/test_daily_listen_websocket.py (1)
1-177: Consider extracting common test logic to reduce duplication.This file is nearly identical to
test_daily_async_listen_websocket.pyexcept for async/await keywords. Consider extracting the common test logic into a shared base class or utility functions.Create a shared test utilities module:
# tests/daily_test/websocket_test_utils.py def create_test_state(): return { "transcript_received": False, "message_structure_valid": False, "raw_json": "" } def validate_message_structure(result, test_state): """Common message validation logic.""" try: # Check if we can access the transcript (validates structure) transcript = result.channel.alternatives[0].transcript # Validate that essential fields exist assert hasattr(result, 'channel'), "Result should have channel field" assert hasattr(result, 'is_final'), "Result should have is_final field" assert hasattr(result, 'metadata'), "Result should have metadata field" assert hasattr(result.channel, 'alternatives'), "Channel should have alternatives" assert len(result.channel.alternatives) > 0, "Should have at least one alternative" test_state["message_structure_valid"] = True test_state["raw_json"] = result.to_json() test_state["transcript_received"] = True except (AttributeError, IndexError, AssertionError) as e: print(f"Message structure validation failed: {type(e).__name__}: {e}") test_state["message_structure_valid"] = False def generate_test_filenames(unique): """Generate test file paths.""" return { "cmd": f"tests/response_data/listen/websocket/{unique}.cmd", "options": f"tests/response_data/listen/websocket/{unique}-options.json", "resp": f"tests/response_data/listen/websocket/{unique}-response.json", "error": f"tests/response_data/listen/websocket/{unique}-error.json" }This would significantly reduce code duplication and make maintenance easier.
♻️ Duplicate comments (5)
tests/daily_test/test_daily_listen_websocket.py (4)
22-22: Remove unused MODEL variable.
122-124: Use specific exception types for better error diagnostics.
150-150: Fix spacing in slice notation.
54-65: Replace global variables with local test state.Same issue as in the async version - global variables can cause race conditions.
Also applies to: 97-97
tests/unit_test/test_unit_authentication.py (1)
183-193: Related to environment variable priority issueThis test also expects
DEEPGRAM_API_KEYto take precedence overDEEPGRAM_ACCESS_TOKEN, which appears to contradict the documented priority order in the PR objectives.
🧹 Nitpick comments (5)
tests/daily_test/test_daily_async_listen_websocket.py (3)
22-22: Remove unused MODEL variable.The
MODELvariable is defined but never used in the test.-MODEL = "general-nova-3" -
123-125: Consider catching specific exceptions for better error diagnostics.The broad
Exceptioncatch might hide specific validation errors that could provide better diagnostics.- except Exception as e: - print(f"Message structure validation failed: {e}") - message_structure_valid = False + except (AttributeError, IndexError, AssertionError) as e: + print(f"Message structure validation failed: {type(e).__name__}: {e}") + message_structure_valid = False + except Exception as e: + print(f"Unexpected error during message validation: {type(e).__name__}: {e}") + message_structure_valid = False + raise # Re-raise unexpected exceptions for better debugging
150-150: Fix inconsistent spacing in slice notation.- chunk = data[i: i + chunk_size].tobytes() + chunk = data[i:i + chunk_size].tobytes()tests/unit_test/test_unit_authentication.py (2)
292-292: Remove unused importThe
loggingmodule is imported but not used in this test method.- import logging - with patch('deepgram.client.verboselogs.VerboseLogger') as mock_logger:
1-446: Consider adding edge case testsWhile the test coverage is comprehensive, consider adding tests for these edge cases:
- Thread safety of credential switching in concurrent scenarios
- Behavior when switching credentials during active API calls
- Token expiration handling scenarios
Would you like me to generate additional test cases for these scenarios?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/response_data/speak/rest/18144fa7f4709bc9972c24d0addc8faa360dca933e7e0027b062e57b7c41f426-f8c3bf62a9aa3e6fc1619c250e48abe7519373d3edf41be62eb5dc45199af2ef.wavis excluded by!**/*.wav
📒 Files selected for processing (13)
deepgram/client.py(12 hunks)deepgram/clients/listen/v1/rest/options.py(1 hunks)deepgram/clients/listen/v1/websocket/options.py(1 hunks)deepgram/options.py(11 hunks)tests/daily_test/test_daily_async_listen_websocket.py(4 hunks)tests/daily_test/test_daily_listen_websocket.py(4 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-options.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-response.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469.cmd(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-options.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-response.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df.cmd(1 hunks)tests/unit_test/test_unit_authentication.py(1 hunks)
✅ Files skipped from review due to trivial changes (8)
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-options.json
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-options.json
- deepgram/clients/listen/v1/rest/options.py
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df.cmd
- deepgram/clients/listen/v1/websocket/options.py
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-response.json
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469.cmd
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-response.json
🚧 Files skipped from review as they are similar to previous changes (2)
- deepgram/client.py
- deepgram/options.py
🔇 Additional comments (3)
tests/unit_test/test_unit_authentication.py (3)
15-21: LGTM!This test correctly verifies that API keys generate the expected
Tokenauthorization header format.
207-222: Well-structured auth switching testThis test properly verifies the authentication switching behavior, including the important detail that the previous credential is cleared when switching auth methods.
351-389: Excellent workflow test coverageThis test comprehensively validates the complete API key to access token workflow, properly mocking the grant token response and verifying each step of the process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
tests/unit_test/test_unit_authentication.py (1)
445-446: Incomplete assertion statement.Line 446 has an assertion that appears incomplete or incorrectly formatted. It's missing the expected value comparison.
The assertion should be properly formatted:
- assert api_client._config.api_key != bearer_client._config.access_token + assert api_client._config.api_key != bearer_client._config.access_tokenIf this was intended to verify the values are different, consider adding a more descriptive assertion message:
- assert api_client._config.api_key != bearer_client._config.access_token + assert api_client._config.api_key != bearer_client._config.access_token, \ + "API key and access token should be different"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/response_data/speak/rest/1fe0ad339338a9d6cffbab2c7ace41ba5387b5fe7906854795702dce91034fd3-f8c3bf62a9aa3e6fc1619c250e48abe7519373d3edf41be62eb5dc45199af2ef.wavis excluded by!**/*.wav
📒 Files selected for processing (12)
deepgram/client.py(12 hunks)deepgram/options.py(10 hunks)tests/response_data/listen/rest/a231370d439312b1a404bb6ad8de955e900ec8eae9a906329af8cc672e6ec7ba-29e7c8100617f70da4ae9da1921cb5071a01219f4780ca70930b0a370ed2163a-response.json(1 hunks)tests/response_data/listen/rest/a231370d439312b1a404bb6ad8de955e900ec8eae9a906329af8cc672e6ec7ba-a17f4880c5b4cf124ac54d06d77c9f0ab7f3fe1052ff1c7b090f7eaf8ede5b76-response.json(1 hunks)tests/response_data/listen/rest/c4e1c0031174878d8f0e3dbd87916ee16d56f1c610ac525af5712ea37226a455-29e7c8100617f70da4ae9da1921cb5071a01219f4780ca70930b0a370ed2163a-response.json(1 hunks)tests/response_data/listen/rest/c4e1c0031174878d8f0e3dbd87916ee16d56f1c610ac525af5712ea37226a455-a17f4880c5b4cf124ac54d06d77c9f0ab7f3fe1052ff1c7b090f7eaf8ede5b76-response.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-response.json(1 hunks)tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-response.json(1 hunks)tests/response_data/read/rest/3917a1c81c08e360c0d4bba0ff9ebd645e610e4149483e5f2888a2c5df388b37-23e873efdfd4d680286fda14ff8f10864218311e79efc92ecc82bce3e574c366-error.json(1 hunks)tests/response_data/read/rest/3917a1c81c08e360c0d4bba0ff9ebd645e610e4149483e5f2888a2c5df388b37-23e873efdfd4d680286fda14ff8f10864218311e79efc92ecc82bce3e574c366-response.json(1 hunks)tests/response_data/speak/rest/1fe0ad339338a9d6cffbab2c7ace41ba5387b5fe7906854795702dce91034fd3-f8c3bf62a9aa3e6fc1619c250e48abe7519373d3edf41be62eb5dc45199af2ef-response.json(1 hunks)tests/unit_test/test_unit_authentication.py(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- tests/response_data/read/rest/3917a1c81c08e360c0d4bba0ff9ebd645e610e4149483e5f2888a2c5df388b37-23e873efdfd4d680286fda14ff8f10864218311e79efc92ecc82bce3e574c366-error.json
- tests/response_data/read/rest/3917a1c81c08e360c0d4bba0ff9ebd645e610e4149483e5f2888a2c5df388b37-23e873efdfd4d680286fda14ff8f10864218311e79efc92ecc82bce3e574c366-response.json
- tests/response_data/listen/rest/a231370d439312b1a404bb6ad8de955e900ec8eae9a906329af8cc672e6ec7ba-29e7c8100617f70da4ae9da1921cb5071a01219f4780ca70930b0a370ed2163a-response.json
🚧 Files skipped from review as they are similar to previous changes (8)
- tests/response_data/speak/rest/1fe0ad339338a9d6cffbab2c7ace41ba5387b5fe7906854795702dce91034fd3-f8c3bf62a9aa3e6fc1619c250e48abe7519373d3edf41be62eb5dc45199af2ef-response.json
- tests/response_data/listen/rest/c4e1c0031174878d8f0e3dbd87916ee16d56f1c610ac525af5712ea37226a455-29e7c8100617f70da4ae9da1921cb5071a01219f4780ca70930b0a370ed2163a-response.json
- tests/response_data/listen/rest/c4e1c0031174878d8f0e3dbd87916ee16d56f1c610ac525af5712ea37226a455-a17f4880c5b4cf124ac54d06d77c9f0ab7f3fe1052ff1c7b090f7eaf8ede5b76-response.json
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-42fc5ed98cabc1fa1a2f276301c27c46dd15f6f5187cd93d944cc94fa81c8469-response.json
- tests/response_data/listen/rest/a231370d439312b1a404bb6ad8de955e900ec8eae9a906329af8cc672e6ec7ba-a17f4880c5b4cf124ac54d06d77c9f0ab7f3fe1052ff1c7b090f7eaf8ede5b76-response.json
- tests/response_data/listen/websocket/ed5bfd217988aa8cad492f63f79dc59f5f02fb9b85befe6f6ce404b8f19aaa0d-d7334c26cf6468c191e05ff5e8151da9b67985c66ab177e9446fd14bbafd70df-response.json
- deepgram/client.py
- deepgram/options.py
🔇 Additional comments (2)
tests/unit_test/test_unit_authentication.py (2)
12-62: Well-structured test coverage for header generation.The
TestHeaderGenerationclass provides comprehensive coverage for all authentication header scenarios, including API key ("Token") and access token ("Bearer") formats, as well as edge cases with empty or missing credentials.
289-302: ```shell
#!/bin/bashInspect deepgram/client.py for logger imports and usage
FILE="deepgram/client.py"
echo "1) Checking for verboselogs references:"
rg -n "verboselogs" "$FILE" || echo "No verboselogs references found."echo -e "\n2) Checking for self._logger instantiation:"
rg -n "self._logger" "$FILE" || echo "No self._logger references found."echo -e "\n3) Showing excerpts around init method for DeepgramClient:"
Find the line where the class starts
START_LINE=$(rg -n "class DeepgramClient" --max-count 1 "$FILE" | cut -d: -f1)
Print the next 60 lines after class declaration
if [ -n "$START_LINE" ]; then
sed -n "${START_LINE},$((START_LINE+60))p" "$FILE"
else
echo "Could not locate DeepgramClient class declaration."
fi</details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| This PR review is late, but it looks good. My only question is: What's the intended use case for tokens, and does the implementation (and example) reflect that use case? For example, I'm surprised that creating a new Should the user be applying the |
Proposed changes
This PR adds comprehensive Bearer Token authentication support to the Deepgram Python SDK, enabling developers to use OAuth 2.0-compliant access tokens alongside the existing API key authentication.
Key Features:
Authorization: Token <API_KEY>andAuthorization: Bearer <ACCESS_TOKEN>DEEPGRAM_ACCESS_TOKENalongside existingDEEPGRAM_API_KEYset_access_token()andset_apikey()grant_token()→ Bearer Auth → API calls patternAuthentication Priority Order:
access_tokenparameter (highest)api_keyparameterDEEPGRAM_ACCESS_TOKENenvironment variableDEEPGRAM_API_KEYenvironment variable (lowest)This enables enhanced security workflows where developers can use long-lived API keys to obtain short-lived access tokens (30-second expiration) for improved security, scope limitation, and OAuth 2.0 compliance.
Additional Enhancement:
examples/all.pyscript that auto-discovers and executes all SDK examples for comprehensive testingTypes of changes
What types of changes does your code introduce to the community Python SDK?
Put an
xin the boxes that applyChecklist
Put an
xin the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.Further comments
Implementation Details:
This feature was implemented following SOLID principles with minimal changes to existing code paths. The core changes are concentrated in:
deepgram/options.py: Addedaccess_tokenparameter andset_access_token()method, enhanced_update_headers()logicdeepgram/client.py: Extended constructor to accept and properly handle access tokens with environment fallbacksTesting Strategy:
Example Usage:
The implementation maintains the SDK's clean, intuitive API while providing the flexibility needed for modern authentication workflows. The
examples/auth/bearer_token_demo/main.pydemonstrates the complete practical usage pattern that developers will likely adopt.Summary by CodeRabbit
New Features
Documentation
Bug Fixes
Noneinstead of the string"None"for consistency.Tests
Chores
.gitignoreto exclude test audio artifacts.