From 43fb1cb6d50cd2bab56d736490ef02eded1fe831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Katariina=20J=C3=A4rvenm=C3=A4ki?= Date: Sun, 1 Mar 2026 12:40:14 +0200 Subject: [PATCH] Switch storage to persistent SQLite and add .env configuration --- .env | 1 + README.md | 2 ++ app/main.py | 51 +++++++++++++++++++++++++++++++++++++++++++++------ urls.db | Bin 0 -> 8192 bytes 4 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 .env create mode 100644 urls.db diff --git a/.env b/.env new file mode 100644 index 0000000..cec81f7 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +BASE_URL=http://localhost:8000 \ No newline at end of file diff --git a/README.md b/README.md index e73055c..ab6d762 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ URL-shortener project to showcase python use ## Create venv +```bash cd /opt/kjc/int/URL-shortener python3 -m venv venv source venv/bin/activate +``` ## Run locally ```bash diff --git a/app/main.py b/app/main.py index 4cf96c9..08de4b8 100644 --- a/app/main.py +++ b/app/main.py @@ -2,14 +2,32 @@ from fastapi import FastAPI, HTTPException from fastapi.responses import RedirectResponse from pydantic import BaseModel from app.utils import generate_short_code +from dotenv import load_dotenv +import os +import sqlite3 + +load_dotenv() app = FastAPI() -url_store = {} +DB_PATH = "urls.db" +def get_db_connection(): + conn = sqlite3.connect(DB_PATH) + return conn + +# URL schema class URLRequest(BaseModel): url: str +@app.on_event("startup") +def startup(): + conn = get_db_connection() + conn.execute('''CREATE TABLE IF NOT EXISTS urls + (id INTEGER PRIMARY KEY, short_code TEXT, original_url TEXT, clicks INTEGER)''') + conn.commit() + conn.close() + @app.get("/") def home(): return {"message": "URL Shortener API"} @@ -18,9 +36,30 @@ def home(): def shorten_url(request: URLRequest): short_code = generate_short_code() - url_store[short_code] = { - "original_url": request.url, - "clicks": 0 - } + conn = get_db_connection() + + while conn.execute("SELECT 1 FROM urls WHERE short_code = ?", (short_code,)).fetchone(): + short_code = generate_short_code() - return {"short_url": f"http://localhost:8000/{short_code}"} \ No newline at end of file + conn.execute("INSERT INTO urls (short_code, original_url, clicks) VALUES (?, ?, ?)", + (short_code, request.url, 0)) + conn.commit() + conn.close() + + return {"short_url": f"{os.getenv('BASE_URL', 'http://localhost:8000')}/{short_code}"} + +@app.get("/{short_code}") +def redirect_to_url(short_code: str): + conn = get_db_connection() + url_data = conn.execute("SELECT original_url, clicks FROM urls WHERE short_code = ?", (short_code,)).fetchone() + + if url_data is None: + raise HTTPException(status_code=404, detail="Shortened URL not found") + + original_url, clicks = url_data + + conn.execute("UPDATE urls SET clicks = ? WHERE short_code = ?", (clicks + 1, short_code)) + conn.commit() + conn.close() + + return RedirectResponse(url=original_url) \ No newline at end of file diff --git a/urls.db b/urls.db new file mode 100644 index 0000000000000000000000000000000000000000..c22e4bbb69df301c12a192c85a9bc3e8c091b129 GIT binary patch literal 8192 zcmeI#PfNov7zXg9Os0a=%McHP_oy&7|6Ih2Rt++oL%Rs>G`g;K!OXZe4m|Fw`7J#9 zO-#U^6ub&P4}C-XzDW+hTL-s2Wixs(#VoOO$Tk`0?39QxR&y1&s>0oi?^W^Nzoo|7 zC+{0>7Y`TAJqQFK009U<00Izz00bZa0SG|g9|