allow api_key assignment to occur after imports

This commit is contained in:
Ajay Raj 2023-03-20 10:49:20 -07:00
commit d1118d375e
9 changed files with 43 additions and 60 deletions

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "vocode" name = "vocode"
version = "0.1.45" version = "0.1.48"
description = "The all-in-one voice SDK" description = "The all-in-one voice SDK"
authors = ["Ajay Raj <ajay@vocode.dev>"] authors = ["Ajay Raj <ajay@vocode.dev>"]
license = "MIT License" license = "MIT License"
@ -31,8 +31,6 @@ sounddevice = { version = "0.4.6", optional = true }
starlette = "0.25.0" starlette = "0.25.0"
urllib3 = "1.26.14" urllib3 = "1.26.14"
uvicorn = "0.20.0" uvicorn = "0.20.0"
black = "23.1.0"
flake8 = "6.0.0"
mccabe = "0.7.0" mccabe = "0.7.0"
mypy-extensions = "1.0.0" mypy-extensions = "1.0.0"
packaging = "23.0" packaging = "23.0"
@ -45,7 +43,6 @@ pyjwt = "2.6.0"
python-multipart = "0.0.6" python-multipart = "0.0.6"
pytz = "2022.7.1" pytz = "2022.7.1"
tomli = "2.0.1" tomli = "2.0.1"
twilio = "7.16.5"
[tool.poetry.extras] [tool.poetry.extras]
io = ["pyaudio", "sounddevice"] io = ["pyaudio", "sounddevice"]

View file

@ -1,12 +1,10 @@
anyio==3.6.2 anyio==3.6.2
black==23.1.0
certifi==2022.12.7 certifi==2022.12.7
cffi==1.15.1 cffi==1.15.1
charset-normalizer==3.0.1 charset-normalizer==3.0.1
click==8.1.3 click==8.1.3
decorator==5.1.1 decorator==5.1.1
fastapi==0.92.0 fastapi==0.92.0
flake8==6.0.0
h11==0.14.0 h11==0.14.0
idna==3.4 idna==3.4
mccabe==0.7.0 mccabe==0.7.0
@ -31,7 +29,6 @@ sniffio==1.3.0
sounddevice==0.4.6 sounddevice==0.4.6
starlette==0.25.0 starlette==0.25.0
tomli==2.0.1 tomli==2.0.1
twilio==7.16.5
typing_extensions>=3.10.0.2 typing_extensions>=3.10.0.2
urllib3==1.26.14 urllib3==1.26.14
uvicorn==0.20.0 uvicorn==0.20.0

View file

@ -3,13 +3,6 @@ import logging
import signal import signal
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
load_dotenv()
import vocode
vocode.api_key = os.getenv("VOCODE_API_KEY")
from vocode.conversation import Conversation from vocode.conversation import Conversation
from vocode.helpers import create_microphone_input_and_speaker_output from vocode.helpers import create_microphone_input_and_speaker_output
from vocode.models.transcriber import ( from vocode.models.transcriber import (
@ -30,6 +23,10 @@ from vocode.models.agent import (
from vocode.models.message import BaseMessage from vocode.models.message import BaseMessage
from vocode.models.synthesizer import AzureSynthesizerConfig from vocode.models.synthesizer import AzureSynthesizerConfig
from vocode.user_implemented_agent.restful_agent import RESTfulAgent from vocode.user_implemented_agent.restful_agent import RESTfulAgent
import vocode
load_dotenv()
vocode.api_key = os.getenv("VOCODE_API_KEY")
logging.basicConfig() logging.basicConfig()
logging.root.setLevel(logging.INFO) logging.root.setLevel(logging.INFO)

View file

@ -12,18 +12,19 @@ from vocode.telephony.zoom_dial_in import ZoomDialIn
if __name__ == "__main__": if __name__ == "__main__":
call = ZoomDialIn( call = ZoomDialIn(
recipient=CallEntity(phone_number="<zoom_phone_number>"), recipient=CallEntity(phone_number="<your zoom phone number>"),
caller=CallEntity( caller=CallEntity(
phone_number="<your_phone_number>", phone_number="<your phone number>",
), ),
zoom_meeting_id="<zoom_meeting_id>", zoom_meeting_id="<your zoom meeting id>",
zoom_meeting_password="<zoom_meeting_password>", zoom_meeting_password="<your zoom meeting password>",
agent_config=ChatGPTAgentConfig( agent_config=ChatGPTAgentConfig(
initial_message=BaseMessage(text="the quick fox jumped over the lazy dog "), initial_message=BaseMessage(text="the quick fox jumped over the lazy dog "),
prompt_preamble="respond two sentences at a time", prompt_preamble="respond two sentences at a time",
generate_responses=True, generate_responses=True,
end_conversation_on_goodbye=True, end_conversation_on_goodbye=True,
send_filler_audio=True, send_filler_audio=True,
allowed_idle_time_seconds=30
), ),
synthesizer_config=AzureSynthesizerConfig.from_output_device( synthesizer_config=AzureSynthesizerConfig.from_output_device(
output_device=TelephoneOutput(), voice_name="en-US-JennyNeural" output_device=TelephoneOutput(), voice_name="en-US-JennyNeural"

View file

@ -4,4 +4,4 @@ from dotenv import load_dotenv
load_dotenv() load_dotenv()
api_key = os.getenv("VOCODE_API_KEY") api_key = os.getenv("VOCODE_API_KEY")
BASE_URL = os.getenv("VOCODE_BASE_URL", "api.vocode.dev") base_url = os.getenv("VOCODE_BASE_URL", "api.vocode.dev")

View file

@ -7,19 +7,16 @@ import os
import logging import logging
import threading import threading
import queue import queue
import vocode
from vocode.input_device.base_input_device import BaseInputDevice
from vocode.output_device.base_output_device import BaseOutputDevice
from vocode.models.transcriber import TranscriberConfig
from vocode.models.agent import AgentConfig
from vocode.models.synthesizer import SynthesizerConfig
from vocode.models.websocket import ReadyMessage, AudioMessage, StartMessage, StopMessage
load_dotenv() load_dotenv()
from .input_device.base_input_device import BaseInputDevice
from .output_device.base_output_device import BaseOutputDevice
from .models.transcriber import TranscriberConfig
from .models.agent import AgentConfig
from .models.synthesizer import SynthesizerConfig
from .models.websocket import ReadyMessage, AudioMessage, StartMessage, StopMessage
from . import api_key, BASE_URL
VOCODE_WEBSOCKET_URL = f"wss://{BASE_URL}/conversation"
class Conversation: class Conversation:
def __init__( def __init__(
self, self,
@ -41,6 +38,7 @@ class Conversation:
self.active = True self.active = True
self.output_loop = asyncio.new_event_loop() self.output_loop = asyncio.new_event_loop()
self.output_audio_queue = queue.Queue() self.output_audio_queue = queue.Queue()
self.vocode_websocket_url = f"wss://{vocode.base_url}/conversation"
async def wait_for_ready(self): async def wait_for_ready(self):
while not self.receiver_ready: while not self.receiver_ready:
@ -63,7 +61,7 @@ class Conversation:
loop.run_until_complete(run()) loop.run_until_complete(run())
async def start(self): async def start(self):
async with websockets.connect(f"{VOCODE_WEBSOCKET_URL}?key={api_key}") as ws: async with websockets.connect(f"{self.vocode_websocket_url}?key={vocode.api_key}") as ws:
async def sender(ws: WebSocketClientProtocol): async def sender(ws: WebSocketClientProtocol):
start_message = StartMessage( start_message = StartMessage(

View file

@ -2,17 +2,12 @@ from fastapi import FastAPI, Response, Form
from typing import Optional from typing import Optional
import requests import requests
import uvicorn import uvicorn
from vocode.models.synthesizer import SynthesizerConfig
from twilio.jwt.access_token.grants import VoiceGrant
import vocode
from vocode.models.transcriber import TranscriberConfig from vocode.models.transcriber import TranscriberConfig
from .. import api_key, BASE_URL from vocode.models.synthesizer import SynthesizerConfig
from vocode.models.agent import AgentConfig
from ..models.agent import AgentConfig from vocode.models.telephony import CreateInboundCall, TwilioConfig, TwilioConfig
from ..models.telephony import CreateInboundCall, TwilioConfig, TwilioConfig
VOCODE_INBOUND_CALL_URL = f"https://{BASE_URL}/create_inbound_call"
class InboundCallServer: class InboundCallServer:
def __init__( def __init__(
@ -33,11 +28,12 @@ class InboundCallServer:
or "The line is really busy right now, check back later!" or "The line is really busy right now, check back later!"
) )
self.twilio_config = twilio_config self.twilio_config = twilio_config
self.vocode_inbound_call_url = f"https://{vocode.base_url}/create_inbound_call"
async def handle_call(self, twilio_sid: str = Form(alias="CallSid")): async def handle_call(self, twilio_sid: str = Form(alias="CallSid")):
response = requests.post( response = requests.post(
VOCODE_INBOUND_CALL_URL, self.vocode_inbound_call_url,
headers={"Authorization": f"Bearer {api_key}"}, headers={"Authorization": f"Bearer {vocode.api_key}"},
json=CreateInboundCall( json=CreateInboundCall(
agent_config=self.agent_config, agent_config=self.agent_config,
twilio_sid=twilio_sid, twilio_sid=twilio_sid,

View file

@ -1,4 +1,7 @@
from typing import Optional from typing import Optional
import requests
import vocode
from vocode.models.agent import AgentConfig from vocode.models.agent import AgentConfig
from vocode.models.synthesizer import SynthesizerConfig from vocode.models.synthesizer import SynthesizerConfig
from vocode.models.transcriber import TranscriberConfig from vocode.models.transcriber import TranscriberConfig
@ -8,14 +11,6 @@ from ..models.telephony import (
EndOutboundCall, EndOutboundCall,
TwilioConfig, TwilioConfig,
) )
import requests
from .. import api_key, BASE_URL
from twilio.jwt.access_token.grants import VoiceGrant
VOCODE_CREATE_OUTBOUND_CALL_URL = f"https://{BASE_URL}/create_outbound_call"
VOCODE_END_OUTBOUND_CALL_URL = f"https://{BASE_URL}/end_outbound_call"
class OutboundCall: class OutboundCall:
@ -36,11 +31,13 @@ class OutboundCall:
self.synthesizer_config = synthesizer_config self.synthesizer_config = synthesizer_config
self.conversation_id = conversation_id self.conversation_id = conversation_id
self.twilio_config = twilio_config self.twilio_config = twilio_config
self.vocode_create_outbound_call_url = f"https://{vocode.base_url}/create_outbound_call"
self.vocode_end_outbound_call_url = f"https://{vocode.base_url}/end_outbound_call"
def start(self) -> str: def start(self) -> str:
response = requests.post( response = requests.post(
VOCODE_CREATE_OUTBOUND_CALL_URL, self.vocode_create_outbound_call_url,
headers={"Authorization": f"Bearer {api_key}"}, headers={"Authorization": f"Bearer {vocode.api_key}"},
json=CreateOutboundCall( json=CreateOutboundCall(
recipient=self.recipient, recipient=self.recipient,
caller=self.caller, caller=self.caller,
@ -57,8 +54,8 @@ class OutboundCall:
def end(self) -> str: def end(self) -> str:
response = requests.post( response = requests.post(
VOCODE_END_OUTBOUND_CALL_URL, self.vocode_end_outbound_call_url,
headers={"Authorization": f"Bearer {api_key}"}, headers={"Authorization": f"Bearer {vocode.api_key}"},
json=EndOutboundCall( json=EndOutboundCall(
call_id=self.conversation_id, call_id=self.conversation_id,
twilio_config=self.twilio_config, twilio_config=self.twilio_config,

View file

@ -1,17 +1,16 @@
from typing import Optional from typing import Optional
import requests
import vocode
from vocode.models.agent import AgentConfig from vocode.models.agent import AgentConfig
from vocode.models.synthesizer import SynthesizerConfig from vocode.models.synthesizer import SynthesizerConfig
from vocode.models.transcriber import TranscriberConfig from vocode.models.transcriber import TranscriberConfig
from vocode.telephony.outbound_call import OutboundCall from vocode.telephony.outbound_call import OutboundCall
from ..models.telephony import ( from vocode.models.telephony import (
CallEntity, CallEntity,
DialIntoZoomCall, DialIntoZoomCall,
TwilioConfig, TwilioConfig,
) )
import requests
from .. import api_key, BASE_URL
VOCODE_ZOOM_DIAL_IN_URL = f"https://{BASE_URL}/dial_into_zoom_call"
class ZoomDialIn(OutboundCall): class ZoomDialIn(OutboundCall):
@ -38,11 +37,12 @@ class ZoomDialIn(OutboundCall):
) )
self.zoom_meeting_id = zoom_meeting_id self.zoom_meeting_id = zoom_meeting_id
self.zoom_meeting_password = zoom_meeting_password self.zoom_meeting_password = zoom_meeting_password
self.vocode_zoom_dial_in_url = f"https://{vocode.base_url}/dial_into_zoom_call"
def start(self) -> str: def start(self) -> str:
response = requests.post( response = requests.post(
VOCODE_ZOOM_DIAL_IN_URL, self.vocode_zoom_dial_in_url,
headers={"Authorization": f"Bearer {api_key}"}, headers={"Authorization": f"Bearer {vocode.api_key}"},
json=DialIntoZoomCall( json=DialIntoZoomCall(
recipient=self.recipient, recipient=self.recipient,
caller=self.caller, caller=self.caller,