Mbonea commited on
Commit
1c49e44
1 Parent(s): 70629ed

added HeyGen

Browse files
App/TTS/Schemas.py CHANGED
@@ -1,23 +1,43 @@
1
- from pydantic import BaseModel,Field
2
- from typing import List,Optional
3
  import uuid
4
 
 
5
  class Speak(BaseModel):
6
  paragraphId: str = Field(default_factory=lambda: str(uuid.uuid4()))
7
  speaker: str
8
  text: str
9
- voiceId: str = Field(default="c60166365edf46589657770d", alias="speaker") # Default speaker value
 
 
10
 
11
  def __init__(self, **data):
12
- data["text"] = data.get('text') if '<speak>' in data.get('text') else f"<speak>{data.get('text')}</speak>"
 
 
 
 
13
  super().__init__(**data)
14
 
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  class TTSGenerateRequest(BaseModel):
18
  paragraphs: List[Speak]
19
  requestId: str = Field(default_factory=lambda: str(uuid.uuid4()))
20
- workspaceId: str =Field(default_factory=lambda: str(uuid.uuid4()))
21
 
22
 
23
  class StatusRequest(BaseModel):
 
1
+ from pydantic import BaseModel, Field, validator
2
+ from typing import List, Optional
3
  import uuid
4
 
5
+
6
  class Speak(BaseModel):
7
  paragraphId: str = Field(default_factory=lambda: str(uuid.uuid4()))
8
  speaker: str
9
  text: str
10
+ voiceId: str = Field(
11
+ default="c60166365edf46589657770d", alias="speaker"
12
+ ) # Default speaker value
13
 
14
  def __init__(self, **data):
15
+ data["text"] = (
16
+ data.get("text")
17
+ if "<speak>" in data.get("text")
18
+ else f"<speak>{data.get('text')}</speak>"
19
+ )
20
  super().__init__(**data)
21
 
22
 
23
+ class HeyGenTTSRequest(BaseModel):
24
+ voice_id: str = Field(default="d7bbcdd6964c47bdaae26decade4a933")
25
+ rate: str = Field(default="1")
26
+ pitch: str = Field(default="-3%")
27
+ text: str = "Sample"
28
+
29
+ @validator("text")
30
+ def validate_age(cls, value, values):
31
+ if not "speak" in value:
32
+ return f'<speak> <voice name="{values.get("voice_id")}"><prosody rate="{values.get("rate")}" pitch="{values.get("pitch")}">{value}</prosody></voice></speak>'
33
+ else:
34
+ return value
35
+
36
 
37
  class TTSGenerateRequest(BaseModel):
38
  paragraphs: List[Speak]
39
  requestId: str = Field(default_factory=lambda: str(uuid.uuid4()))
40
+ workspaceId: str = Field(default_factory=lambda: str(uuid.uuid4()))
41
 
42
 
43
  class StatusRequest(BaseModel):
App/TTS/TTSRoutes.py CHANGED
@@ -1,27 +1,33 @@
1
  from fastapi import APIRouter
2
 
3
 
4
- from .Schemas import StatusRequest, TTSGenerateRequest
5
  from .utils.Podcastle import PodcastleAPI
 
6
  import os
7
 
8
  tts_router = APIRouter(tags=["TTS"])
9
  data = {"username": os.environ.get("USERNAME"), "password": os.environ.get("PASSWORD")}
10
  tts = PodcastleAPI(**data)
 
 
 
 
 
11
 
12
 
13
- #
14
  @tts_router.post("/generate_tts")
15
  async def generate_voice(req: TTSGenerateRequest):
16
  print("here --entered!")
17
  return await tts.make_request(req)
18
 
19
 
 
 
 
 
 
 
20
  @tts_router.post("/status")
21
  async def search_id(req: StatusRequest):
22
  return await tts.check_status(req)
23
-
24
-
25
- # @tts_router.post("/search_text")
26
- # async def search_text(req: SearchRequest):
27
- # return TextSearch(query=req.query)
 
1
  from fastapi import APIRouter
2
 
3
 
4
+ from .Schemas import StatusRequest, TTSGenerateRequest, HeyGenTTSRequest
5
  from .utils.Podcastle import PodcastleAPI
6
+ from .utils.HeyGen import HeygenAPI
7
  import os
8
 
9
  tts_router = APIRouter(tags=["TTS"])
10
  data = {"username": os.environ.get("USERNAME"), "password": os.environ.get("PASSWORD")}
11
  tts = PodcastleAPI(**data)
12
+ data = {
13
+ "account": os.environ.get("HEYGEN_USERNAME"),
14
+ "password": os.environ.get("HEYGEN_PASSWORD"),
15
+ }
16
+ heyGentts = HeygenAPI(**data)
17
 
18
 
 
19
  @tts_router.post("/generate_tts")
20
  async def generate_voice(req: TTSGenerateRequest):
21
  print("here --entered!")
22
  return await tts.make_request(req)
23
 
24
 
25
+ @tts_router.post("/heygen_tts")
26
+ async def generate_heygen_voice(req: HeyGenTTSRequest):
27
+ print("hey gen here")
28
+ return await heyGentts.tts_request(req)
29
+
30
+
31
  @tts_router.post("/status")
32
  async def search_id(req: StatusRequest):
33
  return await tts.check_status(req)
 
 
 
 
 
App/TTS/utils/HeyGen.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import aiohttp
2
+ from App.TTS.Schemas import HeyGenTTSRequest
3
+
4
+
5
+ class HeygenAPI:
6
+ def __init__(self, account, password):
7
+ self.base_url = "https://api2.heygen.com/v1"
8
+ self.account = account
9
+ self.password = password
10
+ self.session = None
11
+ self.session_token = None
12
+
13
+ async def create_session(self):
14
+ self.session = aiohttp.ClientSession()
15
+
16
+ async def close_session(self):
17
+ if self.session:
18
+ await self.session.close()
19
+
20
+ async def login(self):
21
+ url = f"{self.base_url}/pacific/login"
22
+ payload = {
23
+ "login_type": "email",
24
+ "account": self.account,
25
+ "password": self.password,
26
+ }
27
+
28
+ if not self.session:
29
+ await self.create_session()
30
+
31
+ async with self.session.post(url, json=payload) as response:
32
+ response_data = await response.json()
33
+ self.session_token = response_data.get("data", {}).get("session_token")
34
+ return response_data
35
+
36
+ async def relogin(self):
37
+ # Function to relogin and update the session token
38
+ login_result = await self.login()
39
+ if login_result.get("code") == 100:
40
+ self.session_token = login_result["data"]["session_token"]
41
+ return True
42
+ return False
43
+
44
+ async def tts_request(self, req: HeyGenTTSRequest):
45
+ if not self.session_token or not self.session_token:
46
+ await self.login()
47
+
48
+ url = f"{self.base_url}/online/text_to_speech.generate"
49
+ headers = {
50
+ "content-type": "application/json",
51
+ "x-session-token": self.session_token,
52
+ }
53
+
54
+ tts_payload = {
55
+ "text_type": "ssml",
56
+ "output_format": "wav",
57
+ "text": req.text,
58
+ "voice_id": req.voice_id,
59
+ "settings": {},
60
+ }
61
+
62
+ async with self.session.post(
63
+ url, json=tts_payload, headers=headers
64
+ ) as response:
65
+ if response.status == 401:
66
+ # If a 401 error is encountered, relogin and retry the request
67
+ if await self.relogin():
68
+ headers["x-session-token"] = self.session_token
69
+ response = await self.session.post(
70
+ url, json=tts_payload, headers=headers
71
+ )
72
+
73
+ response_data = await response.json()
74
+ return response_data
75
+
76
+ async def __aenter__(self):
77
+ if not self.session:
78
+ await self.create_session()
79
+ return self
80
+
81
+ async def __aexit__(self, exc_type, exc_value, traceback):
82
+ await self.close_session()