Skip to content

Commit a409264

Browse files
committed
Scalable URL Shortener API built with FastAPI
0 parents  commit a409264

11 files changed

Lines changed: 101 additions & 0 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Deploy to EC2
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v2
15+
16+
- name: SSH into EC2 and deploy with Docker Compose
17+
uses: appleboy/ssh-action@master
18+
with:
19+
host: ${{ secrets.EC2_HOST }}
20+
username: ${{ secrets.EC2_USER }}
21+
key: ${{ secrets.EC2_KEY }}
22+
script: |
23+
cd ~/app
24+
git pull origin main
25+
docker compose down
26+
docker compose up -d --build

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
venv/
2+
__pycache__/
3+
*.pyc
4+
.DS_Store

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# 1. Python base image
2+
FROM python:3.10-slim
3+
4+
# 2. Çalışma dizinini oluştur ve ayarla
5+
WORKDIR /app
6+
7+
# 3. Gereken dosyaları kopyala
8+
COPY . .
9+
10+
# 4. Gerekli paketleri yükle
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
# 5. Uvicorn ile başlat
14+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

README.md

Whitespace-only changes.

app/database.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Geçici bellek – ileride DB eklenecek
2+
url_db = {}

app/main.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from fastapi import FastAPI
2+
from fastapi.responses import RedirectResponse
3+
from app.schemas import URLRequest
4+
from app.services import generate_short_code, save_url, get_url
5+
6+
app = FastAPI()
7+
8+
@app.post("/shorten")
9+
def shorten_url(request: URLRequest):
10+
short_code = generate_short_code()
11+
save_url(short_code, request.long_url)
12+
return {"short_url": f"http://localhost:8001/{short_code}"}
13+
14+
@app.get("/{short_code}")
15+
def redirect_url(short_code: str):
16+
long_url = get_url(short_code)
17+
if long_url:
18+
return RedirectResponse(url=long_url)
19+
return {"error": "URL not found"}

app/schemas.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from pydantic import BaseModel
2+
3+
class URLRequest(BaseModel):
4+
long_url: str
5+
6+

app/services.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import string
2+
import random
3+
from app.database import url_db # veritabani gibi davranan dict
4+
5+
#kisa kod uretici
6+
def generate_short_code(length=6):
7+
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
8+
9+
# url kaydetme
10+
def save_url(short_code, long_url):
11+
url_db[short_code] = long_url
12+
13+
# url getirme (yonlendirme icin)
14+
def get_url(short_code):
15+
return url_db.get(short_code)
16+

app/utils.py

Whitespace-only changes.

requirements.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
annotated-types==0.7.0
2+
anyio==4.9.0
3+
click==8.2.1
4+
exceptiongroup==1.3.0
5+
fastapi==0.116.1
6+
h11==0.16.0
7+
idna==3.10
8+
pydantic==2.11.7
9+
pydantic_core==2.33.2
10+
sniffio==1.3.1
11+
starlette==0.47.2
12+
typing-inspection==0.4.1
13+
typing_extensions==4.14.1
14+
uvicorn==0.35.0

0 commit comments

Comments
 (0)