Project Overview
This project implements a basic URL shortening service using Python, the Flask web framework, and Redis as its primary data store. It demonstrates how to build a modular RESTful API that leverages Redis's speed as an in-memory key-value store for efficient URL mapping management and atomic ID generation. This is an excellent project for understanding fundamental backend development, database integration, and the practical application of Redis in a web context.
Features
Shorten URL: Accepts a long URL via a POST request and returns a unique, shortened URL.
Redirect: Redirects users from the generated short URL to its original long URL.
Fast Lookups: Utilizes Redis for extremely fast storage and retrieval of URL mappings.
Unique Code Generation (Custom): Generates unique short codes by atomically incrementing a counter in Redis and converting the resulting ID to a Base62 string.
Modular Design: Organized into separate Python files for application setup, route handling, and business logic (Redis interactions) using Flask Blueprints.
Basic Error Handling: Provides appropriate responses for missing URLs or invalid requests.
Technologies Used
Python 3.x
Flask: A lightweight and flexible web framework for building the API.
Redis: An open-source, in-memory data structure store used for fast storage of URL mappings and atomic counter operations.
redis-py: The official Python client library for interacting with Redis.
Project Structure
This project follows a common Flask application structure to promote modularity and separation of concerns:
url_shortener/
├── app.py # Main Flask application entry point, Redis initialization, blueprint registration.
├── routes.py # Defines all Flask application routes (e.g., '/', '/shorten', '/<short_code>') within a Blueprint.
├── services.py # Contains the core business logic and Redis interaction functions (e.g., generate/store/retrieve URLs).
├── templates/ # Flask's default directory for HTML templates.
│ └── index.html # The simple homepage HTML for
└── README.md # This project documentation.
How It Works
Application Initialization (app.py
):
The create_app() factory function initializes the Flask application instance.
It establishes the connection to the Redis server by calling services.init_redis()
, ensuring Redis is ready to serve requests.
It registers the main_bp Blueprint (defined in routes.py
), which integrates all defined routes into the Flask application.
URL Shortening (routes.py
& services.py
):
A client sends a POST request to the /shorten endpoint (handled by a route in routes.py
) with a JSON body containing the long_url
.
The route handler performs basic URL validation and then delegates the core logic to services.generate_and_store_url(long_url)
.
Inside services.py
:
It uses r.incr('next_short_id')
to atomically increment a counter in Redis. This ensures that every generated ID is globally unique, even with concurrent requests, preventing collisions.
The unique numeric ID is then converted into a compact, alphanumeric Base62 short_code using a custom encoding function.
Finally, r.set(short_code, long_url)
stores this mapping directly in Redis, with the short_code
as the key and the long_url
as its value.
The route then constructs the full shortened URL and returns it as a JSON response to the client.
URL Redirection (routes.py
& services.py
):
When a user accesses a shortened URL (e.g., http://localhost:5000/1
), the short_code
route handler (in routes.py
) extracts the short_code
from the URL path.
It calls services.get_long_url(short_code)
to retrieve the original long_url from Redis.
If the long_url is found in Redis, the Flask application performs an HTTP redirect to the original URL.
If the short_code is not found (meaning it's invalid or never existed), a 404 Not Found error is returned.
detailed code and step by step implementation can be found on my github here: URL Shortener
Top comments (0)