Skip to content

Commit 7325dae

Browse files
Merge pull request #5 from recursivezero/features/RTY-260001
feat: add FastAPI backend and API documentation
2 parents 9f22d1b + 5a9715a commit 7325dae

26 files changed

Lines changed: 1260 additions & 375 deletions

.env.local

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
MONGO_URI=mongodb://admin:1234@127.0.0.1:27017/?retryWrites=true&w=majority
1+
DOMAIN="https://rzro.link"
2+
PORT=8001
3+
API_VERSION="/api/v1"
4+
5+
MONGO_URI="mongodb://localhost:27017/?retryWrites=true&w=majority&appName=tiny"
6+
DATABASE_NAME="tiny"

.poetryignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Ignore Python cache and venv
2+
3+
**pycache**/
4+
_.py[cod]
5+
_.so
6+
\*.egg-info/
7+
.venv/
8+
venv/
9+
env/
10+
11+
## Ignore build output
12+
13+
build/
14+
dist/
15+
_.egg
16+
_.whl
17+
18+
## Ignore IDE/editor settings
19+
20+
.vscode/
21+
.idea/
22+
_.swp
23+
_.bak
24+
25+
## Ignore local config and test logs
26+
27+
.env
28+
.env.\*
29+
\*.log
30+
31+
## Ignore test data/output
32+
33+
tests/
34+
_.test._
35+
debug*\*.py
36+
trace*\*.py
37+
38+
## Ignore OS files
39+
40+
.DS_Store
41+
Thumbs.db

README.md

Lines changed: 108 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# 🔗 Short URL Generator
1+
# 🔗 tiny URL Generator
22

3-
> A modern, Bitly-style URL shortening web application built with Flask & MongoDB\_
3+
> A modern, Bitly-style tiny URL web application built with Flask, FastAPI & MongoDB
44
55
![Python](https://img.shields.io/badge/Python-3.10-blue.svg)
66
![Flask](https://img.shields.io/badge/Flask-Web%20Framework-black.svg)
@@ -12,21 +12,13 @@
1212

1313
## 📌 Overview
1414

15-
**Short URL Generator** is a sleek, fast and modern URL shortening platform built using Flask and MongoDB.
15+
**tiny URL** is a sleek, fast, and modern URL shortening platform built using **Flask**, **FastAPI**, and **MongoDB**.
1616
It converts long URLs into short, shareable links — just like Bitly.
1717

18-
It supports:
18+
The project supports both:
1919

20-
- URL shortening
21-
- QR Code generation (Short URL or Original URL)
22-
- Visit counting
23-
- MongoDB database
24-
- JSON import/export (Admin Panel)
25-
- Input validation + sanitization
26-
- Light/Dark Mode with memory
27-
- Glassmorphism UI
28-
- Copy-to-clipboard button
29-
- Delete confirmation popup
20+
- 🌐 **Flask Web UI** (end users)
21+
- 🚀 **FastAPI REST API** (developers / integrations)
3022

3123
---
3224

@@ -35,26 +27,27 @@ It supports:
3527
### 🔹 User Features
3628

3729
- Convert long URLs into short, unique codes
38-
- default checkbox QR code generation
30+
- Default checkbox QR code generation
3931
- Clean Bitly-style result card
40-
- Download URl button
41-
- share URL
32+
- Download URL button
33+
- Share URL
4234
- Copy button with animation
4335
- Smooth URL validation and sanitization
4436
- Auto Dark/Light Mode (saves preference)
4537
- Mobile-friendly QR Codes
4638
- Fully responsive design
47-
- Recent Table
39+
- Recent URLs page
40+
- Glassmorphism UI
41+
42+
---
4843

49-
### 🔹 Admin Panel Features
44+
### 🔹 API & Developer Features
5045

51-
- View all shortened URLs
52-
- Delete URLs (with confirmation popup)
53-
- Import URLs using JSON file
54-
- Export database to JSON
55-
- Shows JSON format guide
56-
- Strict JSON validation
57-
- Recent Table
46+
- REST API for URL shortening
47+
- API version endpoint
48+
- Swagger / OpenAPI documentation
49+
- API landing page
50+
- CLI to run UI or API independently
5851

5952
---
6053

@@ -82,56 +75,55 @@ def generate_code(length=6):
8275

8376
🗃️ Tech Stack
8477

85-
| Layer | Technology |
86-
| ------------ | ---------------------------------------- |
87-
| Backend | Flask (Python) |
88-
| Database | MongoDB |
89-
| Frontend | HTML, CSS (Glassmorphism), Vanilla JS |
90-
| QR Generator | `qrserver.com` API |
91-
| Hosting | Local / PythonAnywhere / Render / Heroku |
92-
| Component | Technology |
93-
| UI Style | Glassmorphism, Gradient UI |
94-
| Data Format | JSON |
78+
| Layer | Technology |
79+
| ----------- | -------------------------- |
80+
| UI Backend | Flask |
81+
| API Backend | FastAPI |
82+
| Database | MongoDB |
83+
| Frontend | HTML, CSS, Vanilla JS |
84+
| UI Style | Glassmorphism, Gradient UI |
85+
| API Server | Uvicorn |
86+
| Validation | Pydantic v2 |
87+
| CLI | Click |
88+
| Data | JSON |
9589

9690
📁 Project Folder Structure
9791

9892
```text
93+
Directory structure:
94+
tiny/
9995
├── CHANGELOG.md
10096
├── LICENSE
10197
├── README.md
10298
├── app/
103-
│ ├── __init__.py
104-
│ ├── admin.py
105-
│ ├── api/
106-
│ │ ├── __init__.py
107-
│ │ └── fast_api.py
99+
│ ├──__init__.py
108100
│ ├── app.py
109-
│ ├── assets/
110-
│ │ └── images/
111101
│ ├── cli.py
102+
│ ├── api/
103+
│ │ └── fast_api.py
104+
| ├──assets/images
112105
│ ├── db/
113-
│ │ ├── __init__.py
114-
│ │ └── data.py
115-
│ ├── qr.py
106+
| | └──__init__.py
107+
| | └──data.py
108+
│ ├── utils/
109+
| | └──__init__.py
110+
| | └──_version.py
111+
| | └── helper.py
112+
| | └── lint.py
116113
│ ├── static/
117-
│ │ ├── images/
118-
│ │ │ ├── logo.png
119-
│ │ └── style.css
120-
│ ├── templates/
121-
│ │ ├── admin.html
122-
│ │ ├── coming-soon.html
123-
│ │ ├── index.html
124-
│ │ └── recent.html
125-
│ └── utils/
126-
│ ├── __init__.py
127-
│ ├── helper.py
128-
│ └── lint.py
129-
├── mypy.ini
130-
├── package.json
131-
├── poetry.lock
114+
| | └── images
115+
| | └── qr
116+
│ └── templates/
117+
| └── index.html
118+
| └── recent.html
119+
| └── admin.html
132120
├── pyproject.toml
133-
├── requirements.txt
134-
└── tiny.code-workspace
121+
| └── poetry.lock
122+
├──README.md
123+
| └── CHANGELOG.md
124+
| └── requirements.txt
125+
├── tiny.code-workspace
126+
└── .gitignore
135127
136128
```
137129

@@ -167,67 +159,80 @@ open [http://localhost:8000](http://127.0.0.1:8000)
167159

168160
🔗 How the App Works
169161
▶️ User Flow
162+
1.User enters a long URL
163+
164+
2.System sanitizes + validates input
170165

171-
User enters a long URL
166+
3.Generates a unique short code
172167

173-
System sanitizes + validates input
168+
4.Saves it in MongoDB
174169

175-
Generates a unique short code
170+
5.Displays short URL + QR code
176171

177-
Saves it in MongoDB
172+
5.Clicking the short URL:
178173

179-
Displays short URL + QR code
174+
- Increases visit count
180175

181-
When someone clicks the short link →
176+
- Redirects to original URL
182177

183-
Visit count increases
178+
## 🔌 REST API (FastAPI)
184179

185-
User redirected to original URL <http://127.0.0.1:5000/abc123> Someone clicks it → visit count increases → redirected to original URL
180+
Tiny provides a FastAPI-based REST API for programmatic URL shortening.
186181

187-
🧩 Short Code Generation Algorithm
182+
▶ Run API Server
183+
184+
```sh
185+
poetry run tiny api
186+
```
188187

189-
Uses characters: a–z, A–Z, 0–9
188+
📍 API Base URL
190189

191-
Random 6-character string
190+
open [http://localhost:8001](http://127.0.0.1:8001)
192191

193-
Ensures uniqueness by checking database
192+
🌙 tiny API Landing Page
194193

195-
If code exists → generate again
194+
open [http://localhost:8001](http://127.0.0.1:8001)
196195

197-
Saves final unique code
196+
📘 Swagger Docs
198197

199-
🗄️ Database Schema (SQLAlchemy Model)
198+
open [http://localhost:8001/docs](http://127.0.0.1:8001/docs)
200199

201-
| Field | Type | Description |
202-
| ------------ | --------- | ------------------ |
203-
| id | Integer | Primary Key |
204-
| short_code | String | Unique short ID |
205-
| original_url | String | Long URL |
206-
| created_at | DateTime | Timestamp |
207-
| visit_count | Integer | Click count |
208-
| meta | JSON Text | Title, notes, tags |
200+
➤ Shorten URL
209201

210-
📦 JSON Import Format (Admin)
202+
POST `/api/shorten`
211203

212-
Example JSON file for bulk import:
204+
Request:
213205

214-
[
206+
```json
215207
{
216-
"short_code": "abc123",
217-
"original_url": "https://example.com",
218-
"created_at": "2025-11-18T23:59:00Z",
219-
"visit_count": 42,
220-
"meta": {
221-
"title": "Example Page",
222-
"notes": "Optional notes",
223-
"tags": ["test", "demo"]
208+
"url": "https://example.com"
224209
}
210+
```
211+
212+
Response:
213+
214+
```json
215+
{
216+
"input_url": "https://examplecom",
217+
"output_url": "http://127.0.0.1:8001/AbX92p",
218+
"created_on": "2026-01-03T13:25:10+00:00"
225219
}
226-
]
220+
```
221+
222+
➤ API Version
227223

228-
📤 Export Format
224+
GET `/api/version`
225+
226+
Response:
227+
228+
```json
229+
{
230+
"version": "0.0.1"
231+
}
232+
```
229233

230-
Admin can download all URLs in the same JSON format.
234+
📜Docs
235+
[run_with_curl](run_with_curl)
231236

232237
Screenshots:
233238
Home Page:
@@ -236,9 +241,9 @@ Home Page:
236241
![home page](app/assets/images/valid.png)
237242
![home layout](app/assets/images/short_url.png)
238243
![recent](app/assets/images/recent.png)
239-
Admin Page:
240-
![admin](app/assets/images/admin.png)
241-
![Jsonformat](app/assets/images/admin2.png)
244+
tiny API Page:
245+
![API](app/assets/images/API_page.png)
246+
![API1](app/assets/images/api_page2.png)
242247

243248
📜License
244249
[License](LICENSE)

app/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from app.utils._version import get_version
2+
3+
__version__ = get_version()

app/api/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from app.utils._version import get_version
2+
3+
__version__ = get_version()

0 commit comments

Comments
 (0)