Skip to content

Commit

Permalink
Updated readme, a common script to run api and app server during deve…
Browse files Browse the repository at this point in the history
…lopment
  • Loading branch information
amitt001 committed Dec 9, 2017
1 parent f047ddb commit 61d8f30
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -7,6 +7,7 @@ bootstrap.min.css
*.egg-info/
env
.idea
.vscode
dist
.DS_Store
.cache
192 changes: 118 additions & 74 deletions README.md
Expand Up @@ -3,92 +3,88 @@ Pygmy

[![Build Status](https://travis-ci.org/amitt001/pygmy.svg?branch=master)](https://travis-ci.org/amitt001/pygmy) [![Coverage Status](https://coveralls.io/repos/github/amitt001/pygmy/badge.svg?branch=master)](https://coveralls.io/github/amitt001/pygmy?branch=master) [![Requirements Status](https://requires.io/github/amitt001/pygmy/requirements.svg?branch=master)](https://requires.io/github/amitt001/pygmy/requirements/?branch=master)

Live version of this project: [https://pygy.co](https://pygy.co)

Check link stats by adding + to url. Example [pygy.co/pygmy+](https://pygy.co/pygmy+)

Open-source, extensible & easy-to-use URL shortener. It's very easy to host and run. It's created keeping in mind that it should be easy to have your custom URL shortener up and running without much effort.

Major features are:
- Custom URL
- Auto expiry URL
- Secret key protected URL
- User Login/Sign up
Live version of this project @ [https://pygy.co](https://pygy.co)

Check link stats by adding **+** to the URL. Example [pygy.co/pygmy+](https://pygy.co/pygmy+)

# Table of Contents
- [Pygmy](#pygmy)
- [Table of Contents](#table-of-contents)
- [Features](#features)
- [Technical Info](#tech-used)
- [Installaton/Setup](#installatonsetup)
- [DB Setup:](#db-setup)
- [Use MySQL](#use-mysql)
- [Use Postgresql](#use-postgresql)
- [Use SQLite](#use-sqlite)
- [Using Pygmy API](#using-pygmy-api)
- [Create User:](#create-user)
- [Shell Usage](#shell-usage)
- [How Link Stats Are Generated?](#how-link-stats-are-generated)
- [How Pygmy Auth Token Works?](#how-pygmy-auth-token-works)
- [File Issues](#file-issues)
- [Development](#development)
- [License](#license)

Pygmy or `pygy.co` is an open-source, extensible & easy-to-use but powerful URL shortener. It's created keeping in mind that it should be easy to host and run your custom URL shortener without much effort. [Open-source Python URL shortener]

The architecture is very loosely coupled which allows custom integrations easily.

**The project has 3 major parts**

- The core URL shortening code
- A REST API on top. Uses Flask framework
- The UI layer for rendering the UI. It uses Django framework

Features
========

- URL shortner
- Customized short URL's(ex: `pygy.co/pygmy`)
- Support to create auto expiry URL after sometime.
- Secret key protected URL's
- User Login/Sign up to track shortned URL's and link stats
- User dashboard
- Link Analytics(add + to the tiny URL to get link stats)

The architecture is very loosely coupled which allows custom integrations very easily.

The project has 3 major parts:
- The core program for URL shortening
- REST API on top. Uses Flask framework.
- The UI layer for rendering the UI. It uses Django framework.
Technical Info
==============

Each part is independent of other part and it can function independently.
- Python 3, Javascript, JQuery, HTML, CSS
- REST API: Flask
- Pyui: Django(It serves the web user interface)
- DB: PostgreSQL/MySQL/SQLite
- Others: SQLAlchmey, JWT

This comment has been minimized.

Copy link
@sebastian-j

sebastian-j Feb 2, 2023

SQLAlchmey -> SQLAlchemy


Tech Stack:
Installaton/Setup
=================

Python 3, Javascript, JQuery, HTML, CSS
REST API: Flask
Pyui: Django(It provides a web user interface.)
DB: PostgreSQL/MySQL/SQLite


Setup:
======

- Clone `git clone https://github.com/amitt001/pygmy.git & cd pygmy`
- Install pip `easy_install pip` or `apt-get install python3-pip`
- Install virtualenv (optional but recommended)
1. Clone `git clone https://github.com/amitt001/pygmy.git & cd pygmy`
2. (Optional) Install virtualenv (optional but recommended)
- `pip install virtualenv`
- `virtualenv env`
- `source env/bin/activate`
- Install dependencies `pip install -r requirements.txt` (if you are using MySQL or PostgreSQL check db setup section)
- cd src
- To run the rest api `./run` to run UI `python pyui/manage.py runserver 127.0.0.1:8000`
- Visit 127.0.0.1:8000 to use the app
3. Install dependencies: `pip install -r requirements.txt` (if you are using MySQL or PostgreSQL check [DB setup](#db-setup) section)
4. `cd src`
5. `python run.py` (It runs Flask and Django servers using gunicorn)
6. Visit `127.0.0.1:8000` to use the app

Note:

1. The project has two config files:
- pygmy.cfg: src/pygmy/config/pygmy.cfg rest API and pygmy core settings file
- settings.py: src/pyui/pyui/settings.py Django settings file
- pygmy.cfg: `src/pygmy/config/pygmy.cfg` rest API and pygmy core settings file
- settings.py: `src/pyui/pyui/settings.py` Django settings file
2. SQLite is default db, if you are using PostgreSQL or MySQL with this project, make sure they are installed into the system.
3. To modify config settings vim src/pygmy/config/pygmy.cfg
4. You can run pygmy shell present in src directory to run the program on terminal
5. By default src/pyui/pyui/settings.py DEBUG is set to True set it to False in production
3. To modify config settings vim `src/pygmy/config/pygmy.cfg`
4. You can run pygmy shell present in src directory to run the program on terminal. `python shell`
5. By default in `src/pyui/pyui/settings.py` DEBUG is set to True, set it to False in production


Using API
DB Setup:
=========

Create User:

curl -XPOST http://127.0.0.1:9119/api/user/1 -H 'Content-Type: application/json' -d '{
"email": "00amit99@gmail.com",
"f_name": "Amit",
"l_name": "Tripathi",
"password": "amit@123"
}'


Get User:

Get All User Link:

Create Link:

Get Link:

How Auth Token Works:
=====================

It uses JWT. When user logs in using username and password a token is generated that are marked as fresh and it has a time period of 30 minutes. After 30 minutes. When a request comes with the old token and a new token is generated from the refresh token API. This refreshed token has a new field `fresh=False`. This new token can only shorten the URL and refresh the token for the further user. It CAN'T reset the password, disable the link and change the secret key of the URL.

DB Setup:
Use MySQL
---------

**Use MySQL:**

`pip install pymysql`

Check correct port:
Expand All @@ -104,19 +100,42 @@ Enter MySQL URL
`CREATE DATABASE pygmy;`


**Use Postgresql**
Use Postgresql
--------------

`pip install psycopg2`

`postgres://amit@127.0.0.1:5432/pygmy`

Use Sqlite
==========
Use SQLite
----------

SQLite is natively supported in Python

`sqlite:////var/lib/pygmy/pygmy.db`

Using Pygmy API
===============

Create User:
------------

curl -XPOST http://127.0.0.1:9119/api/user/1 -H 'Content-Type: application/json' -d '{
"email": "amit@gmail.com",
"f_name": "Amit",
"l_name": "Tripathi",
"password": "a_safe_one"
}'


Get User:

Get All User Link:

Create Link:

Get Link:

Shell Usage
===========

Expand Down Expand Up @@ -192,12 +211,37 @@ Docstring:
URL value.
```

Link stats:
How Link Stats Are Generated?
=============================

For getting geo location stats from IP maxminds' [GeoLite2-Country.mmd](http://pygy.co/cm) database is used. It's in `src/pygmy/app` directory.

How Pygmy Auth Token Works?
===========================

It uses JWT. When user logs in using username and password two tokens are generated, refresh token and auth token. Auth token is used for authentication with the Pygmy API. Refresh token can only be used to generate new auth token. Auth token has a very short TTL but refresh token has a longer TTL. After 30 minutes. When a request comes with the old auht token and a new token is generated from the refresh token API. User passwords are encrypted by [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) hash algorithm.

File Issues
===========

Something is not working or you have question or you want to see a new feature?

[Open a new issue](https://github.com/amitt001/pygmy/issues)

Development
===========

For getting geo location stats from IP maxminds' GeoLite2-Country.mmd database is used. It's in src/pygmy/app folder.
Run tests and generate a coverage report:

`coverage run --source src/pygmy -m py.test`

See coverage report:

`coverage report`

License
=======

The MIT license (MIT)
The MIT license (MIT)

[Read License Terms](https://github.com/amitt001/pygmy/blob/master/LICENSE)
2 changes: 1 addition & 1 deletion init.d/pygmyapi
Expand Up @@ -7,7 +7,7 @@ PIDFILE=/var/run/$NAME.pid
PORT=9119
APP_DIR=/opt/pygyco/src
PYTHONPATH='/opt/pygyco/env/bin/gunicorn'
APP_ARGS='--log-file /var/log/pygmy/error_logs.log --access-logfile /var/log/pygmy/acclogs.log --bind 127.0.0.1:9119 --workers 2 wsgi:app'
APP_ARGS='--log-file /var/log/pygmy/error_logs.log --access-logfile /var/log/pygmy/acclogs.log --bind 127.0.0.1:9119 --workers 2 pygmy.rest.wsgi:app'
APP_STOP_ARGS='--stop $PIDFILE'
APP_RELOAD_ARGS='--reload $PIDFILE'

Expand Down
59 changes: 59 additions & 0 deletions init.d/pyui
@@ -0,0 +1,59 @@
#!/bin/bash
# init.d script for pyui app

NAME=pyui
PIDFILE=/var/run/$NAME.pid

PORT=8000
APP_DIR=/opt/pygyco/src/pyui
PYTHONPATH='/opt/pygyco/env/bin/gunicorn'
APP_ARGS='--log-file /var/log/pygmy/uierror_logs.log --access-logfile /var/log/pygmy/uiacclogs.log --bind 127.0.0.1:8000 --workers 2 pyui.wsgi'
APP_STOP_ARGS='--stop $PIDFILE'
APP_RELOAD_ARGS='--reload $PIDFILE'

. /lib/lsb/init-functions

start() {
start-stop-daemon --start --background --make-pidfile --chdir $APP_DIR --pidfile $PIDFILE --exec $PYTHONPATH -- $APP_ARGS
}

stop() {
fuser -k $PORT/tcp
PID=`cat $PIDFILE`
kill -HUP $PID
rm -f $PIDFILE
}

case "$1" in
start)
if ! [ -f $PIDFILE ]; then
echo "Starting $NAME"
start
echo "Done"
else
echo "$NAME is already running"
fi
;;
stop)
if [ -f $PIDFILE ]; then
echo "Stopping $NAME"
stop
else
echo "$NAME not running"
fi
;;
restart)
echo "Restarting "
echo "$NAME."
;;
status)
status_of_proc $NAME
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|status}" >&2
exit 1
;;
esac

exit 0
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -11,6 +11,7 @@ Flask-Cors==3.0.3
Flask-JWT-Extended==3.3.4
Flask-Script==2.0.6
geoip2==2.6.0
gunicorn=19.7.1
idna==2.6
ipython==6.2.1
ipython-genutils==0.2.0
Expand Down

0 comments on commit 61d8f30

Please sign in to comment.