Implement image fetching and storage functionality with logging
This commit is contained in:
@@ -1,8 +1,31 @@
|
||||
from fastapi import FastAPI
|
||||
import aiohttp
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.responses import FileResponse
|
||||
import asyncmy
|
||||
import asyncio
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
from contextlib import asynccontextmanager
|
||||
import logging
|
||||
|
||||
load_dotenv()
|
||||
|
||||
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
|
||||
log_formatter = logging.Formatter(
|
||||
fmt="%(asctime)s [%(levelname)s] %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
|
||||
file_handler = logging.FileHandler("data/api.log", encoding="utf-8")
|
||||
file_handler.setFormatter(log_formatter)
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(log_formatter)
|
||||
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, log_level, logging.INFO),
|
||||
handlers=[file_handler, console_handler],
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def connect_db(app: FastAPI):
|
||||
@@ -15,18 +38,34 @@ async def connect_db(app: FastAPI):
|
||||
minsize=5,
|
||||
maxsize=20
|
||||
)
|
||||
await create_tables(app.state.pool)
|
||||
task = asyncio.create_task(fetch_images())
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
app.state.pool.close()
|
||||
await app.state.pool.wait_closed()
|
||||
|
||||
app = FastAPI(lifespan=connect_db)
|
||||
|
||||
@asynccontextmanager
|
||||
async def get_connection():
|
||||
async with app.state.pool.acquire() as conn:
|
||||
yield conn
|
||||
async def create_tables(pool):
|
||||
async with pool.acquire() as conn:
|
||||
async with conn.cursor() as cursor:
|
||||
await cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS images (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
url VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
subreddit VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
await conn.commit()
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
@@ -34,5 +73,30 @@ async def root():
|
||||
|
||||
@app.get("/random")
|
||||
async def get_random_bnuy():
|
||||
async with get_connection() as conn:
|
||||
return {"message": "here could be a bnuy, if I would've implemented it"}
|
||||
return {"message": "here could be a bnuy, if I would've implemented it"}
|
||||
|
||||
@app.get("/images/{filename}")
|
||||
async def get_image(filename: str):
|
||||
async with app.state.pool.acquire() as conn:
|
||||
async with conn.cursor() as cursor:
|
||||
await cursor.execute("SELECT filename FROM images WHERE filename = %s", (filename,))
|
||||
result = await cursor.fetchone()
|
||||
if result:
|
||||
filepath = os.path.join("data/images", result[0])
|
||||
if os.path.exists(filepath):
|
||||
return FileResponse(filepath)
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Image file not found")
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Image not found")
|
||||
|
||||
async def fetch_images():
|
||||
from collector import save_picture
|
||||
while True:
|
||||
try:
|
||||
logging.info("Starting image collection...")
|
||||
await save_picture(app.state.pool)
|
||||
logging.info("Image collection completed. Sleeping for 1 hour...")
|
||||
except Exception as e:
|
||||
logging.error(f"Error during image collection: {e}")
|
||||
await asyncio.sleep(86400) # Sleep for 24 hours
|
||||
Reference in New Issue
Block a user