A url shortener.
If you liked this project please consider giving it a star! ⭐️
Phlasch is a url shortener. It aims to be easy-to-use, flexible and performant. As a result of this philosophy, it has been designed to be usable as a docker image, a program, or an aiohttp library.
There are two approaches to deploying Phlasch.
An all in one approach, which means the url shortener, redirector and the stats apps are all deployed as part of one service.
For example:
-
Deploy this
docker-compose.yml
file.version: "3.7" services: database: image: postgres restart: always environment: POSTGRES_PASSWORD: postgres server: image: bbmokhtari/phlasch restart: always ports: - 8080:8080 environment: PHLASCH_DB_HOST: database PHLASCH_DB_PASSWORD: postgres
-
Navigate to http://localhost:8080/api/doc to see what APIs are available.
A separated approach, which means the url shortener, redirector and the stats apps are all deployed separately as different services.
For example:
-
Deploy this
docker-compose.yml
file.version: "3.7" services: database: image: postgres restart: always environment: POSTGRES_PASSWORD: postgres shortener: image: bbmokhtari/phlasch command: ./start-shortener.sh restart: always ports: - 8080:8080 environment: PHLASCH_DB_HOST: database PHLASCH_DB_PASSWORD: postgres PHLASCH_SHORTENER_ORIGIN: http://localhost:9090 redirector: image: bbmokhtari/phlasch command: ./start-redirector.sh restart: always ports: - 9090:8080 environment: PHLASCH_DB_HOST: database PHLASCH_DB_PASSWORD: postgres stats: image: bbmokhtari/phlasch command: ./start-stats.sh restart: always ports: - 7070:8080 environment: PHLASCH_DB_HOST: database PHLASCH_DB_PASSWORD: postgres PHLASCH_STATS_ORIGIN: http://localhost:9090
-
Navigate to http://localhost:8080/api/doc to see what APIs are available.
-
Navigate to http://localhost:9090/api/doc to see what APIs are available.
-
Navigate to http://localhost:7070/api/doc to see what APIs are available.
- Python (>=3.7)
-
Make sure the OS has the following prerequisites:
- build essentials packages (gcc, etc.)
- postgresql development packages (postgresql-dev, etc.)
- libffi development packages (libffi-dev, etc.)
-
Upgrade
pip
,setuptools
andwheel
.$ pip install --upgrade pip setuptools wheel
-
Install Phlasch using pip:
$ pip install phlasch
When Phlasch is installed, the following apps are made available:
- DB: to store the links.
- Shortener: to shorten the links.
- Redirector: to redirect to the links.
- Stats: to get the stats of the links.
Each app can be configured using its own special environment variables.
DB is the app which stores the links. it uses the following environment variables:
-
PHLASCH_DB_BACKEND
The database backend to use. e.g. postgresql, sqlite, etc.
Default: postgresql
Note: Currently only postgresql is supported due to aiopg support.
-
PHLASCH_DB_DRIVER
The database driver to use. e.g. psycopg2, pg8000, etc.
Default: psycopg2
Note: Currently only psycopg2 is supported due to aiopg support.
-
PHLASCH_DB_USER
The database user.
Default: postgres
-
PHLASCH_DB_PASSWORD
The database password.
Default: nothing
-
PHLASCH_DB_HOST
The database host.
Default: localhost
-
PHLASCH_DB_PORT
The database port.
Default: 5432
-
PHLASCH_DB_NAME
The database name.
Default: postgres
-
PHLASCH_DB_URL
The database url.
Default: see note
Note: If set, it will override all the other DB configurations, otherwise it will be set automatically using the other DB configurations.
-
PHLASCH_DB_ENGINE
The aiohttp app's engine key.
Default: phlasch
If you are not using Phlasch as an aiohttp lib don't mind this, but if you are, this is the app key which the database engine is set on after creation.
Shortener is the app which shortens the links. it uses the following environment variables:
-
PHLASCH_SHORTENER_BASE
The characters to use in the shortened url.
Default: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Some people prefer not to use the (O, o, 0), (I, l, 1) or some similar-looking characters at all.
Warning: ONCE SET, DO NOT CHANGE THIS! EVER!
-
PHLASCH_SHORTENER_SHORTEN_URL
The url on which the users can shorten links.
Default: shortener/shorten
Note: It is set as a slashed url so that it can't be mistaken with a shortened url.
-
PHLASCH_SHORTENER_ORIGIN
The origin of the shortened url.
Default: nothing
In case the Redirector app is deployed on another host or domain, set this to the origin of that host or domain.
Note: If empty, it will use the origin of the Shortener host or domain.
Redirector is the app which redirects to the links. it uses no environment variables.
Stats is the app which is used to get the stats of the links. it uses the following environment variables:
-
PHLASCH_STATS_LIST_URL
The url on which the users can list the stats of all links.
Default: stats/list
Note: It is set as a slashed url so that it can't be mistaken with a shortened url.
-
PHLASCH_STATS_RETRIEVE_URL
The url on which the users can retrieve the stats of a link.
Default: stats/retrieve
Note: It is set as a slashed url so that it can't be mistaken with a shortened url.
-
PHLASCH_STATS_ORIGIN
The origin of the shortened url.
Default: nothing
In case the Redirector app is deployed on another host or domain, set this to the origin of that host or domain.
Note: If empty, it will use the origin of the Stats host or domain.
When the configurations are in place, the command line interface can be used effectively.
To see what is available, run the cli with the -h
option:
python -m phlasch -h
It will print something like this:
usage: phlasch [-h] {run,history,revision,upgrade,downgrade} ...
A url shortener.
optional arguments:
-h, --help show this help message and exit
Action:
The action to take.
{run,history,revision,upgrade,downgrade}
run Run app.
history Log revisions.
revision Make revision.
upgrade Upgrade to revision.
downgrade Downgrade to revision.
As seen above, the command line interface provides some actions which can be taken.
Phlasch database migrations are being tracked using revisions. Each time the database schema is changed in any app by Phlasch developers a revision is created in that app. Revisions represent the points in which the database schema was changed, as a result we can upgrade or downgrade to any revision at any time.
Each time Phlasch is installed or is updated, it is a good idea to upgrade to the latest revision (or head) for each database-using app, in the current case: only the DB app.
To upgrade the DB app to the latest revision (head), run:
python -m phlasch upgrade db head
It will print something like this:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> bfd35ebcbeb5, added link table
To log the revisions of the DB app, run:
python -m phlasch history db
It will print something like this:
Rev: bfd35ebcbeb5 (head)
Parent: <base>
Path: /app/phlasch/db/migrations/versions/bfd35ebcbeb5_added_link_table.py
added link table
Revision ID: bfd35ebcbeb5
Revises:
Create Date: 2020-01-30 21:29:35.727874+00:00
If we encounter any weird database situations after an upgrade we can always downgrade to the previous revisions.
To downgrade the DB app to the none revision (base), run:
python -m phlasch downgrade db base
It will print something like this:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running downgrade bfd35ebcbeb5 -> , added link table
WARNING: SETTING DOWNGRADE TO BASE WILL DELETE EVERYTHING AND DROP ALL TABLES!
If you are contributing to Phlasch and happen to change database schemas, you can create a revision for that change.
To create a revision for the DB app, run:
python -m phlasch revision db "some message"
It will print something like this:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.ddl.postgresql] ...
Generating /app/phlasch/db/migrations/versions/1fb7a742b953_some_message.py ... done
After migrating to the desired revision, either a single app or all apps can be run.
Apps can be run using the aiohttp server.
To run all apps, run:
python -m phlasch run all
It will print something like this:
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Now you can navigate to http://localhost:8080/api/doc to see what APIs are available!
To run a single app, run:
python -m phlasch run ${app_name}
It will print something like this:
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Apps can be run using the Gunicorn wsgi server.
To run all apps, run:
gunicorn phlasch.runners:get_all_runnable \
--bind 0.0.0.0:8080 \
--worker-class aiohttp.GunicornWebWorker
It will print something like this:
[2020-02-03 03:59:38 +0330] [80163] [INFO] Starting gunicorn 20.0.4
[2020-02-03 03:59:38 +0330] [80163] [INFO] Listening at: http://0.0.0.0:8080 (80163)
[2020-02-03 03:59:38 +0330] [80163] [INFO] Using worker: aiohttp.GunicornWebWorker
[2020-02-03 03:59:38 +0330] [80166] [INFO] Booting worker with pid: 80166
Now you can navigate to http://localhost:8080/api/doc to see what APIs are available!
To run a single app, run:
gunicorn phlasch.runners:get_${app_name}_runnable \
--bind 0.0.0.0:8080 \
--worker-class aiohttp.GunicornWebWorker
It will print something like this:
[2020-02-03 04:01:13 +0330] [80251] [INFO] Starting gunicorn 20.0.4
[2020-02-03 04:01:13 +0330] [80251] [INFO] Listening at: http://0.0.0.0:8080 (80251)
[2020-02-03 04:01:13 +0330] [80251] [INFO] Using worker: aiohttp.GunicornWebWorker
[2020-02-03 04:01:13 +0330] [80254] [INFO] Booting worker with pid: 80254
If the configurations are set, Phlasch can also be used as an aiohttp library.
-
If you are using alembic as your migration tool add the following lines to
alembic.ini
.[db] script_location = %(location_of_phlasch_package)s/db/migrations version_locations = %(location_of_phlasch_package)s/db/migrations/versions
If not, simply run the upgrade command described above in the migrators sections.
-
Configure your app using the configure functions provided by the apps.
from phlasch.db.configure import configure as configure_db from phlasch.shortener.configure import configure as configure_shortener from phlasch.stats.configure import configure as configure_stats from phlasch.redirector.configure import configure as configure_redirector # your app app = Application() ... # please keep this configure order intact configure_db(app) configure_shortener(app) configure_stats(app) configure_redirector(app) ...