feat(api): Add caching
This commit is contained in:
+10
-4
@@ -1,16 +1,22 @@
|
|||||||
import aiohttp, asyncio
|
import asyncio
|
||||||
from ebooklib import epub
|
from ebooklib import epub
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import re
|
import re
|
||||||
|
from aiohttp_client_cache import CachedSession, FileBackend
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache = FileBackend(
|
||||||
|
use_temp=True,
|
||||||
|
expire_after=43200, # 12 hours
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def retrieve_story(story_id: int, retry=True) -> dict:
|
async def retrieve_story(story_id: int, retry=True) -> dict:
|
||||||
"""Taking a story_id, return its information from the Wattpad API."""
|
"""Taking a story_id, return its information from the Wattpad API."""
|
||||||
async with aiohttp.ClientSession(headers=headers) as session:
|
async with CachedSession(headers=headers, cache=cache) as session:
|
||||||
try:
|
try:
|
||||||
async with session.get(
|
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"
|
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"
|
||||||
@@ -31,7 +37,7 @@ async def retrieve_story(story_id: int, retry=True) -> dict:
|
|||||||
|
|
||||||
async def fetch_part_content(part_id: int) -> str:
|
async def fetch_part_content(part_id: int) -> str:
|
||||||
"""Return the HTML Content of a Part."""
|
"""Return the HTML Content of a Part."""
|
||||||
async with aiohttp.ClientSession(headers=headers) as session:
|
async with CachedSession(headers=headers, cache=cache) as session:
|
||||||
try:
|
try:
|
||||||
async with session.get(
|
async with session.get(
|
||||||
f"https://www.wattpad.com/apiv2/?m=storytext&id={part_id}"
|
f"https://www.wattpad.com/apiv2/?m=storytext&id={part_id}"
|
||||||
@@ -52,7 +58,7 @@ async def fetch_part_content(part_id: int) -> str:
|
|||||||
|
|
||||||
async def fetch_cover(url: str) -> bytes:
|
async def fetch_cover(url: str) -> bytes:
|
||||||
"""Fetch image bytes."""
|
"""Fetch image bytes."""
|
||||||
async with aiohttp.ClientSession(headers=headers) as session:
|
async with CachedSession(headers=headers, cache=cache) as session:
|
||||||
try:
|
try:
|
||||||
async with session.get(url) as response:
|
async with session.get(url) as response:
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
|
|||||||
+17
-4
@@ -1,11 +1,19 @@
|
|||||||
|
from pathlib import Path
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import FileResponse, StreamingResponse
|
||||||
from ebooklib import epub
|
from ebooklib import epub
|
||||||
from create_book import retrieve_story, set_cover, set_metadata, add_chapters
|
from create_book import retrieve_story, set_cover, set_metadata, add_chapters, slugify
|
||||||
import tempfile
|
import tempfile
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
BUILD_PATH = Path(__file__).parent / "build"
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def home():
|
||||||
|
return FileResponse(BUILD_PATH / "index.html")
|
||||||
|
|
||||||
|
|
||||||
@app.get("/download/{story_id}")
|
@app.get("/download/{story_id}")
|
||||||
@@ -37,11 +45,16 @@ async def download_book(story_id: int):
|
|||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
BytesIO(book_data),
|
BytesIO(book_data),
|
||||||
media_type="application/epub+zip",
|
media_type="application/epub+zip",
|
||||||
headers={"Content-Disposition": f'attachment; filename="book_{story_id}.epub"'},
|
headers={
|
||||||
|
"Content-Disposition": f'attachment; filename="{slugify(data["title"])}_{story_id}.epub"' # Thanks https://stackoverflow.com/a/72729058
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
app.mount("/", StaticFiles(directory=BUILD_PATH), "static")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=80)
|
uvicorn.run(app, host="0.0.0.0", port=8084)
|
||||||
|
|||||||
Reference in New Issue
Block a user