Skip to content

Commit

Permalink
DOCS-298: Update Rev AI python sdk to support different base url (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
jennywong2129 authored Oct 25, 2024
1 parent d1ddb4a commit b171899
Show file tree
Hide file tree
Showing 16 changed files with 128 additions and 35 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ your [AccessToken Settings Page](https://www.rev.ai/access_token). Create a clie
generated Access Token:

```python
from rev_ai import apiclient
from rev_ai import apiclient, RevAiApiDeploymentConfigMap, RevAiApiDeployment

# create your client
client = apiclient.RevAiAPIClient("ACCESS TOKEN")
# optionally configure the Rev AI deployment to use
client = apiclient.RevAiAPIClient("ACCESS TOKEN", url=RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url'])
```

### Sending a file
Expand Down Expand Up @@ -211,18 +212,20 @@ In order to stream audio, you will need to setup a streaming client and a media

```python
from rev_ai.streamingclient import RevAiStreamingClient
from rev_ai.models import MediaConfig
from rev_ai.models import MediaConfig, RevAiApiDeploymentConfigMap, RevAiApiDeployment

#on_error(error)
#on_close(code, reason)
#on_connected(id)

# optionally configure the Rev AI deployment to use
config = MediaConfig()
streaming_client = RevAiStreamingClient("ACCESS TOKEN",
config,
on_error=ERRORFUNC,
on_close=CLOSEFUNC,
on_connected=CONNECTEDFUNC)
on_connected=CONNECTEDFUNC,
url=RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_websocket_url'])
```

`on_error`, `on_close`, and `on_connected` are optional parameters that are functions to be called when the websocket errors, closes, and connects respectively. The default `on_error` raises the error, `on_close` prints out the code and reason for closing, and `on_connected` prints out the job ID.
Expand Down
3 changes: 2 additions & 1 deletion src/rev_ai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
from .models import Job, JobStatus, Account, Transcript, Monologue, Element, MediaConfig, \
CaptionType, CustomVocabulary, TopicExtractionJob, TopicExtractionResult, Topic, Informant, \
SpeakerName, LanguageIdentificationJob, LanguageIdentificationResult, LanguageConfidence, \
SentimentAnalysisResult, SentimentValue, SentimentMessage, SentimentAnalysisJob, CustomerUrlData
SentimentAnalysisResult, SentimentValue, SentimentMessage, SentimentAnalysisJob, \
CustomerUrlData, RevAiApiDeploymentConfigMap, RevAiApiDeployment
14 changes: 10 additions & 4 deletions src/rev_ai/apiclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from . import utils
from .baseclient import BaseClient
from .models import Account, CaptionType, Job, Transcript
from .models import Account, CaptionType, Job, Transcript, RevAiApiDeploymentConfigMap, \
RevAiApiDeployment
from .models.asynchronous.summarization_options import SummarizationOptions
from .models.asynchronous.summary import Summary
from .models.asynchronous.translation_options import TranslationOptions
Expand All @@ -30,20 +31,25 @@ class RevAiAPIClient(BaseClient):
# Default version of Rev AI
version = 'v1'

# Default base url for Rev AI
base_url = 'https://api.rev.ai/speechtotext/{}/'.format(version)
# Default url for US Rev AI deployment
default_url = RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']

# Rev AI transcript format
rev_json_content_type = 'application/vnd.rev.transcript.v1.0+json'

def __init__(self, access_token):
def __init__(self, access_token: str, url: str = None):
"""Constructor
:param access_token: access token which authorizes all requests and links them to your
account. Generated on the settings page of your account dashboard
on Rev AI.
:param url (optional): url of the Rev AI API deployment to use, defaults to the US
deployement, i.e. 'https://api.rev.ai', which can be referenced as
RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url'].
"""

# Default speech to text base url
self.base_url = f'{url if url else self.default_url}/speechtotext/{self.version}/'
BaseClient.__init__(self, access_token)

def submit_job_url(
Expand Down
19 changes: 17 additions & 2 deletions src/rev_ai/generic_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Generic client used to interact with our newer style apis"""

from .baseclient import BaseClient
from .models import RevAiApiDeploymentConfigMap, RevAiApiDeployment

try:
from urllib.parse import urljoin
Expand All @@ -13,7 +14,18 @@ class GenericApiClient(BaseClient):
"""Generic client which handles logic for making requests to almost any Rev AI Api.
Intended to be inherited and extended by a specific client per API"""

def __init__(self, access_token, api_name, api_version, parse_job_info, parse_job_result):
# Default url for US Rev AI deployment
default_url = RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']

def __init__(
self,
access_token: str,
api_name: str,
api_version: str,
parse_job_info,
parse_job_result,
url: str = None
):
"""Constructor
:param access_token: access token which authorizes all requests and links them to your
Expand All @@ -23,10 +35,13 @@ def __init__(self, access_token, api_name, api_version, parse_job_info, parse_jo
:param api_version: version of the api to submit to
:param parse_job_info: method to be used to parse job information
:param parse_job_result: method to be used to parse job results
:param url (optional): url of the Rev AI API deployment to use, defaults to the US
deployement, i.e. 'https://api.rev.ai', which can be referenced as
RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url'].
"""

BaseClient.__init__(self, access_token)
self.base_url = 'https://api.rev.ai/{0}/{1}/'.format(api_name, api_version)
self.base_url = f'{url if url else self.default_url}/{api_name}/{api_version}/'
self.parse_job_info = parse_job_info
self.parse_job_result = parse_job_result

Expand Down
10 changes: 7 additions & 3 deletions src/rev_ai/language_identification_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

import json
from .generic_api_client import GenericApiClient
from .models import LanguageIdentificationJob, LanguageIdentificationResult
from .models import LanguageIdentificationJob, LanguageIdentificationResult, \
RevAiApiDeploymentConfigMap, RevAiApiDeployment

try:
from urllib.parse import urljoin
Expand All @@ -20,17 +21,20 @@ class LanguageIdentificationClient(GenericApiClient):
# Default api name of Rev AI language identification api
api_name = 'languageid'

def __init__(self, access_token):
def __init__(self, access_token, url=None):
"""Constructor
:param access_token: access token which authorizes all requests and links them to your
account. Generated on the settings page of your account dashboard
on Rev AI.
:param url (optional): url of the Rev AI API deployment to use, defaults to the US
deployement, i.e. 'https://api.rev.ai', which can be referenced as
RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url'].
"""

GenericApiClient.__init__(self, access_token, self.api_name, self.api_version,
LanguageIdentificationJob.from_json,
LanguageIdentificationResult.from_json)
LanguageIdentificationResult.from_json, url)

def submit_job_url(
self,
Expand Down
1 change: 1 addition & 0 deletions src/rev_ai/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
SentimentAnalysisResult, SentimentValue, SentimentMessage, SentimentAnalysisJob
from .language_id import LanguageIdentificationJob, LanguageIdentificationResult, LanguageConfidence
from .customer_url_data import CustomerUrlData
from .revaiapi_deployment_config_constants import RevAiApiDeployment, RevAiApiDeploymentConfigMap
39 changes: 39 additions & 0 deletions src/rev_ai/models/revaiapi_deployment_config_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from enum import Enum
from typing import Dict, TypedDict


class RevAiApiDeployment(Enum):
"""
Enum representing the deployment regions for Rev AI API.
Attributes:
US: Represents the United States deployment.
EU: Represents the European Union deployment.
"""
US = 'US'
EU = 'EU'


class RevAiApiConfig(TypedDict):
"""
TypedDict representing the configuration for a Rev AI API deployment.
Attributes:
base_url: The base URL for API requests.
base_websocket_url: The base URL for WebSocket connections.
"""
base_url: str
base_websocket_url: str


# Dictionary mapping RevAiApiDeployment enum values to their respective configuration settings.
RevAiApiDeploymentConfigMap: Dict[RevAiApiDeployment, RevAiApiConfig] = {
RevAiApiDeployment.US: {
'base_url': 'https://api.rev.ai',
'base_websocket_url': 'wss://api.rev.ai'
},
RevAiApiDeployment.EU: {
'base_url': 'https://ec1.api.rev.ai',
'base_websocket_url': 'wss://ec1.api.rev.ai'
}
}
21 changes: 15 additions & 6 deletions src/rev_ai/streamingclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import six
import json
from . import __version__
from .models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from .models.streaming import MediaConfig

try:
from urllib.parse import urlencode
Expand All @@ -26,13 +28,18 @@ def on_connected(job_id):


class RevAiStreamingClient:

# Default url for US Rev AI deployment
default_url = RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_websocket_url']

def __init__(self,
access_token,
config,
version='v1',
access_token: str,
config: MediaConfig,
version: str = 'v1',
on_error=on_error,
on_close=on_close,
on_connected=on_connected):
on_connected=on_connected,
url: str = None):
"""Constructor for Streaming Client
:param access_token: access token which authorizes all requests and
links them to your account. Generated on the settings page of your
Expand All @@ -46,6 +53,9 @@ def __init__(self,
closes
:param on_connected (optional): function to be called when the websocket
and thread starts successfully
:param url (optional): url of the Rev AI API deployment to use, defaults to the US
deployement, i.e. 'wss://api.rev.ai', which can be referenced as
RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_websocket_url'].
"""
if not access_token:
raise ValueError('access_token must be provided')
Expand All @@ -55,8 +65,7 @@ def __init__(self,

self.access_token = access_token
self.config = config
self.base_url = 'wss://api.rev.ai/speechtotext/{}/stream'. \
format(version)
self.base_url = f'{url if url else self.default_url}/speechtotext/{version}/stream'
self.on_error = on_error
self.on_close = on_close
self.on_connected = on_connected
Expand Down
4 changes: 3 additions & 1 deletion tests/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

import pytest
from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from src.rev_ai.models.asynchronous import Account

try:
from urllib.parse import urljoin
except ImportError:
from urlparse import urljoin

URL = urljoin(RevAiAPIClient.base_url, 'account')
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
URL = urljoin(SPEECH_TO_TEXT_URL, 'account')


@pytest.mark.usefixtures('mock_session', 'make_mock_response')
Expand Down
6 changes: 4 additions & 2 deletions tests/test_async_captions_translation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment

try:
from urllib.parse import urljoin
Expand All @@ -9,8 +10,9 @@

TOKEN = "token"
JOB_ID = '1'
JOB_ID_URL = urljoin(RevAiAPIClient.base_url, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(RevAiAPIClient.base_url, 'jobs')
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
JOB_ID_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs')


@pytest.mark.usefixtures('mock_session', 'make_mock_response')
Expand Down
6 changes: 4 additions & 2 deletions tests/test_async_summarization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest

from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from src.rev_ai.models.asynchronous.summarization_formatting_options import SummarizationFormattingOptions
from src.rev_ai.models.asynchronous.summarization_job_status import SummarizationJobStatus
from src.rev_ai.models.asynchronous.summarization_options import SummarizationOptions
Expand All @@ -15,8 +16,9 @@

TOKEN = "token"
JOB_ID = '1'
JOB_ID_URL = urljoin(RevAiAPIClient.base_url, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(RevAiAPIClient.base_url, 'jobs')
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
JOB_ID_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs')
JOB_TRANSCRIPT_SUMMARY_URL = '{}/transcript/summary'.format(JOB_ID_URL)


Expand Down
6 changes: 4 additions & 2 deletions tests/test_async_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest

from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from src.rev_ai.models.asynchronous.translation_job_status import TranslationJobStatus
from src.rev_ai.models.asynchronous.translation_language_options import TranslationLanguageOptions
from src.rev_ai.models.asynchronous.translation_options import TranslationOptions
Expand All @@ -15,8 +16,9 @@

TOKEN = "token"
JOB_ID = '1'
JOB_ID_URL = urljoin(RevAiAPIClient.base_url, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(RevAiAPIClient.base_url, 'jobs')
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
JOB_ID_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs')


@pytest.mark.usefixtures('mock_session', 'make_mock_response')
Expand Down
3 changes: 2 additions & 1 deletion tests/test_baseclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai import __version__
from src.rev_ai.baseclient import BaseClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from tests.helpers.errors import get_error_test_cases

TOKEN = "token"
Expand All @@ -34,7 +35,7 @@ def test_constructor_with_no_token(self, token):
def test_make_http_request(self, error, method, mock_session,
make_mock_response):
status = error.get('status')
URL = RevAiAPIClient.base_url
URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
response = make_mock_response(url=URL, status=status, json_data=error)
mock_session.request.return_value = response
client = RevAiAPIClient(TOKEN)
Expand Down
6 changes: 4 additions & 2 deletions tests/test_captions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import pytest
from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import CaptionType
from src.rev_ai.models import CaptionType, RevAiApiDeploymentConfigMap, RevAiApiDeployment


try:
from urllib.parse import urljoin
Expand All @@ -11,7 +12,8 @@

JOB_ID = '1'
TOKEN = "token"
URL = urljoin(RevAiAPIClient.base_url, 'jobs/{}/captions'.format(JOB_ID))
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs/{}/captions'.format(JOB_ID))


@pytest.mark.usefixtures('mock_session', 'make_mock_response')
Expand Down
8 changes: 5 additions & 3 deletions tests/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import json
import pytest

from src.rev_ai.models.customer_url_data import CustomerUrlData
from src.rev_ai.apiclient import RevAiAPIClient
from src.rev_ai.models import RevAiApiDeploymentConfigMap, RevAiApiDeployment
from src.rev_ai.models.asynchronous import Job, JobStatus, SpeakerName
from src.rev_ai.models.customer_url_data import CustomerUrlData

try:
from urllib.parse import urljoin
Expand All @@ -22,8 +23,9 @@
SOURCE_URL = 'https://example.com/test.mp3'
SOURCE_AUTH = 'source auth headers'
FILENAME = 'test.mp3'
JOB_ID_URL = urljoin(RevAiAPIClient.base_url, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(RevAiAPIClient.base_url, 'jobs')
SPEECH_TO_TEXT_URL = f"{RevAiApiDeploymentConfigMap[RevAiApiDeployment.US]['base_url']}/speechtotext/v1/"
JOB_ID_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs/{}'.format(JOB_ID))
JOBS_URL = urljoin(SPEECH_TO_TEXT_URL, 'jobs')
CUSTOM_VOCAB = [{"phrases": ["word one", "word two"]}]
CUSTOM_VOCAB_ID = "vid"
LANGUAGE = 'en'
Expand Down
Loading

0 comments on commit b171899

Please sign in to comment.