1- # 🔗 tiny URL Generator
1+ # Tiny URL Generator
22
33> A modern, Bitly-style tiny URL web application built with FastAPI & MongoDB
44
99
1010---
1111
12- ## 📌 Overview
12+ ## Overview
1313
1414** tiny URL** is a sleek, fast, and modern URL shortening platform built using ** FastAPI** , and ** MongoDB** .
1515It converts long URLs into short, shareable links — just like Bitly.
1616
17- The project supports both :
17+ The project supports:
1818
1919- 🚀 ** FastAPI REST API** (developers / integrations)
2020
2121---
2222
23- ## 🚀 Features
23+ ## Features
2424
25- ### 🔹 User Features
25+ ### User Features
2626
2727- Convert long URLs into short, unique codes
2828- Default checkbox QR code generation
2929- Clean Bitly-style result card
30+ - Copy & share buttons
3031- Download URL button
3132- Share URL
3233- Copy button with animation
@@ -36,31 +37,32 @@ The project supports both:
3637- Fully responsive design
3738- Recent URLs page
3839
39- ---
40-
41- ### 🔹 API & Developer Features
40+ ### API & Developer Features
4241
4342- REST API for URL shortening
4443- API version endpoint
4544- Swagger / OpenAPI documentation
4645- API landing page
47- - CLI to run UI or API independently
46+ - Cache layer for fast redirects
47+ - Graceful offline mode (no DB required)
48+ - Clean startup lifecycle using FastAPI lifespan
49+ - Optional MongoDB dependency
4850
4951---
5052
51- ## 🧠 Short Code Generation Algorithm
53+ ## Short Code Generation Algorithm
5254
53- The app uses a ** Random Alphanumeric Short Code Generator** .
55+ The app uses a Random Alphanumeric Short Code Generator.
5456
55- ### 🔍 Algorithm Details
57+ ### Algorithm Details
5658
57- - Uses Python’s ` string.ascii_letters + string.digits `
59+ - Uses ` string.ascii_letters + string.digits `
5860- Randomly picks characters
5961- Generates a 6-character short ID
60- - Checks MongoDB to avoid duplicates
61- - If duplicate → regenerate automatically
62+ - Checks MongoDB for collisions (if DB is enabled)
63+ - Automatically regenerates on collision
6264
63- ### 🔢 Example
65+ ### Example
6466
6567``` python
6668import random, string
@@ -70,7 +72,7 @@ def generate_code(length=6):
7072 return ' ' .join(random.choice(chars) for _ in range (length))
7173```
7274
73- 🗃️ Tech Stack
75+ ---
7476
7577| Layer | Technology |
7678| ----------- | --------------------- |
@@ -82,36 +84,61 @@ def generate_code(length=6):
8284| CLI | Click |
8385| Data | JSON |
8486
85- 📁 Project Folder Structure
87+ | Layer | Technology |
88+ | ----------- | --------------------- |
89+ | UI Backend | FastAPI |
90+ | API Backend | FastAPI |
91+ | Database | MongoDB (Optional) |
92+ | Frontend | HTML, CSS, Vanilla JS |
93+ | QR Code | qrcode + Pillow |
94+ | API Server | Uvicorn |
95+ | Validation | Pydantic v2 |
96+ | Env Mgmt | python-dotenv |
97+ | Tooling | Poetry |
98+
99+ ---
100+
101+ ## Project Folder Structure
86102
87103``` text
88104Directory structure:
89105tiny/
90106├── CHANGELOG.md
91107├── LICENSE
92- ├── README.md
93108├── app/
94109│ ├──__init__.py
95- │ ├── app .py
110+ │ ├── main .py
96111│ ├── cli.py
97112│ ├── api/
113+ | | └──__init__.py
98114│ │ └── fast_api.py
99115| ├──assets/images
100116│ ├── db/
101117| | └──__init__.py
102118| | └──data.py
119+ | ├── static/
120+ | | └── images
121+ | | └── qr
122+ | | └── style.css
123+ | ├── templates/
124+ | | └── index.html
125+ | | └── recent.html
103126│ ├── utils/
104- | | └──__init__.py
105- | | └──_version.py
127+ | | └── __init__.py
128+ | | └── _version.py
129+ | | └── config.py
106130| | └── helper.py
107131| | └── lint.py
108- │ ├── static/
109- | | └── images
110- | | └── qr
111- │ └── templates/
112- | └── index.html
113- | └── recent.html
114- | └── admin.html
132+ | | └── qr.py
133+ |
134+ ├── docs/
135+ | └── build-test.md
136+ | └─ run_with_curl.md
137+ |
138+ ├── request/
139+ | └── mixed.json
140+ | └── single.json
141+ | └── urls.json
115142├── pyproject.toml
116143| └── poetry.lock
117144├──README.md
@@ -128,73 +155,120 @@ tiny/
128155
129156``` sh
130157poetry install
131- poetry install --all-extras --with dev
132158```
133159
134- create ` .env ` file and add content from ` .env.local ` file anc change value according to your project
160+ ### 3. Install with MongoDB Support (Optional)
135161
136- Note: according to your port change the port in ` frontend/vite.config.ts ` and ` VITE_API_URL `
162+ ``` sh
163+ poetry install --with mongodb
164+ ```
165+
166+ ---
167+
168+ ## Running the App
169+
170+ ``` sh
171+ poetry run uvicorn app.main:app --reload
172+ ```
173+
174+ or
137175
138176``` sh
139- poetry shell
140177poetry run tiny dev
141178```
142179
143- ## Lint
180+ Open:
181+ http://127.0.0.1:8000
144182
145- to lint the code run
183+ ---
146184
147- ``` sh
148- poetry run black .
149- # then
150- poetry run ruff .
185+ ## Environment Configuration
186+
187+ ```
188+ ENV=development
189+ DOMAIN=http://127.0.0.1:8000
190+ MONGO_URI=mongodb://<user>:<password>@localhost:27017/tiny_url?authSource=tiny_url
191+ DATABASE_NAME=tiny_url
151192```
152193
153- open [ http://localhost:8000 ] ( http://127.0.0.1:8000 )
194+ Supported env files:
154195
155- 🔗 How the App Works
156- ▶️ User Flow
157- 1.User enters a long URL
196+ - .env.development
197+ - .env.local
198+ - .env (production)
199+
200+ ---
158201
159- 2.System sanitizes + validates input
202+ ## Offline Mode (No Database)
160203
161- 3.Generates a unique short code
204+ TinyURL supports graceful offline mode.
162205
163- 4.Saves it in MongoDB
206+ ### What works
164207
165- 5.Displays short URL + QR code
208+ - App starts normally
209+ - UI loads
210+ - Short URLs are generated
211+ - QR codes are generated
166212
167- 5.Clicking the short URL:
213+ ### What is disabled
168214
169- - Increases visit count
215+ - Recent URLs page
216+ - Persistent redirects after restart
217+ - Visit count tracking
170218
171- - Redirects to original URL
219+ Offline Mode activates automatically when:
172220
173- ## 🔌 REST API (FastAPI)
221+ - MongoDB is down
222+ - OR pymongo is not installed
223+ - OR MONGO_URI is missing/invalid
174224
175- Tiny provides a FastAPI-based REST API for programmatic URL shortening.
225+ Log message:
176226
177- ▶ Run API Server
227+ ```
228+ ⚠️ MongoDB connection failed. Running in NO-DB mode.
229+ ```
230+
231+ ---
232+
233+ ## Switching Modes
234+
235+ ### With MongoDB
178236
179237``` sh
180- poetry run tiny api
238+ poetry install --with mongodb
239+ sudo systemctl start mongod
240+ poetry run tiny dev
181241```
182242
183- 📍 API Base URL
243+ ### Without MongoDB
184244
185- open [ http://localhost:8001 ] ( http://127.0.0.1:8001 )
245+ ``` sh
246+ sudo systemctl stop mongod
247+ poetry run tiny dev
248+ ```
186249
187- 🌙 tiny API Landing Page
250+ or
188251
189- open [ http://localhost:8001 ] ( http://127.0.0.1:8001 )
252+ ``` sh
253+ poetry run pip uninstall pymongo
254+ poetry run tiny dev
255+ ```
256+
257+ ---
258+
259+ ## REST API (FastAPI)
190260
191- 📘 Swagger Docs
261+ ### API Base URL
192262
193- open [ http://localhost:8001/docs ] ( http:// 127.0.0.1:8001/docs )
263+ http://127.0.0.1:8000/api
194264
195- ➤ Shorten URL
265+ ### Swagger Docs
196266
197- POST ` /api/shorten `
267+ http://127.0.0.1:8000/api/docs
268+
269+ ### Shorten URL
270+
271+ POST /api/shorten
198272
199273Request:
200274
@@ -208,24 +282,53 @@ Response:
208282
209283``` json
210284{
211- "input_url" : " https://examplecom " ,
212- "output_url" : " http://127.0.0.1:8001 /AbX92p" ,
285+ "input_url" : " https://example.com " ,
286+ "output_url" : " http://127.0.0.1:8000 /AbX92p" ,
213287 "created_on" : " 2026-01-03T13:25:10+00:00"
214288}
215289```
216290
217- ➤ API Version
291+ ### API Version
218292
219- GET ` /api/version `
293+ GET /api/version
220294
221295Response:
222296
223297``` json
224298{
225- "version" : " 0.0.1 "
299+ "version" : " 0.1.0 "
226300}
227301```
228302
303+ ---
304+
305+ ## Troubleshooting
306+
307+ ### Mongo auth error
308+
309+ Encode special chars:
310+
311+ @ ? %40
312+
313+ Example:
314+
315+ ```
316+ MONGO_URI=mongodb://user%40gmail.com:Pass%40123@localhost:27017/tiny_url?authSource=tiny_url
317+ ```
318+
319+ ---
320+
321+ ## WSL Notes
322+
323+ ``` sh
324+ sudo systemctl start mongod
325+ poetry run uvicorn app.main:app --reload
326+ ```
327+
328+ ---
329+
330+ ## License
331+
229332📜Docs
230333[ run_with_curl] ( run_with_curl )
231334
0 commit comments