link_shortener/app/main.py
2024-04-05 16:23:27 +05:00

57 lines
1.7 KiB
Python

import time
from urllib.parse import urljoin
from fastapi import FastAPI, status, HTTPException
from fastapi.responses import RedirectResponse
import redis
from app.config import settings
from app.dao import URLsDAO
from app.migrations.shemas import SURL, SNewUrl, SGetStats
app = FastAPI(
title="Сокращатель ссылок",
)
r = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB)
@app.post("/zip_url", response_model=SNewUrl)
async def zip_url(url: SURL):
url = str(url.url)
url_hash = await URLsDAO.add_new_url(original_url=url)
new_url_path = urljoin(settings.SHORTENER_HOST, str(url_hash))
return {"new_url_path": new_url_path}
@app.get("/{url_hash}", response_class=RedirectResponse, status_code=status.HTTP_307_TEMPORARY_REDIRECT)
async def redirect(url_hash: int):
if r.exists(str(url_hash)):
url_bytes = r.get(str(url_hash))
url = url_bytes.decode('utf-8')
else:
urls = await URLsDAO.find_by_hash(url_hash)
if not urls:
raise HTTPException(status_code=404, detail="Этой ссылки ещё не существует")
url = urls.original_url
r.set(str(url_hash), url)
r.expire(str(url_hash), 60)
list_key = f"visit_times:{url_hash}"
timestamp = int(time.time())
r.lpush(list_key, timestamp)
return RedirectResponse(url=url)
@app.get("/stats/{url_hash}", response_model=SGetStats)
async def get_stats(url_hash: int):
list_key = f"visit_times:{url_hash}"
if r.exists(list_key):
timestamps = r.lrange(list_key, 0, -1)
visit_times = len(timestamps)
return {"visit_times": visit_times, "timestamps": timestamps}
return {"visit_times": 0, "timestamps": []}