Skip to content

Commit 0870468

Browse files
committed
neda working
1 parent 5277c90 commit 0870468

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

app/apps/neda/routes.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fastapi
44
from fastapi import BackgroundTasks
55
from fastapi_mongo_base.routes import AbstractTaskRouter
6+
from fastapi_mongo_base.core import exceptions
67
from usso.fastapi import jwt_access_security
78

89
from .models import VoiceConvert
@@ -28,13 +29,51 @@ def __init__(self):
2829
def config_routes(self, **kwargs):
2930
super().config_routes(update_route=False)
3031

32+
async def retrieve_item(
33+
self,
34+
request: fastapi.Request,
35+
uid: uuid.UUID,
36+
):
37+
user = await self.get_user(request)
38+
is_admin = "admin" in user.data.get("scopes", [])
39+
if is_admin:
40+
item = await self.get_item(uid, ignore_user_id=True)
41+
else:
42+
item = await self.get_item(uid, user_id=user.uid)
43+
return item
44+
3145
async def create_item(
3246
self,
3347
request: fastapi.Request,
3448
data: VoiceConvertTaskCreateSchema,
3549
background_tasks: BackgroundTasks,
50+
# user_id: uuid.UUID | None = fastapi.Body(
51+
# default=None,
52+
# embed=True,
53+
# description="Request for another User ID. It is possible only if the request user is admin. If not provided, the request user will be used.",
54+
# ),
3655
):
37-
return await super().create_item(request, data.model_dump(), background_tasks)
56+
user = await self.get_user(request)
57+
is_admin = "admin" in user.data.get("scopes", [])
58+
# import logging
59+
# logging.info(f"user_id: {user_id} is_admin: {is_admin} user.uid: {user.uid}")
60+
61+
# if user_id and not is_admin and user_id != user.uid:
62+
# raise exceptions.BaseHTTPException(
63+
# status_code=403,
64+
# error="Forbidden",
65+
# message={
66+
# "en": "You are not allowed to request another user's ID.",
67+
# "fa": "شما مجوز دسترسی به آیدی کاربر دیگری را ندارید.",
68+
# },
69+
# )
70+
71+
user_id = user.uid
72+
item = await self.model.create_item({**data.model_dump(), "user_id": user_id})
73+
74+
if item.task_status == "init" or not self.draftable:
75+
background_tasks.add_task(item.start_processing)
76+
return item
3877

3978
async def webhook(
4079
self,
@@ -48,3 +87,12 @@ async def webhook(
4887

4988

5089
router = VoiceConvertRouter().router
90+
91+
92+
@router.post("/pitch")
93+
async def get_pitch(url: str = fastapi.Body(..., embed=True)):
94+
from utils import voice
95+
from .services import get_voice
96+
97+
pitch_data = voice.get_voice_pitch_parselmouth(await get_voice(url))
98+
return pitch_data

app/apps/neda/schemas.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def progress(self):
5050

5151
class VoiceConvertTaskCreateSchema(BaseModel):
5252
url: str
53-
pitch_difference: float = 0.0
53+
pitch_difference: float | None = None
5454
target_voice: str
5555

5656
meta_data: dict | None = None

app/apps/neda/services.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
)
1616

1717

18-
@cached(ttl=60)
18+
@cached(ttl=60 * 10)
1919
async def get_voice(url: str) -> BytesIO:
2020
async with httpx.AsyncClient() as client:
2121
response = await client.get(url)
@@ -24,11 +24,14 @@ async def get_voice(url: str) -> BytesIO:
2424

2525

2626
async def register_cost(voice_task: VoiceConvert):
27-
duration = voice_task.meta_data.get("duration", 0)
28-
price = Settings.minutes_price * duration
29-
usage = await finance.meter_cost(voice_task.user_id, amount=price)
30-
if usage:
31-
return usage
27+
try:
28+
duration = voice_task.meta_data.get("duration", 0)
29+
price = Settings.minutes_price * duration
30+
usage = await finance.meter_cost(voice_task.user_id, amount=price)
31+
if usage:
32+
return usage
33+
except Exception as e:
34+
logging.error(f"Error registering cost. {voice_task.user_id} {voice_task.uid} {e}")
3235

3336
logging.error(f"Insufficient balance. {voice_task.user_id} {voice_task.id}")
3437
await voice_task.fail("Insufficient balance.")
@@ -44,7 +47,6 @@ async def convert_voice(voice_task: VoiceConvert, **kwargs):
4447
usage = await register_cost(voice_task)
4548

4649
if usage is None:
47-
await voice_task.fail("Insufficient balance.")
4850
return
4951

5052
model = await VoiceModel.get_by_slug(voice_task.target_voice)
@@ -59,13 +61,14 @@ async def convert_voice(voice_task: VoiceConvert, **kwargs):
5961
await voice_task.fail("Model not found.")
6062
return
6163

62-
voice_task._status = VoiceConvertStatus.pitch_conversion
63-
await voice_task.save()
64+
if voice_task.pitch_difference is None:
65+
voice_task._status = VoiceConvertStatus.pitch_conversion
66+
await voice_task.save()
6467

65-
pitch_data = voice.get_voice_pitch_parselmouth(await get_voice(voice_task.url))
66-
voice_task.pitch_difference = voice.calculate_pitch_shift_log(
67-
pitch_data["robust_average"], model.base_pitch
68-
)
68+
pitch_data = voice.get_voice_pitch_parselmouth(await get_voice(voice_task.url))
69+
voice_task.pitch_difference = voice.calculate_pitch_shift_log(
70+
pitch_data["robust_average"], model.base_pitch
71+
)
6972

7073
run_id = voice.create_rvc_conversion_runpod(
7174
voice_task.url,

app/utils/finance.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from ufaas import AsyncUFaaS, exceptions
1010
from ufaas.apps.saas.schemas import UsageCreateSchema, UsageSchema
1111

12-
resource_variant = getattr(Settings, "UFAAS_RESOURCE_VARIANT", "subtitle")
12+
resource_variant = getattr(Settings, "UFAAS_RESOURCE_VARIANT", "neda")
1313

1414

1515
@asynccontextmanager
@@ -26,6 +26,7 @@ async def get_ufaas_client() -> AsyncGenerator[AsyncUFaaS, None]:
2626
pass
2727

2828

29+
@basic.retry_execution(attempts=2, delay=0.1)
2930
async def meter_cost(
3031
user_id: uuid.UUID, amount: float, meta_data: dict = None
3132
) -> UsageSchema:

0 commit comments

Comments
 (0)