Sign inSign up

hibare/shorty

By hibare

Updated about 4 years ago

A minimalistic URL shortening API service written in Python using Django.

Image
0

344

hibare/shorty repository overview

Shorty

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.

APIs

Unshorten

[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\""
}
Health Check

[GET] /__health/

Response:

[200 OK]

{
  "healthy": "ok"
}

Running Locally

Without Docker

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
With Docker

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:

  1. There is an Docker image published on Docker Hub.
  2. There is a prod version of docker-compose named docker-compose.yml which will use latest image published on Docker hub.
  3. For dev docker-compose, store is mounted to host store directory. For production docker-compose, store is mounted to a named volume shorty_store.
Environment Variables
NameRequiredDefaultRemarks
DEBUGYes-Set to false in local development. Set to true in production.
SECRET_KEYYes-Set to a strong long random string.
SCHEMEYes-This is the URL scheme used to generate full short URL.
NETLOCYes-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
Running Tests

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'...

Tag summary

Content type

Image

Digest

Size

78 MB

Last updated

about 4 years ago

docker pull hibare/shorty