feat(api): Descriptive error messages (#21 - @AaronBenDaniel)

Co-authored-by: AaronBenDaniel <144371000+AaronBenDaniel@users.noreply.github.com>
This commit is contained in:
Dhanush R
2024-11-29 00:01:33 +05:30
committed by TheOnlyWayUp
3 changed files with 32 additions and 15 deletions
+1
View File
@@ -4,3 +4,4 @@ venv
data
*ipynb
build
.vscode
-9
View File
@@ -111,9 +111,6 @@ async def retrieve_story(story_id: int, cookies: Optional[dict] = None) -> dict:
async with session.get(
f"https://www.wattpad.com/api/v3/stories/{story_id}?fields=tags,id,title,createDate,modifyDate,language(name),description,completed,mature,url,isPaywalled,user(username),parts(id,title),cover"
) as response:
if not response.ok:
if response.status in [404, 400]:
return {}
response.raise_for_status()
body = await response.json()
@@ -132,9 +129,6 @@ async def fetch_part_content(part_id: int, cookies: Optional[dict] = None) -> st
async with session.get(
f"https://www.wattpad.com/apiv2/?m=storytext&id={part_id}"
) as response:
if not response.ok:
if response.status in [404, 400]:
return ""
response.raise_for_status()
body = await response.text()
@@ -151,9 +145,6 @@ async def fetch_cover(url: str, cookies: Optional[dict] = None) -> bytes:
else ClientSession(headers=headers, cookies=cookies)
) as session: # Don't cache requests with Cookies.
async with session.get(url) as response:
if not response.ok:
if response.status in [404, 400]:
return bytes()
response.raise_for_status()
body = await response.read()
+31 -6
View File
@@ -1,8 +1,14 @@
"""WattpadDownloader API Server."""
from typing import Optional
import tempfile
from pathlib import Path
from io import BytesIO
from enum import Enum
from fastapi import FastAPI
from aiohttp import ClientResponseError
from fastapi import FastAPI, Request
from fastapi.responses import FileResponse, HTMLResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
from ebooklib import epub
from create_book import (
retrieve_story,
@@ -13,9 +19,6 @@ from create_book import (
wp_get_cookies,
fetch_story_id,
)
import tempfile
from io import BytesIO
from fastapi.staticfiles import StaticFiles
app = FastAPI()
BUILD_PATH = Path(__file__).parent / "build"
@@ -36,6 +39,28 @@ def home():
return FileResponse(BUILD_PATH / "index.html")
@app.exception_handler(ClientResponseError)
def download_error_handler(request: Request, exception: ClientResponseError):
match exception.status:
case 400 | 404:
return HTMLResponse(
status_code=404,
content='This story does not exist, or has been deleted. Support is available on the <a href="https://discord.gg/P9RHC4KCwd" target="_blank">Discord</a>',
)
case 429:
# Rate-limit by Wattpad
return HTMLResponse(
status_code=429,
content='The website is overloaded. Please try again in a few minutes. Support is available on the <a href="https://discord.gg/P9RHC4KCwd" target="_blank">Discord</a>',
)
case _:
# Unhandled error
return HTMLResponse(
status_code=500,
content='Something went wrong. Yell at me on the <a href="https://discord.gg/P9RHC4KCwd" target="_blank">Discord</a>',
)
@app.get("/download/{download_id}")
async def handle_download(
download_id: int,
@@ -44,7 +69,6 @@ async def handle_download(
username: Optional[str] = None,
password: Optional[str] = None,
):
if username and not password or password and not username:
return HTMLResponse(
status_code=422,
@@ -69,10 +93,11 @@ async def handle_download(
case DownloadMode.part:
story_id = await fetch_story_id(download_id, cookies)
metadata = await retrieve_story(story_id, cookies)
book = epub.EpubBook()
metadata = await retrieve_story(story_id, cookies)
set_metadata(book, metadata)
await set_cover(book, metadata, cookies=cookies)
async for title in add_chapters(