A minimalistic URL shortening API service written in Python using Django.
344
A minimalistic URL shortening API service written in Python using Django.
Example:
For a long URL https://hibare.in shorty will generate a short URL https://<host>/MjE4ZA.
Shorty uses URL hash to generate a short random uniq code for the long URL.
All URLs are normalized to standard form before generating a short verion. Normalization ensures same short URL is generated for similar kind of long URLs.
Example:
For following long URLs, same short URL is generated. As these are same URLs in reality.
All generated Short URL and its corresponding long URLs are stored in a flat file short_urls.json under store as a JSON string.
There is an Docker image published on Docker Hub.
[POST] /api/v1/shorten/
Headers:
content-type: application/json
Payload:
{
"url": "hibare.in"
}
Response:
Success
[200 OK]
{
"details": {
"original_url": "hibare.in",
"normalized_url": "http://hibare.in",
"short_code": "MjE4ZA",
"short_url": "http://localhost:8000/MjE4ZA"
}
}
Missing long URL in request
[400 Bad Request]
{
"details": "\"url\" input required"
}
Invalid long URL
[400 Bad Request]
{
"details": "Invalid \"url\""
}
[GET] /__health/
Response:
[200 OK]
{
"healthy": "ok"
}
Step 1: Navigate to project root and create a virtual environment.
python3 -m venv venv
This creates a virtual environment with a directory named venv.
Step 2: Activate virtual environment.
source venv/bin/activate
Step 3: Install all requirements inside virtual environment.
pip install -r requirements.txt
To install dev requirements, run following command.
pip install -r dev-requirements.txt
Step 4: Create a .env file under directory src. There is a .env template named .env.example. Rename .env.example to .env.
Populate all environment variables in .env file.
Step 5: Run project
Navigate to directory src. Run following command.
python3 manage.py runserver 127.0.0.1:8000
This command will start a Django development server on port 8000. This will only accept connections from localhost.
Alternatively, to start a gunicorn process, run following command.
gunicorn shorty.wsgi
A Dockerfile is present to package the entire application in docker.
Step 1: Create a .env file under project root. There is a .env template named .env.example under src for reference. Copy .env.example as .env in project root.
Populate all environment variables in .env file.
Step 2: Build docker image
If you are having legacy docker-compose use legacy command otherwise use latest commands.
Legacy
docker-compose -f docker-compose-dev.yml build
Latest
docker compose -f docker-compose-dev.yml build
Step 3: Run docker image.
Legacy
docker-compose -f docker-compose-dev.yml up
Latest
docker compose -f docker-compose-dev.yml up
This will start a web server on port 8000.
Note:
docker-compose.yml which will use latest image published on Docker hub.store is mounted to host store directory. For production docker-compose, store is mounted to a named volume shorty_store.| Name | Required | Default | Remarks |
|---|---|---|---|
| DEBUG | Yes | - | Set to false in local development. Set to true in production. |
| SECRET_KEY | Yes | - | Set to a strong long random string. |
| SCHEME | Yes | - | This is the URL scheme used to generate full short URL. |
| NETLOC | Yes | - | This is combination of host & port in format host:port. If port is not available then value is just host. Ex: localhost:8000 or shorty.com |
To run tests, follow Running locally without Docker steps to setup neccessary environemnt.
Run tests using following commands.
> python3 manage.py test
Found 7 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.2022-07-03 19:33:37,039 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,039 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,039 django.request WARNING [241] Bad Request: /api/v1/shorten/
.2022-07-03 19:33:37,040 url_shortner.views ERROR [55] Short code OWQ3NQT not found
2022-07-03 19:33:37,040 django.request WARNING [241] Not Found: /OWQ3NQT/
2022-07-03 19:33:37,040 django.request WARNING [241] Not Found: /OWQ3NQT/
2022-07-03 19:33:37,040 django.request WARNING [241] Not Found: /OWQ3NQT/
.2022-07-03 19:33:37,068 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,068 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,068 django.request WARNING [241] Bad Request: /api/v1/shorten/
.2022-07-03 19:33:37,069 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,069 django.request WARNING [241] Bad Request: /api/v1/shorten/
2022-07-03 19:33:37,069 django.request WARNING [241] Bad Request: /api/v1/shorten/
.2022-07-03 19:33:37,071 url_shortner.views INFO [35] Generated short code OWQ3NQ for https://hibare.in
.2022-07-03 19:33:37,072 url_shortner.views INFO [35] Generated short code OWQ3NQ for https://hibare.in
2022-07-03 19:33:37,073 url_shortner.views INFO [52] Redirecting short code OWQ3NQ to https://hibare.in
.
----------------------------------------------------------------------
Ran 7 tests in 0.039s
OK
Destroying test database for alias 'default'...
Content type
Image
Digest
Size
78 MB
Last updated
about 4 years ago
docker pull hibare/shorty