Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
import shutil
|
2 |
-
from fastapi import FastAPI, HTTPException, Request
|
3 |
from deezspot.deezloader import DeeLogin
|
4 |
from deezspot.spotloader import SpoLogin
|
5 |
import requests
|
@@ -9,7 +9,7 @@ import json
|
|
9 |
from typing import Optional
|
10 |
from fastapi.staticfiles import StaticFiles
|
11 |
from dotenv import load_dotenv
|
12 |
-
from pydantic import BaseModel
|
13 |
from urllib.parse import quote
|
14 |
from pathlib import Path
|
15 |
import uuid
|
@@ -18,7 +18,8 @@ from collections import defaultdict
|
|
18 |
import time
|
19 |
from datetime import timedelta
|
20 |
import gc
|
21 |
-
from typing import Dict
|
|
|
22 |
|
23 |
# Set up logging
|
24 |
logging.basicConfig(level=logging.INFO)
|
@@ -306,6 +307,70 @@ def search_tracks(query: str, limit: Optional[int] = 10):
|
|
306 |
logger.error(f"Error searching tracks: {e}")
|
307 |
raise HTTPException(status_code=500, detail=str(e))
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
# Spotify credentials from environment variables
|
310 |
'''SPOTIFY_USERNAME = os.getenv("SPOTIFY_USERNAME")
|
311 |
SPOTIFY_CREDENTIALS = os.getenv("SPOTIFY_CREDENTIALS")
|
|
|
1 |
import shutil
|
2 |
+
from fastapi import FastAPI, HTTPException, Request, Body
|
3 |
from deezspot.deezloader import DeeLogin
|
4 |
from deezspot.spotloader import SpoLogin
|
5 |
import requests
|
|
|
9 |
from typing import Optional
|
10 |
from fastapi.staticfiles import StaticFiles
|
11 |
from dotenv import load_dotenv
|
12 |
+
from pydantic import BaseModel, Field, HttpUrl
|
13 |
from urllib.parse import quote
|
14 |
from pathlib import Path
|
15 |
import uuid
|
|
|
18 |
import time
|
19 |
from datetime import timedelta
|
20 |
import gc
|
21 |
+
from typing import Dict, Union, Literal
|
22 |
+
import urllib.parse
|
23 |
|
24 |
# Set up logging
|
25 |
logging.basicConfig(level=logging.INFO)
|
|
|
307 |
logger.error(f"Error searching tracks: {e}")
|
308 |
raise HTTPException(status_code=500, detail=str(e))
|
309 |
|
310 |
+
|
311 |
+
# --- Request Body Model ---
|
312 |
+
# Defines the expected structure and validation for the request body.
|
313 |
+
class SpotDlRequest(BaseModel):
|
314 |
+
url: HttpUrl = Field(..., description="The URL to be processed.")
|
315 |
+
quality: Literal["128", "320", "FLAC"] = Field(
|
316 |
+
...,
|
317 |
+
description="The desired quality. Currently, only '128' is supported for link generation."
|
318 |
+
)
|
319 |
+
|
320 |
+
# --- Response Body Model ---
|
321 |
+
# Defines the structure for a successful response.
|
322 |
+
class SpotDlResponse(BaseModel):
|
323 |
+
download_url: str
|
324 |
+
|
325 |
+
# --- Error Response Model ---
|
326 |
+
# Defines the structure for an error response.
|
327 |
+
class ErrorResponse(BaseModel):
|
328 |
+
detail: str
|
329 |
+
|
330 |
+
# --- API Endpoint ---
|
331 |
+
@app.post(
|
332 |
+
"/spot_dl",
|
333 |
+
response_model=SpotDlResponse,
|
334 |
+
responses={
|
335 |
+
400: {"model": ErrorResponse, "description": "Bad Request - Invalid input"},
|
336 |
+
422: {"model": ErrorResponse, "description": "Validation Error - Input data is not valid"}
|
337 |
+
},
|
338 |
+
summary="Generate SpotDL Link",
|
339 |
+
description="Accepts a URL and quality, returns a processed URL if quality is '128', "
|
340 |
+
"otherwise returns an error for higher qualities."
|
341 |
+
)
|
342 |
+
async def create_spot_dl_link(request: SpotDlRequest = Body(...)):
|
343 |
+
"""
|
344 |
+
Processes a URL and quality to generate a download link.
|
345 |
+
|
346 |
+
- **url**: The URL to process (must be a valid HTTP/HTTPS URL).
|
347 |
+
- **quality**: The desired quality. Must be one of "128", "320", "FLAC".
|
348 |
+
Currently, only "128" will result in a successful link generation.
|
349 |
+
"""
|
350 |
+
# Log the received request for debugging (optional)
|
351 |
+
print(f"Received request: url='{request.url}', quality='{request.quality}'")
|
352 |
+
|
353 |
+
# Check the quality
|
354 |
+
if request.quality == "128":
|
355 |
+
# URL-encode the input URL
|
356 |
+
encoded_url = urllib.parse.quote(str(request.url))
|
357 |
+
# Construct the target URL
|
358 |
+
output_url = f"https://velynapi.vercel.app/api/downloader/spotifydl?url{encoded_url}"
|
359 |
+
return SpotDlResponse(download_url=output_url)
|
360 |
+
elif request.quality == "320" or request.quality == "FLAC":
|
361 |
+
# If quality is 320 or FLAC, return an error as per requirements
|
362 |
+
raise HTTPException(
|
363 |
+
status_code=400,
|
364 |
+
detail=f"Quality '{request.quality}' is for Premium Users Only. '128' is allowed."
|
365 |
+
)
|
366 |
+
else:
|
367 |
+
# This case should ideally be caught by Pydantic's Literal validation,
|
368 |
+
# but as a fallback or for more general invalid quality values:
|
369 |
+
raise HTTPException(
|
370 |
+
status_code=400,
|
371 |
+
detail=f"Invalid quality value: '{request.quality}'. Allowed values are '128', '320', 'FLAC'."
|
372 |
+
)
|
373 |
+
|
374 |
# Spotify credentials from environment variables
|
375 |
'''SPOTIFY_USERNAME = os.getenv("SPOTIFY_USERNAME")
|
376 |
SPOTIFY_CREDENTIALS = os.getenv("SPOTIFY_CREDENTIALS")
|