Skip to content

EmiSadler/URL_shortener

Repository files navigation

URL Shortener

A full-stack URL shortener application with a Python Flask backend and React frontend.

πŸš€ Live Demo: https://url-shortener.sadlers.cloud/

Features

Backend (Flask + SQLite)

  • βœ… Create short URLs from long URLs
  • βœ… Redirect short URLs to original URLs
  • βœ… Multiple short URLs allowed for same long URL (for tracking)
  • βœ… Base62 encoding for short, readable URLs
  • βœ… SQLite database for persistence
  • βœ… IDs start at 10000 for better-looking short URLs
  • βœ… CORS support for frontend integration
  • βœ… Comprehensive error handling and validation

Frontend (React)

  • βœ… Modern, responsive UI with gradient background
  • βœ… Real-time URL validation
  • βœ… Copy shortened URL to clipboard
  • βœ… Test shortened URLs directly in the interface
  • βœ… Loading states and error handling
  • βœ… Success notifications

Quick Start

Option 1: Use the Development Startup Script (Recommended)

./start-dev.sh

This will start both the backend (port 8000) and frontend (port 3000) automatically.

Option 2: Manual Setup

Backend Setup

  1. Set up Virtual Environment

     python3 -m venv venv
     source venv/bin/activate
  2. Install Python dependencies:

    pip install -r requirements.txt
  3. Start the backend:

    python main.py

Frontend Setup

  1. Install Node.js dependencies:

    cd frontend
    npm install
  2. Start the React development server:

    npm start

Application URLs

API Testing

1. Health Check

Test if the server is running:

curl http://localhost:8000/

Expected Response:

{ "message": "URL Shortener API is running!" }

2. Create Short URL

Convert a long URL to a short one:

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.google.com"}' \
  http://localhost:8000/shorten

Expected Response:

{ "short_url": "2Bi" }

Note: Your actual short URL will vary but will be 3+ characters

3. Test Redirect

Use the short URL to redirect to the original:

curl -L http://localhost:8000/2Bi

This will redirect you to https://www.google.com (showing in the CLI the HTML content from Google's homepage)

alternatively:

curl -I http://localhost:8000/2Bi

This will show you the redirect response instead of following it (cleaner in the CLI)

4. Test Multiple URLs

Create several short URLs:

# GitHub
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"url": "https://github.com/EmiSadler/URL_shortener"}' \
  http://localhost:8000/shorten

# Bootcamp Simulator
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"url": "https://bootcampsim.netlify.app/"}' \
  http://localhost:8000/shorten

5. Error Handling

Test with missing URL:

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{}' \
  http://localhost:8000/shorten

Test with non-existent short URL:

curl http://localhost:8000/xyz123

Production Build

Build Frontend for Production

./build-prod.sh

Or manually:

cd frontend
npm run build

Serve Production Build

Option 1 - Using a static file server:

npm install -g serve
serve -s frontend/build -l 3000

Option 2 - Using Python's built-in server:

cd frontend/build
python -m http.server 3000

Production Deployment

For production deployment:

  1. Backend: Use a WSGI server like Gunicorn

    pip install gunicorn
    gunicorn -w 4 -b 0.0.0.0:8000 main:create_app()
  2. Frontend: Serve the built files using a web server like Nginx or Apache

  3. Database: Consider using PostgreSQL for production instead of SQLite

API Endpoints

Method Endpoint Description
GET / Health check
POST /shorten Create short URL from long URL
GET /<short_url> Redirect to original URL

Project Structure

URL_shortener/
β”œβ”€β”€ app/                    # Backend Flask application
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ config.py          # Configuration settings
β”‚   β”œβ”€β”€ db.py              # Database connection and initialization
β”‚   β”œβ”€β”€ models.py          # URL model and database operations
β”‚   β”œβ”€β”€ routes.py          # Flask API routes
β”‚   β”œβ”€β”€ shortener.py       # Short URL generation logic (base62)
β”‚   β”œβ”€β”€ validators.py      # Input validation functions
β”‚   └── error_handlers.py  # Error handling utilities
β”œβ”€β”€ frontend/               # React frontend application
β”‚   β”œβ”€β”€ public/
β”‚   β”‚   β”œβ”€β”€ index.html     # HTML template
β”‚   β”‚   └── manifest.json  # PWA manifest
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/    # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ Header.js      # App header
β”‚   β”‚   β”‚   β”œβ”€β”€ Footer.js      # App footer
β”‚   β”‚   β”‚   └── URLShortener.js # Main URL shortener form
β”‚   β”‚   β”œβ”€β”€ App.js         # Main App component
β”‚   β”‚   β”œβ”€β”€ index.js       # React entry point
β”‚   β”‚   └── index.css      # Global styles
β”‚   β”œβ”€β”€ package.json       # Node.js dependencies
β”‚   └── build/             # Production build (after npm run build)
β”œβ”€β”€ tests/                  # Test files for backend
β”œβ”€β”€ .github/                # GitHub Actions CI/CD
β”œβ”€β”€ docs/                   # Documentation
β”œβ”€β”€ scripts/                # Utility scripts
β”œβ”€β”€ main.py                # Backend entry point
β”œβ”€β”€ requirements.txt       # Python dependencies
β”œβ”€β”€ start-dev.sh           # Development startup script
β”œβ”€β”€ build-prod.sh          # Production build script
β”œβ”€β”€ url_shortener.db       # SQLite database (created automatically)
└── README.md

How It Works

  1. URL Submission: User submits a long URL via POST request
  2. ID Generation: Database assigns an ID starting from 10000
  3. Short Code Creation: ID is converted to base62 (0-9, a-z, A-Z)
  4. Database Storage: Both original URL and short code are saved
  5. Response: Short code is returned to user

Technical Details

  • Database: SQLite with auto-incrementing IDs starting at 10000
  • Encoding: Base62 encoding for compact, readable URLs
  • Port: Runs on port 8000
  • Framework: Flask
  • URL Format: http://localhost:8000/<short_code>

Troubleshooting

Port 8000 in use?

  • Kill the process: lsof -ti:8000 | xargs kill -9
  • Or change the port in main.py

Database issues?

  • Delete and recreate: rm url_shortener.db then restart the app

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages