Files
minxa.lol/app/routes/shortener.py

47 lines
1.5 KiB
Python

from fastapi import APIRouter, HTTPException
from fastapi.responses import RedirectResponse
from sqlalchemy.exc import IntegrityError
from app.db import database
from app.models import Url
from app.schemas import UrlPayload
from app.services import encoder
router = APIRouter()
@router.get("/{shortcode}")
async def redirect_to_original_url(shortcode: str):
if not encoder.is_valid(shortcode):
raise HTTPException(status_code=400, detail="Shortcode is not valid")
query = Url.__table__.select().where(Url.shortcode == shortcode)
url_result = await database.fetch_one(query)
if url_result:
return RedirectResponse(url=url_result.url, status_code=302)
else:
raise HTTPException(status_code=404, detail="Shortcode not found")
@router.post("/shorten")
async def create_url_shortcode(url_payload: UrlPayload):
original_url = str(url_payload.url)
query = "SELECT nextval('urls_id_seq')"
next_id = await database.fetch_val(query)
shortcode = encoder.encode(next_id)
try:
query = Url.__table__.insert().values({
"id": next_id,
"url": original_url,
"shortcode": shortcode
})
await database.execute(query)
return {"shortcode": shortcode, "original_url": original_url}
except IntegrityError as e:
if 'shortcode' in str(e):
raise HTTPException(status_code=409, detail="Shortcode already in use")
else:
raise HTTPException(status_code=500, detail="Internal Server Error")