From ddf417708b1b4fcb41821a139ad1e54e8ba97208 Mon Sep 17 00:00:00 2001 From: dvonthenen Date: Thu, 9 Nov 2023 10:55:47 -0800 Subject: [PATCH] Implement All Examples for APIs --- README.md | 2 +- deepgram/__init__.py | 4 +- deepgram/clients/abstract_client.py | 21 +- deepgram/clients/listen.py | 3 +- deepgram/clients/manage/v1_client.py | 120 ++++-- deepgram/clients/manage/v1_response.py | 407 ++++++++++++------ deepgram/clients/prerecorded/client.py | 2 +- deepgram/clients/prerecorded/v1_client.py | 4 - deepgram/clients/prerecorded/v1_response.py | 129 +++--- deepgram/errors.py | 22 +- deepgram/options.py | 1 - examples/demo_manage.py | 39 -- examples/manage/balances/main.py | 54 +++ examples/manage/invitations/main.py | 72 ++++ examples/manage/keys/main.py | 94 ++++ examples/manage/members/main.py | 75 ++++ examples/manage/projects/main.py | 94 ++++ examples/manage/scopes/main.py | 94 ++++ examples/manage/usage/main.py | 82 ++++ examples/prerecorded/file/main.py | 46 ++ examples/{ => prerecorded/file}/preamble.wav | Bin .../url/main.py} | 31 +- .../main.py} | 15 +- examples/requirements.txt | 4 - .../{demo_live.py => streaming/http/main.py} | 17 +- requirements-dev.txt => requirements.txt | 10 + 26 files changed, 1082 insertions(+), 360 deletions(-) delete mode 100644 examples/demo_manage.py create mode 100644 examples/manage/balances/main.py create mode 100644 examples/manage/invitations/main.py create mode 100644 examples/manage/keys/main.py create mode 100644 examples/manage/members/main.py create mode 100644 examples/manage/projects/main.py create mode 100644 examples/manage/scopes/main.py create mode 100644 examples/manage/usage/main.py create mode 100644 examples/prerecorded/file/main.py rename examples/{ => prerecorded/file}/preamble.wav (100%) rename examples/{demo_prerecorded.py => prerecorded/url/main.py} (52%) rename examples/{demo_versioning.py => project-repo/main.py} (67%) delete mode 100644 examples/requirements.txt rename examples/{demo_live.py => streaming/http/main.py} (81%) rename requirements-dev.txt => requirements.txt (59%) diff --git a/README.md b/README.md index 6c5e986a..36b5ba27 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ To quickly get started with examples for prerecorded and streaming, run the file Run the following command to install `pytest` and `pytest-cov` as dev dependencies. ``` -pip install -r requirements-dev.txt +pip install -r requirements.txt ``` ## Run All Tests diff --git a/deepgram/__init__.py b/deepgram/__init__.py index ba09e452..878f0a10 100644 --- a/deepgram/__init__.py +++ b/deepgram/__init__.py @@ -8,14 +8,14 @@ # entry point for the deepgram python sdk from .client import DeepgramClient from .options import DeepgramClientOptions -from .errors import DeepgramError, DeepgramApiError, DeepgramUnknownApiError, DeepgramUnknownError +from .errors import DeepgramError, DeepgramApiError, DeepgramUnknownApiError # live from .clients.live.enums import LiveTranscriptionEvents from .clients.live.client import LiveClient, LiveOptions # prerecorded -from .clients.prerecorded.client import PreRecordedClient, PrerecordedOptions +from .clients.prerecorded.client import PreRecordedClient, PrerecordedOptions, PrerecordedSource, FileSource, UrlSource # manage from .clients.manage.client import ManageClient, ProjectOptions, KeyOptions, ScopeOptions, InviteOptions, UsageRequestOptions, UsageSummaryOptions, UsageFieldsOptions diff --git a/deepgram/clients/abstract_client.py b/deepgram/clients/abstract_client.py index 3b21e169..36c39d34 100644 --- a/deepgram/clients/abstract_client.py +++ b/deepgram/clients/abstract_client.py @@ -6,7 +6,7 @@ import json from typing import Dict, Any, Optional -from ..errors import DeepgramApiError, DeepgramUnknownApiError, DeepgramUnknownError +from ..errors import DeepgramApiError, DeepgramUnknownApiError class AbstractRestfulClient: """ @@ -27,9 +27,7 @@ class AbstractRestfulClient: Exceptions: DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. """ - def __init__(self, url: Dict[str, str], headers: Optional[Dict[str, Any]]): self.url = url self.client = httpx.AsyncClient() @@ -60,19 +58,18 @@ async def _handle_request(self, method, url, **kwargs): with httpx.Client() as client: response = client.request(method, url, **kwargs) response.raise_for_status() - return response.json() + return response.text except httpx._exceptions.HTTPError as e: if isinstance(e, httpx.HTTPStatusError): status_code = e.response.status_code or 500 - if is_json(e.response.text): + try: json_object = json.loads(e.response.text) - raise DeepgramApiError(json_object.get( - 'err_msg'), status_code, json.dumps(json_object)) from e - else: - raise DeepgramUnknownApiError( - e.response.text, status_code) from e + raise DeepgramApiError(json_object.get('message'), status_code, json.dumps(json_object)) from e + except json.decoder.JSONDecodeError: + raise DeepgramUnknownApiError(e.response.text, status_code) from e + except ValueError as e: + raise DeepgramUnknownApiError(e.response.text, status_code) from e else: raise except Exception as e: - raise DeepgramUnknownError( - "An unknown error occurred during the request.", e) from e + raise diff --git a/deepgram/clients/listen.py b/deepgram/clients/listen.py index 4d91c771..0b40da70 100644 --- a/deepgram/clients/listen.py +++ b/deepgram/clients/listen.py @@ -6,13 +6,12 @@ from .live.client import LiveClient # FUTURE VERSIONINING:, LiveClientV1 from typing import Dict, Any, Optional - class ListenClient: def __init__(self, url: str, api_key: str, headers: Optional[Dict[str, Any]]): self.url = url self.api_key = api_key self.headers = headers - + @property def prerecorded(self): return PreRecordedClient(self.url, self.headers) diff --git a/deepgram/clients/manage/v1_client.py b/deepgram/clients/manage/v1_client.py index f2f65897..0cef46eb 100644 --- a/deepgram/clients/manage/v1_client.py +++ b/deepgram/clients/manage/v1_client.py @@ -2,7 +2,7 @@ # Use of this source code is governed by a MIT license that can be found in the LICENSE file. # SPDX-License-Identifier: MIT -from .v1_response import Project, ProjectsResponse, Message, ProjectOptionsV1, KeysResponse, Key, KeyOptionsV1, CreateKeyResponse, MembersResponse, ScopesResponse, ScopeOptionsV1, InvitesResponse, InviteOptionsV1, UsageRequestsResponse, UsageRequestOptionsV1, UsageRequest, UsageSummaryOptionsV1, UsageSummaryResponse, UsageFieldsResponse, UsageFieldsOptionsV1, BalancesResponse, Balance +from .v1_response import Project, ProjectsResponse, Message, ProjectOptionsV1, KeysResponse, KeyResponse, KeyOptionsV1, Key, MembersResponse, ScopesResponse, ScopeOptionsV1, InvitesResponse, InviteOptionsV1, UsageRequestsResponse, UsageRequestOptionsV1, UsageRequest, UsageSummaryOptionsV1, UsageSummaryResponse, UsageFieldsResponse, UsageFieldsOptionsV1, BalancesResponse, Balance from ..abstract_client import AbstractRestfulClient @@ -29,7 +29,6 @@ class ManageClientV1(AbstractRestfulClient): Raises: DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. Exception: For any other unexpected exceptions. """ def __init__(self, url, headers): @@ -37,91 +36,120 @@ def __init__(self, url, headers): self.headers = headers self.endpoint = "v1/projects" super().__init__(url, headers) - - async def get_projects(self) -> ProjectsResponse: + + # projects + async def list_projects(self): + return self.get_projects() + async def get_projects(self): url = f"{self.url}/{self.endpoint}" - return await self.get(url) + return ProjectsResponse.from_json(await self.get(url)) - async def get_project(self, project_id: str) -> Project: + async def get_project(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}" - return await self.get(url) + return Project.from_json(await self.get(url)) - async def update_project(self, project_id: str, options: ProjectOptionsV1) -> Message: + async def update_project_option(self, project_id: str, options: ProjectOptionsV1): + url = f"{self.url}/{self.endpoint}/{project_id}" + return Message.from_json(await self.patch(url, json=options)) + async def update_project(self, project_id: str, name=""): url = f"{self.url}/{self.endpoint}/{project_id}" - return await self.patch(url, json=options) + options: ProjectOptionsV1 = { + "name": name, + } + return Message.from_json(await self.patch(url, json=options)) async def delete_project(self, project_id: str) -> None: url = f"{self.url}/{self.endpoint}/{project_id}" - return await self.delete(url) + return Message.from_json(await self.delete(url)) - async def get_project_keys(self, project_id: str) -> KeysResponse: + # keys + async def list_keys(self, project_id: str): + return self.get_keys(project_id) + async def get_keys(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/keys" - return await self.get(url) + result = await self.get(url) + return KeysResponse.from_json(result) - async def get_project_key(self, project_id: str, key_id: str) -> Key: + async def get_key(self, project_id: str, key_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/keys/{key_id}" - return await self.get(url) + return KeyResponse.from_json(await self.get(url)) - async def create_project_key(self, project_id: str, options: KeyOptionsV1) -> CreateKeyResponse: + async def create_key(self, project_id: str, options: KeyOptionsV1): url = f"{self.url}/{self.endpoint}/{project_id}/keys" - return await self.post(url, json=options) + return Key.from_json(await self.post(url, json=options)) - async def delete_project_key(self, project_id: str, key_id: str) -> None: + async def delete_key(self, project_id: str, key_id: str) -> None: url = f"{self.url}/{self.endpoint}/{project_id}/keys/{key_id}" - return await self.delete(url) + return Message.from_json(await self.delete(url)) - async def get_project_members(self, project_id: str) -> MembersResponse: + # members + async def get_members(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/members" - return await self.get(url) + return MembersResponse.from_json(await self.get(url)) - async def remove_project_member(self, project_id: str, member_id: str) -> None: + async def remove_member(self, project_id: str, member_id: str) -> None: url = f"{self.url}/{self.endpoint}/{project_id}/members/{member_id}" - return await self.delete(url) + return Message.from_json(await self.delete(url)) - async def get_project_member_scopes(self, project_id: str, member_id: str) -> ScopesResponse: + # scopes + async def get_member_scopes(self, project_id: str, member_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/members/{member_id}/scopes" - return await self.get(url) + return ScopesResponse.from_json(await self.get(url)) - async def update_project_member_scope(self, project_id: str, member_id: str, options: ScopeOptionsV1) -> Message: + async def update_member_scope(self, project_id: str, member_id: str, options: ScopeOptionsV1): url = f"{self.url}/{self.endpoint}/{project_id}/members/{member_id}/scopes" - return await self.put(url, json=options) + return Message.from_json(await self.put(url, json=options)) - async def get_project_invites(self, project_id: str) -> InvitesResponse: + # invites + async def list_invites(self, project_id: str): + return self.get_invites(project_id) + async def get_invites(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/invites" - return await self.get(url) + return InvitesResponse.from_json(await self.get(url)) - async def send_project_invite(self, project_id: str, options: InviteOptionsV1) -> Message: + async def send_invite_options(self, project_id: str, options: InviteOptionsV1): + url = f"{self.url}/{self.endpoint}/{project_id}/invites" + return Message.from_json(await self.post(url, json=options)) + async def send_invite(self, project_id: str, email: str, scope="member"): url = f"{self.url}/{self.endpoint}/{project_id}/invites" - return await self.post(url, json=options) + options: InviteOptionsV1 = { + "email": email, + "scope": scope, + } + return Message.from_json(await self.post(url, json=options)) - async def delete_project_invite(self, project_id: str, email: str) -> Message: + async def delete_invite(self, project_id: str, email: str): url = f"{self.url}/{self.endpoint}/{project_id}/invites/{email}" - return await self.delete(url) + return Message.from_json(await self.delete(url)) - async def leave_project(self, project_id: str) -> Message: + async def leave_project(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/leave" - return await self.delete(url) + return Message.from_json(await self.delete(url)) - async def get_project_usage_requests(self, project_id: str, options: UsageRequestOptionsV1) -> UsageRequestsResponse: + # usage + async def get_usage_requests(self, project_id: str, options: UsageRequestOptionsV1): url = f"{self.url}/{self.endpoint}/{project_id}/requests" - return await self.get(url, options) + return UsageRequestsResponse.from_json(await self.get(url, options)) - async def get_project_usage_request(self, project_id: str, request_id: str) -> UsageRequest: + async def get_usage_request(self, project_id: str, request_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/requests/{request_id}" - return await self.get(url) + return UsageRequest.from_json(await self.get(url)) - async def get_project_usage_summary(self, project_id: str, options: UsageSummaryOptionsV1) -> UsageSummaryResponse: + async def get_usage_summary(self, project_id: str, options: UsageSummaryOptionsV1): url = f"{self.url}/{self.endpoint}/{project_id}/usage" - return await self.get(url, options) + return UsageSummaryResponse.from_json(await self.get(url, options)) - async def get_project_usage_fields(self, project_id: str, options: UsageFieldsOptionsV1) -> UsageFieldsResponse: + async def get_usage_fields(self, project_id: str, options: UsageFieldsOptionsV1): url = f"{self.url}/{self.endpoint}/{project_id}/usage/fields" - return await self.get(url, options) + return UsageFieldsResponse.from_json(await self.get(url, options)) - async def get_project_balances(self, project_id: str) -> BalancesResponse: + # balances + async def list_balances(self, project_id: str): + return self.get_balances(project_id) + async def get_balances(self, project_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/balances" - return await self.get(url) + return BalancesResponse.from_json(await self.get(url)) - async def get_project_balance(self, project_id: str, balance_id: str) -> Balance: + async def get_balance(self, project_id: str, balance_id: str): url = f"{self.url}/{self.endpoint}/{project_id}/balances/{balance_id}" - return await self.get(url) + return Balance.from_json(await self.get(url)) diff --git a/deepgram/clients/manage/v1_response.py b/deepgram/clients/manage/v1_response.py index 44d15f53..facbf725 100644 --- a/deepgram/clients/manage/v1_response.py +++ b/deepgram/clients/manage/v1_response.py @@ -2,142 +2,249 @@ # Use of this source code is governed by a MIT license that can be found in the LICENSE file. # SPDX-License-Identifier: MIT +from dataclasses import dataclass +from dataclasses_json import dataclass_json from datetime import datetime from typing import TypedDict, List, Optional, Dict -class Message(TypedDict): - message: str +# Result Message -# Projects +@dataclass_json +@dataclass +class Message: + message: Optional[str] -class Project(TypedDict): - project_id: str - name: str + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] -class ProjectsResponse(TypedDict): - projects: List[Project] +# Projects -class ProjectOptionsV1(TypedDict, total=False): +@dataclass_json +@dataclass +class Project: + project_id: Optional[str] name: Optional[str] - company: Optional[str] -# Members + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] -class Member(TypedDict): - email: str - first_name: str - last_name: str - member_id: str - scopes: List[str] - -class MembersResponse(TypedDict): - projects: List[Member] +@dataclass_json +@dataclass +class ProjectsResponse: + projects: Optional[List[Project]] -# Keys + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["projects"] is not None: + _dict["projects"] = [Project.from_dict(project) for project in _dict["projects"]] + _dict["projects"] = [Project.from_dict(project) for project in _dict["projects"]] + return _dict[key] -class ApiKey(TypedDict): - api_key_id: str - comment: Optional[str] - created: datetime - scopes: List[str] - tags: Optional[List[str]] +class ProjectOptionsV1(TypedDict, total=False): + name: Optional[str] -class Key(TypedDict): - api_key: ApiKey - member: Member +# Members -class KeysResponse(TypedDict): - api_keys: List[Key] +@dataclass_json +@dataclass +class Member: + email: Optional[str] + first_name: Optional[str] + last_name: Optional[str] + member_id: Optional[str] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class MembersResponse: + members: Optional[List[Member]] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["members"] is not None: + _dict["members"] = [Member.from_dict(member) for member in _dict["members"]] + return _dict[key] -class CreateKeyResponse(TypedDict): - api_key_id: str - key: str +# Keys +@dataclass_json +@dataclass +class Key: + api_key_id: Optional[str] comment: Optional[str] - created: datetime - scopes: List[str] - tags: Optional[List[str]] + created: Optional[str] + scopes: Optional[List[str]] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class KeyResponse: + api_key: Optional[Key] + member: Optional[Member] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["api_key"] is not None: + _dict["api_key"] = Key.from_dict(_dict["api_key"]) + if _dict["member"] is not None: + _dict["member"] = Member.from_dict(_dict["member"]) + return _dict[key] + +@dataclass_json +@dataclass +class KeysResponse: + api_keys: Optional[List[KeyResponse]] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["api_keys"] is not None: + _dict["api_keys"] = [KeyResponse.from_dict(key) for key in _dict["api_keys"]] + return _dict[key] class KeyOptionsV1(TypedDict): - comment: str - scopes: List[str] + comment: Optional[str] + scopes: Optional[List[str]] tags: Optional[List[str]] time_to_live_in_seconds: Optional[int] expiration_date: Optional[datetime] # Scopes - -class ScopesResponse(TypedDict): +@dataclass_json +@dataclass +class ScopesResponse: scopes: List[str] + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + class ScopeOptionsV1(TypedDict): scope: str # Invites -class Invite(TypedDict): - email: str - scope: str - -class InvitesResponse(TypedDict): - projects: List[Invite] - -class InviteOptionsV1(TypedDict): - email: str - scope: str - +@dataclass_json +@dataclass +class Invite: + email: Optional[str] + scope: Optional[str] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class InvitesResponse: + invites: List[Invite] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["invites"] is not None: + _dict["invites"] = [Invite.from_dict(invite) for invite in _dict["invites"]] + return _dict[key] + +class InviteOptionsV1: + email: Optional[str] + scope: Optional[str] + # Usage - -class Config(TypedDict, total=False): - alternatives: Optional[int] - callback: Optional[str] - diarize: Optional[bool] - keywords: Optional[List[str]] - language: Optional[str] - model: Optional[str] - multichannel: Optional[bool] - ner: Optional[bool] - numerals: Optional[bool] - profanity_filter: Optional[bool] - punctuate: Optional[bool] - redact: Optional[List[str]] - search: Optional[List[str]] - utterances: Optional[bool] - -class Details(TypedDict, total=False): +@dataclass_json +@dataclass +class Config: + # diarize: Optional[bool] + # language: Optional[str] + # model: Optional[str] + # punctuate: Optional[bool] + # utterances: Optional[bool] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class Details: usd: Optional[float] duration: Optional[float] total_audio: Optional[float] - channels: Optional[float] - streams: Optional[float] + channels: Optional[int] + streams: Optional[int] models: List[str] method: Optional[str] tags: Optional[List[str]] features: Optional[List[str]] - config: Config + config: Optional[Config] -class Callback(TypedDict): + def __getitem__(self, key): + _dict = self.to_dict() + # if _dict["config"] is not None: + # _dict["config"] = Config.from_dict(_dict["config"]) + return _dict[key] + +@dataclass_json +@dataclass +class Callback: attempts: Optional[int] code: Optional[int] completed: Optional[str] -class Response(TypedDict, total=False): - details: Details + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class Response: + details: Optional[Details] code: Optional[int] completed: Optional[str] -class UsageRequest(TypedDict): - request_id: str - created: str - path: str - api_key_id: str - response: Response - callback: Optional[Callback] - -class UsageRequestsResponse(TypedDict): - page: int - limit: int + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["details"] is not None: + _dict["details"] = Details.from_dict(_dict["details"]) + return _dict[key] + +@dataclass_json +@dataclass +class UsageRequest: + request_id: Optional[str] + created: Optional[str] + path: Optional[str] + # accessor: Optional[str] + api_key_id: Optional[str] + response: Optional[Response] + # callback: Optional[Callback] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["response"] is not None: + _dict["response"] = Response.from_dict(_dict["response"]) + # if _dict["callback"] is not None: + # _dict["callback"] = Callback.from_dict(_dict["callback"]) + return _dict[key] + +@dataclass_json +@dataclass +class UsageRequestsResponse: + page: Optional[int] + limit: Optional[int] requests: List[UsageRequest] + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["requests"] is not None: + _dict["requests"] = [UsageRequest.from_dict(request) for request in _dict["requests"]] + return _dict[key] + class UsageRequestOptionsV1(TypedDict): start: Optional[str] end: Optional[str] @@ -167,35 +274,71 @@ class UsageSummaryOptionsV1(TypedDict): numerals: Optional[bool] smart_format: Optional[bool] -class UsageSummary(TypedDict): - start: str - end: str - hours: int - total_hours: int - requests: int - -class Resolution(TypedDict): - units: str - amount: int - -class UsageSummaryResponse(TypedDict): - start: str - end: str - resolution: Resolution - results: List[UsageSummary] - -class UsageModel(TypedDict): - name: str - language: str - version: str - model_id: str - -class UsageFieldsResponse(TypedDict): - tags: List[str] - models: List[UsageModel] - processing_methods: List[str] - languages: List[str] - features: List[str] +@dataclass_json +@dataclass +class Results: + start: Optional[str] + end: Optional[str] + hours: Optional[int] + total_hours: Optional[int] + requests: Optional[int] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class Resolution: + units: Optional[str] + amount: Optional[int] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class UsageSummaryResponse: + start: Optional[str] + end: Optional[str] + resolution: Optional[Resolution] + results: Optional[List[Results]] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["resolution"] is not None: + _dict["resolution"] = Resolution.from_dict(_dict["resolution"]) + if _dict["results"] is not None: + _dict["results"] = [Results.from_dict(result) for result in _dict["results"]] + return _dict[key] + +@dataclass_json +@dataclass +class UsageModel: + name: Optional[str] + language: Optional[str] + version: Optional[str] + model_id: Optional[str] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class UsageFieldsResponse: + tags: Optional[List[str]] + models: Optional[List[UsageModel]] + processing_methods: Optional[List[str]] + # languages: Optional[List[str]] + features: Optional[List[str]] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["models"] is not None: + _dict["models"] = [UsageModel.from_dict(model) for model in _dict["models"]] + return _dict[key] class UsageFieldsOptionsV1(TypedDict): start: Optional[str] @@ -203,11 +346,25 @@ class UsageFieldsOptionsV1(TypedDict): # Billing -class Balance(TypedDict): - balance_id: str - amount: int - units: str - purchase: str - -class BalancesResponse(TypedDict): - balances: List[Balance] \ No newline at end of file +@dataclass_json +@dataclass +class Balance: + balance_id: Optional[str] + amount: Optional[str] + units: Optional[str] + purchase_order_id: Optional[str] + + def __getitem__(self, key): + _dict = self.to_dict() + return _dict[key] + +@dataclass_json +@dataclass +class BalancesResponse: + balances: Optional[List[Balance]] + + def __getitem__(self, key): + _dict = self.to_dict() + if _dict["balances"] is not None: + _dict["balances"] = [Balance.from_dict(balance) for balance in _dict["balances"]] + return _dict[key] \ No newline at end of file diff --git a/deepgram/clients/prerecorded/client.py b/deepgram/clients/prerecorded/client.py index 2061e444..898661f9 100644 --- a/deepgram/clients/prerecorded/client.py +++ b/deepgram/clients/prerecorded/client.py @@ -6,6 +6,7 @@ from .v1_client import PreRecordedClientV1 from .v1_options import PrerecordedOptionsV1 +from .source import PrerecordedSource, FileSource, UrlSource ''' The client.py points to the current supported version in the SDK. @@ -18,7 +19,6 @@ class PreRecordedClient(PreRecordedClientV1): """ Please see PreRecordedClientV1 for details """ - def __init__(self, url, headers): self.url = url self.headers = headers diff --git a/deepgram/clients/prerecorded/v1_client.py b/deepgram/clients/prerecorded/v1_client.py index 9bf44665..8f585150 100644 --- a/deepgram/clients/prerecorded/v1_client.py +++ b/deepgram/clients/prerecorded/v1_client.py @@ -44,7 +44,6 @@ async def transcribe_url( DeepgramError: If the "callback" option is provided for a synchronous transcription. DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. Exception: For any other unexpected exceptions. """ @@ -74,7 +73,6 @@ async def transcribe_url_callback( self, source: UrlSource, callback:str, option DeepgramError: If the "callback" option is provided for a synchronous transcription. DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. Exception: For any other unexpected exceptions. """ url = f"{self.url}/{endpoint}" @@ -104,7 +102,6 @@ async def transcribe_file(self, source: FileSource, options: PrerecordedOptionsV DeepgramError: If the "callback" option is provided for a synchronous transcription. DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. Exception: For any other unexpected exceptions. """ @@ -134,7 +131,6 @@ async def transcribe_file_callback(self, source: FileSource, callback:str, optio DeepgramError: If the "callback" option is provided for a synchronous transcription. DeepgramApiError: Raised for known API errors. DeepgramUnknownApiError: Raised for unknown API errors. - DeepgramUnknownError: Raised for unexpected errors not specific to the API. Exception: For any other unexpected exceptions. """ diff --git a/deepgram/clients/prerecorded/v1_response.py b/deepgram/clients/prerecorded/v1_response.py index 98335f37..add52139 100644 --- a/deepgram/clients/prerecorded/v1_response.py +++ b/deepgram/clients/prerecorded/v1_response.py @@ -12,105 +12,110 @@ class AsyncPrerecordedResponseV1(TypedDict): # Sync Prerecorded Response Types: class Metadata(TypedDict): - transaction_key: str - request_id: str - sha256: str - created: str - duration: float - channels: int - models: List[str] - model_info: Dict[str, 'ModelInfo'] + transaction_key: Optional[str] + request_id: Optional[str] + sha256: Optional[str] + created: Optional[str] + duration: Optional[float] + channels: Optional[int] + models: Optional[List[str]] + model_info: Optional[Dict[str, 'ModelInfo']] + summary_info: Optional[Dict[str, 'SummaryV2']] warnings: Optional[List['Warning']] class ModelInfo(TypedDict): - name: str - version: str - arch: str + name: Optional[str] + version: Optional[str] + arch: Optional[str] class SummaryV2(TypedDict): summary: Optional[str] start_word: Optional[float] end_word: Optional[float] +class Summaries(SummaryV2): # internal reference to old name + pass class SummaryV1(TypedDict): - result: str - short: str + result: Optional[str] + short: Optional[str] +class Summary(SummaryV1): # internal reference to old name + pass class Hit(TypedDict): - confidence: float - start: float - end: float - snippet: str + confidence: Optional[float] + start: Optional[float] + end: Optional[float] + snippet: Optional[str] class Word(TypedDict): - word: str - start: float - end: float - confidence: float + word: Optional[str] + start: Optional[float] + end: Optional[float] + confidence: Optional[float] punctuated_word: Optional[str] speaker: Optional[int] speaker_confidence: Optional[float] class Sentence(TypedDict): - text: str - start: float - end: float + text: Optional[str] + start: Optional[float] + end: Optional[float] class Paragraph(TypedDict): - sentences: List[Sentence] - start: float - end: float - num_words: float + sentences: Optional[List[Sentence]] + start: Optional[float] + end: Optional[float] + num_words: Optional[float] speaker: Optional[int] class Paragraphs(TypedDict): - transcript: str - paragraphs: List[Paragraph] + transcript: Optional[str] + paragraphs: Optional[List[Paragraph]] class Topic(TypedDict): - topic: str - confidence: float + topic: Optional[str] + confidence: Optional[float] class Topics(TypedDict): - topics: List[Topic] - text: str - start_word: float - end_word: float + topics: Optional[List[Topic]] + text: Optional[str] + start_word: Optional[float] + end_word: Optional[float] class Translation(TypedDict): - language: str - translation: str + language: Optional[str] + translation: Optional[str] class Warning(TypedDict): - parameter: str - type: str - message: str + parameter: Optional[str] + type: Optional[str] + message: Optional[str] class Search(TypedDict): - query: str - hits: List[Hit] + query: Optional[str] + hits: Optional[List[Hit]] class Utterance(TypedDict): - start: float - end: float - confidence: float - channel: int - transcript: str - words: List[Word] + start: Optional[float] + end: Optional[float] + confidence: Optional[float] + channel: Optional[int] + transcript: Optional[str] + words: Optional[List[Word]] speaker: Optional[int] - id: str + id: Optional[str] class Entity(TypedDict): - label: str - value: str - confidence: float - start_word: float - end_word: float + label: Optional[str] + value: Optional[str] + confidence: Optional[float] + start_word: Optional[float] + end_word: Optional[float] class Alternative(TypedDict): - transcript: str - confidence: float - words: List[Word] + transcript: Optional[str] + confidence: Optional[float] + words: Optional[List[Word]] summaries: Optional[List[SummaryV2]] paragraphs: Optional[Paragraphs] entities: Optional[List[Entity]] @@ -119,14 +124,14 @@ class Alternative(TypedDict): class Channel(TypedDict): search: Optional[List[Search]] - alternatives: List[Alternative] + alternatives: Optional[List[Alternative]] detected_language: Optional[str] class Result(TypedDict): - channels: List[Channel] + channels: Optional[List[Channel]] utterances: Optional[List[Utterance]] summary: Optional[SummaryV1] class SyncPrerecordedResponseV1(TypedDict): - metadata: Metadata - results: Result + metadata: Optional[Metadata] + results: Optional[Result] diff --git a/deepgram/errors.py b/deepgram/errors.py index 8762781b..89463dea 100644 --- a/deepgram/errors.py +++ b/deepgram/errors.py @@ -13,7 +13,7 @@ def __init__(self, message: str): super().__init__(message) self.name = "DeepgramError" -class DeepgramApiError(DeepgramError): +class DeepgramApiError(Exception): """ Exception raised for known errors (in json response format) related to the Deepgram API. @@ -29,9 +29,9 @@ def __init__(self, message: str, status: str, original_error = None): self.original_error = original_error def __str__(self): - return f"{self.name}: {self.message} (Status: {self.status}) \n Error: {self.original_error}" + return f"{self.name}: {self.message} (Status: {self.status})" -class DeepgramUnknownApiError(DeepgramApiError): +class DeepgramUnknownApiError(Exception): """ Exception raised for unknown errors related to the Deepgram API. @@ -44,16 +44,8 @@ class DeepgramUnknownApiError(DeepgramApiError): def __init__(self, message: str, status: str): super().__init__(message, status) self.name = "DeepgramUnknownApiError" + self.status = status + self.message = message -class DeepgramUnknownError(DeepgramError): - """ - Exception raised for unknown errors not specific to the Deepgram API. - - Attributes: - message (str): The error message describing the exception. - original_error (Exception): The original error that triggered this exception. - """ - def __init__(self, message: str, original_error): - super().__init__(message) - self.name = "DeepgramUnknownError" - self.original_error = original_error + def __str__(self): + return f"{self.name}: {self.message} (Status: {self.status})" \ No newline at end of file diff --git a/deepgram/options.py b/deepgram/options.py index 70d51c50..ae13cc99 100644 --- a/deepgram/options.py +++ b/deepgram/options.py @@ -21,7 +21,6 @@ def __init__(self, api_key): self.global_options = { "headers": { "Accept": "application/json", - "Content-Type": "application/json", "Authorization": f"Token {self.api_key}" }, "url": "api.deepgram.com" diff --git a/examples/demo_manage.py b/examples/demo_manage.py deleted file mode 100644 index a0e7dcad..00000000 --- a/examples/demo_manage.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. -# Use of this source code is governed by a MIT license that can be found in the LICENSE file. -# SPDX-License-Identifier: MIT - -import asyncio -import os -from dotenv import load_dotenv - -from deepgram import DeepgramClient - -load_dotenv() - -API_KEY = os.getenv('DG_API_KEY_MANAGE') -PROJECT_ID = os.getenv('DG_PROJECT_ID') -UPDATE_PROJECT_OPTIONS = { - "name": "example_project_name", - "company": "deepgram" -} -CREATE_KEY_OPTIONS = { - "comment": "this is a comment", # requred - "scopes": ["keys:read", "owners:read"], - "tags": ["my_name", "sdk_test"], - "testkey": "test value", - "time_to_live_in_seconds": 60000, -} - -# Create a Deepgram client using the API key -deepgram: DeepgramClient = DeepgramClient(API_KEY) - -async def main(): - response = await deepgram.manage.get_projects() - # response = await deepgram.manage.get_project(PROJECT_ID) - # response = await deepgram.manage.update_project(PROJECT_ID, UPDATE_PROJECT_OPTIONS) - # response = await deepgram.manage.create_project_key(PROJECT_ID, CREATE_KEY_OPTIONS) - - print(response) - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/manage/balances/main.py b/examples/manage/balances/main.py new file mode 100644 index 00000000..e80efe5e --- /dev/null +++ b/examples/manage/balances/main.py @@ -0,0 +1,54 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + break + + # list balances + listResp = await deepgram.manage.get_balances(myId) + if listResp is None: + print(f"ListBalances failed.") + sys.exit(1) + + myBalanceId = None + for balance in listResp.balances: + myBalanceId = balance.balance_id + print(f"GetBalance() - Name: {balance.balance_id}, Amount: {balance.amount}") + + # get balance + getResp = await deepgram.manage.get_balance(myId, myBalanceId) + print(f"GetBalance() - Name: {getResp.balance_id}, Amount: {getResp.amount}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/invitations/main.py b/examples/manage/invitations/main.py new file mode 100644 index 00000000..36bb833a --- /dev/null +++ b/examples/manage/invitations/main.py @@ -0,0 +1,72 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, InviteOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + break + + # list invites + listResp = await deepgram.manage.get_invites(myId) + if listResp is None: + print("No invites found") + else: + for invite in listResp.invites: + print(f"GetInvites() - Name: {invite.email}, Amount: {invite.scope}") + + # send invite + options: InviteOptions = { + "email": "spam@spam.com", + "scope": "member" + } + + getResp = await deepgram.manage.send_invite_options(myId, options) + print(f"SendInvite() - Msg: {getResp.message}") + + # list invites + listResp = await deepgram.manage.get_invites(myId) + if listResp is None: + print("No invites found") + else: + for invite in listResp.invites: + print(f"GetInvites() - Name: {invite.email}, Amount: {invite.scope}") + + # delete invite + delResp = await deepgram.manage.delete_invite(myId, "spam@spam.com") + print(f"DeleteInvite() - Msg: {delResp.message}") + + # # leave invite + # delResp = await deepgram.manage.leave_project(myId) + # print(f"LeaveProject() - Msg: {delResp.message}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/keys/main.py b/examples/manage/keys/main.py new file mode 100644 index 00000000..3eeff3ff --- /dev/null +++ b/examples/manage/keys/main.py @@ -0,0 +1,94 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, KeyOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + break + + # list keys + listResp = await deepgram.manage.get_keys(myId) + if listResp is None: + print("No keys found") + else: + for key in listResp.api_keys: + print(f"GetKeys() - ID: {key.api_key.api_key_id}, Member: {key.member.email}, Comment: {key.api_key.comment}, Scope: {key.api_key.scopes}") + + # create key + options: KeyOptions = { + "comment": "MyTestKey", + "scopes": ["member"] + } + + myKeyId = None + createResp = await deepgram.manage.create_key(myId, options) + if createResp is None: + print(f"CreateKey failed.") + sys.exit(1) + else: + myKeyId = createResp.api_key_id + print(f"CreateKey() - ID: {myKeyId}, Comment: {createResp.comment} Scope: {createResp.scopes}") + + # list keys + listResp = await deepgram.manage.get_keys(myId) + if listResp is None: + print("No keys found") + else: + for key in listResp.api_keys: + print(f"GetKeys() - ID: {key.api_key.api_key_id}, Member: {key.member.email}, Comment: {key.api_key.comment}, Scope: {key.api_key.scopes}") + + # get key + getResp = await deepgram.manage.get_key(myId, myKeyId) + if getResp is None: + print(f"GetKey failed.") + sys.exit(1) + else: + print(f"GetKey() - ID: {key.api_key.api_key_id}, Member: {key.member.email}, Comment: {key.api_key.comment}, Scope: {key.api_key.scopes}") + + # delete key + deleteResp = await deepgram.manage.delete_key(myId, myKeyId) + if deleteResp is None: + print(f"DeleteKey failed.") + sys.exit(1) + else: + print(f"DeleteKey() - Msg: {deleteResp.message}") + + # list keys + listResp = await deepgram.manage.get_keys(myId) + if listResp is None: + print("No keys found") + else: + for key in listResp.api_keys: + print(f"GetKeys() - ID: {key.api_key.api_key_id}, Member: {key.member.email}, Comment: {key.api_key.comment}, Scope: {key.api_key.scopes}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/members/main.py b/examples/manage/members/main.py new file mode 100644 index 00000000..442a97de --- /dev/null +++ b/examples/manage/members/main.py @@ -0,0 +1,75 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, KeyOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") +DELETE_MEMBER_BY_EMAIL = "enter-your-email@gmail.com" + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + + # list members + delMemberId = None + listResp = await deepgram.manage.get_members(myId) + if listResp is None: + print("No members found") + else: + for member in listResp.members: + if member.email == DELETE_MEMBER_BY_EMAIL: + delMemberId = member.member_id + print(f"GetMembers() - ID: {member.member_id}, Email: {member.email}") + + # delete member + if delMemberId == None: + print("") + print("This example requires a project who already exists who name is in \"DELETE_MEMBER_BY_EMAIL\".") + print("This is required to exercise the RemoveMember function.") + print("In the absence of this, this example will exit early.") + print("") + sys.exit(1) + + deleteResp = await deepgram.manage.remove_member(myId, delMemberId) + if deleteResp is None: + print(f"RemoveMember failed.") + sys.exit(1) + else: + print(f"RemoveMember() - Msg: {deleteResp.message}") + + # list members + delMemberId = None + listResp = await deepgram.manage.get_members(myId) + if listResp is None: + print("No members found") + else: + for member in listResp.members: + print(f"GetMembers() - ID: {member.member_id}, Email: {member.email}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/projects/main.py b/examples/manage/projects/main.py new file mode 100644 index 00000000..a26e4c40 --- /dev/null +++ b/examples/manage/projects/main.py @@ -0,0 +1,94 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, ProjectOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") +DELETE_PROJECT_BY_NAME = os.getenv("DG_DELETE_PROJECT_BY_NAME") + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + listResp = await deepgram.manage.get_projects() + if listResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + myDeleteId = None + for project in listResp.projects: + if project.name == DELETE_PROJECT_BY_NAME: + myDeleteId = project.project_id + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + + + # get project + getResp = await deepgram.manage.get_project(myId) + print(f"GetProject() - Name: {getResp.name}") + + # update project + updateOptions: ProjectOptions = { + "name": "My TEST RENAME Example", + } + + updateResp = await deepgram.manage.update_project_option(myId, updateOptions) + if updateResp is None: + print(f"UpdateProject failed.") + sys.exit(1) + print(f"UpdateProject() - Msg: {updateResp.message}") + + # get project + getResp = await deepgram.manage.get_project(myId) + if getResp is None: + print(f"GetProject failed.") + sys.exit(1) + print(f"GetProject() - Name: {getResp.name}") + + # update project + updateResp = await deepgram.manage.update_project(myId, name=myName) + if updateResp is None: + print(f"UpdateProject failed.") + sys.exit(1) + print(f"UpdateProject() - Msg: {updateResp.message}") + + # get project + getResp = await deepgram.manage.get_project(myId) + if getResp is None: + print(f"GetProject failed.") + sys.exit(1) + print(f"GetProject() - Name: {getResp.name}") + + # delete project + if myDeleteId == None: + print("") + print("This example requires a project who already exists who name is in the value \"DELETE_PROJECT_ID\".") + print("This is required to exercise the UpdateProject and DeleteProject function.") + print("In the absence of this, this example will exit early.") + print("") + sys.exit(1) + + respDelete = deepgram.manage.delete_project(myDeleteId) + if respDelete is None: + print(f"DeleteProject failed.") + sys.exit(1) + print(f"DeleteProject() - Msg: {respDelete.message}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/scopes/main.py b/examples/manage/scopes/main.py new file mode 100644 index 00000000..2f1e76cc --- /dev/null +++ b/examples/manage/scopes/main.py @@ -0,0 +1,94 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, ScopeOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") +MEMBER_BY_EMAIL = "enter-your-email@gmail.com" + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + break + + # list members + memberId = None + listResp = await deepgram.manage.get_members(myId) + if listResp is None: + print("No members found") + else: + for member in listResp.members: + if member.email == MEMBER_BY_EMAIL: + memberId = member.member_id + print(f"GetMembers() - ID: {member.member_id}, Email: {member.email}") + + if memberId == None: + print("This example requires a member who is already a member with email in the value of \"MEMBER_BY_EMAIL\".") + print("This is required to exercise the UpdateMemberScope function.") + print("In the absence of this, this example will exit early.") + sys.exit(1) + + # get member scope + memberResp = await deepgram.manage.get_member_scopes(myId, memberId) + if memberResp is None: + print("No scopes found") + sys.exit(1) + print(f"GetMemberScope() - ID: {myId}, Email: {memberId}, Scope: {memberResp.scopes}") + + # update scope + options: ScopeOptions = { + "scope": "admin" + } + + updateResp = await deepgram.manage.update_member_scope(myId, memberId, options) + print(f"UpdateMemberScope() - Msg: {updateResp.message}") + + # get member scope + memberResp = await deepgram.manage.get_member_scopes(myId, memberId) + if memberResp is None: + print("No scopes found") + sys.exit(1) + print(f"GetMemberScope() - ID: {myId}, Email: {memberId}, Scope: {memberResp.scopes}") + + # update scope + options: ScopeOptions = { + "scope": "member" + } + + updateResp = await deepgram.manage.update_member_scope(myId, memberId, options) + print(f"UpdateMemberScope() - Msg: {updateResp.message}") + + # get member scope + memberResp = await deepgram.manage.get_member_scopes(myId, memberId) + if memberResp is None: + print("No scopes found") + sys.exit(1) + print(f"GetMemberScope() - ID: {myId}, Email: {memberId}, Scope: {memberResp.scopes}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/manage/usage/main.py b/examples/manage/usage/main.py new file mode 100644 index 00000000..c961a51d --- /dev/null +++ b/examples/manage/usage/main.py @@ -0,0 +1,82 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +import sys +from dotenv import load_dotenv + +from deepgram import DeepgramClient, UsageFieldsOptions, UsageSummaryOptions, UsageRequestOptions + +load_dotenv() + +# environment variables +API_KEY = os.getenv("DG_API_KEY") + +# Create a Deepgram client using the API key +deepgram: DeepgramClient = DeepgramClient(API_KEY) + +async def main(): + try: + # get projects + projectResp = await deepgram.manage.get_projects() + if projectResp is None: + print(f"ListProjects failed.") + sys.exit(1) + + myId = None + myName = None + for project in projectResp.projects: + myId = project.project_id + myName = project.name + print(f"ListProjects() - ID: {myId}, Name: {myName}") + + # list requests + requestId = None + options: UsageRequestOptions = {} + listResp = await deepgram.manage.get_usage_requests(myId, options) + if listResp is None: + print("No requests found") + else: + for request in listResp.requests: + requestId = request.request_id + print(f"GetUsageRequests() - ID: {requestId}, Path: {request.path}") + print(f"request_id: {requestId}") + print("") + + # get request + reqResp = await deepgram.manage.get_usage_request(myId, requestId) + if reqResp is None: + print("No request found") + else: + for request in listResp.requests: + print(f"GetUsageRequest() - ID: {request.request_id}, Path: {request.path}") + print("") + + # get fields + options: UsageFieldsOptions = {} + listResp = await deepgram.manage.get_usage_fields(myId, options) + if listResp is None: + print(f"UsageFields not found.") + sys.exit(1) + else: + for model in listResp.models: + print(f"GetUsageFields Models - ID: {model.model_id}, Name: {model.name}") + for method in listResp.processing_methods: + print(f"GetUsageFields Methods: {method}") + print("") + + # list members + options: UsageSummaryOptions = {} + listResp = await deepgram.manage.get_usage_summary(myId, options) + if listResp is None: + print("UsageSummary not found") + else: + for item in listResp.results: + print(f"GetSummary - {item.requests} Calls/{listResp.resolution.units}") + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/prerecorded/file/main.py b/examples/prerecorded/file/main.py new file mode 100644 index 00000000..ee88898f --- /dev/null +++ b/examples/prerecorded/file/main.py @@ -0,0 +1,46 @@ +# Copyright 2023 Deepgram SDK contributors. All Rights Reserved. +# Use of this source code is governed by a MIT license that can be found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import asyncio +import os +from dotenv import load_dotenv + +from deepgram import DeepgramClient, PrerecordedOptions, FileSource + +load_dotenv() + +API_KEY = os.getenv('DG_API_KEY') +AUDIO_FILE = "preamble.wav" + +options: PrerecordedOptions = { + "model": "nova", + "smart_format": "true", + "summarize": "v2", +} + +# STEP 1 Create a Deepgram client using the API key (optional - add config options) +deepgram = DeepgramClient(API_KEY) + +# STEP 2 Call the transcribe_file method on the prerecorded class +async def transcribe_file(): + # Logic to read the file + with open(AUDIO_FILE, 'rb') as file: + buffer_data = file.read() + + payload: FileSource = { + "buffer": buffer_data, + } + + file_response = await deepgram.listen.prerecorded.transcribe_file(payload, options) + return file_response + +async def main(): + try: + response = await transcribe_file() + print(response) + except Exception as e: + print(f"Exception: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/preamble.wav b/examples/prerecorded/file/preamble.wav similarity index 100% rename from examples/preamble.wav rename to examples/prerecorded/file/preamble.wav diff --git a/examples/demo_prerecorded.py b/examples/prerecorded/url/main.py similarity index 52% rename from examples/demo_prerecorded.py rename to examples/prerecorded/url/main.py index a2c90b6d..31758bbe 100644 --- a/examples/demo_prerecorded.py +++ b/examples/prerecorded/url/main.py @@ -11,9 +11,7 @@ load_dotenv() API_KEY = os.getenv('DG_API_KEY') -AUDIO_FILE = "preamble.wav" AUDIO_URL = {"url":"https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav"} -CALLBACK = "https://example.com/callback" options: PrerecordedOptions = { "model": "nova", @@ -24,33 +22,18 @@ # STEP 1 Create a Deepgram client using the API key (optional - add config options) deepgram = DeepgramClient(API_KEY) -###### TRANSCRIBE A LOCAL FILE ##### -async def transcribe_file(): - # Logic to read the file - with open(AUDIO_FILE, 'rb') as file: - buffer_data = file.read() - - PAYLOAD = { - "buffer": buffer_data, - } - - # STEP 2 Call the transcribe_file method on the prerecorded class - file_response = await deepgram.listen.prerecorded.transcribe_file(PAYLOAD, options) - return file_response - - -###### TRANSCRIBE A HOSTED FILE ##### +# STEP 2 Call the transcribe_url method on the prerecorded class async def transcribe_url(): - # STEP 2 Call the transcribe_url method on the prerecorded class url_response = await deepgram.listen.prerecorded.transcribe_url(AUDIO_URL, options) - # url_response = await deepgram.listen.prerecorded.transcribe_url_callback(AUDIO_URL,CALLBACK, options) return url_response async def main(): - # response = await transcribe_file() - response = await transcribe_url() - print(response) - + try: + response = await transcribe_url() + print(response) + except Exception as e: + print(f"Exception: {e}") + if __name__ == "__main__": asyncio.run(main()) diff --git a/examples/demo_versioning.py b/examples/project-repo/main.py similarity index 67% rename from examples/demo_versioning.py rename to examples/project-repo/main.py index ee1c209d..cd8d9cd3 100644 --- a/examples/demo_versioning.py +++ b/examples/project-repo/main.py @@ -17,12 +17,15 @@ deepgram: DeepgramClient = DeepgramClient(API_KEY) async def main(): - response = await deepgram.manage.get_projects() - print(response) - -# FUTURE VERSIONINING: -# response = await deepgram.manage_v1.get_projects() -# print(response) + try: + response = await deepgram.manage.get_projects() + print(response) + + # FUTURE VERSIONINING: + # response = await deepgram.manage_v1.get_projects() + # print(response) + except Exception as e: + print(f"Exception: {e}") if __name__ == "__main__": asyncio.run(main()) \ No newline at end of file diff --git a/examples/requirements.txt b/examples/requirements.txt deleted file mode 100644 index c8de68fb..00000000 --- a/examples/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ --e ../ -httpx -typing_extensions -python-dotenv \ No newline at end of file diff --git a/examples/demo_live.py b/examples/streaming/http/main.py similarity index 81% rename from examples/demo_live.py rename to examples/streaming/http/main.py index 9bff4fe3..3297de06 100644 --- a/examples/demo_live.py +++ b/examples/streaming/http/main.py @@ -2,30 +2,15 @@ # Use of this source code is governed by a MIT license that can be found in the LICENSE file. # SPDX-License-Identifier: MIT -from dotenv import load_dotenv import asyncio import aiohttp import os +from dotenv import load_dotenv from deepgram import DeepgramClient, LiveTranscriptionEvents, LiveOptions load_dotenv() -base_url = "api.beta.deepgram.com" # will change to https://api.beta.deepgram.com -beta_url = "https://api.beta.deepgram.com" # will stay as to https://api.beta.deepgram.com -testing_url = "http://localhost:8080" # will stay as http://api.deepgram.com - -config_headers = { - "header_key": "header value", -} - -config_options = { - "global_options" : { - "url": beta_url, - "headers": config_headers - } - } - options: LiveOptions = { 'model': 'nova', 'interim_results': False, diff --git a/requirements-dev.txt b/requirements.txt similarity index 59% rename from requirements-dev.txt rename to requirements.txt index 7a360ab6..76c908ce 100644 --- a/requirements-dev.txt +++ b/requirements.txt @@ -1,5 +1,15 @@ # pip install -r requirements-dev.txt +# standard libs +httpx +dataclasses-json +dataclasses +typing_extensions +python-dotenv + +# streaming libs +pyaudio + # Async functionality, likely to be already installed asyncio aiohttp