Package: burl
burl(brief url) is a URL shortener written in python with the django framework.As of version 2, this application and repo is for the standalone burl service,
providing a docker-packaged reference implementation ofdjango-burl. If you’re looking for a
URL-shortener to include in your own django project,seedjango-burl.Features include:data models and REST API fromdjango-burlJWT authenticationCORS management viadjango-cors-headersswagger-uiuser model withUUIDFieldfor its primary keyaccount management pages/templatesstatic assets served viawhitenoisegunicornWSGI servereasy configuration withcfitallQuick StartFirst, configure a postgres user and database to hostburl’s data, then create
a file/etc/burl/envspecifing the environment variables for configuringburl(see below).Run the latest image from docker hub (remember to change 10.0.0.10 to
the ip of the postgres server you configured above):docker pull wryfi/burl:latest
docker run -dit --name=myburl -p 8000:8000 --env-file /etc/burl/env \
    --add-host=dbhost:10.0.0.10 \
    --restart unless-stopped wryfi/burl:latest run
docker exec -it myburl burl-manager createsuperuser
docker exec -it myburl burl-manager set_default_site --name localhost --domain localhostPoint your browser tohttp://localhost:8000/adminand create some BURLs!Or go old school:curl \
  -X POST -H "Content-Type: application/json" \
  -d '{"username": "dooper", "password": "sooperuser"}' \
  http://localhost:8000/api/v2/token/auth
...
{
  "access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
  "refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}

curl \
  -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU" \
  -d '{"url": "https://archive.org", "burl": "arc"}' \
  http://localhost:8000/api/v2/burls/
...
{
  "burl": "arc",
  "created": "2022-03-14T16:16:09.353538-05:00",
  "description": "",
  "enabled": true,
  "updated": "2022-03-14T16:16:09.353543-05:00",
  "url": "https://archive.org",
  "user": "aec88b92-267f-430e-b4e2-0c63f4fc411a"
}

curl -IL "http://localhost:8000/arc/"
...
HTTP/1.0 302 Found
Content-Type: text/html; charset=utf-8
Location: https://archive.org
X-Frame-Options: DENY
Content-Length: 0
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Vary: Origin
Server: Werkzeug/2.0.3 Python/3.10.2
Date: Mon, 14 Mar 2022 21:21:03 GMT

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 14 Mar 2022 21:21:04 GMT
Content-Type: text/html; charset=utf-8
Connection: close
vary: Accept-Encoding
Strict-Transport-Security: max-age=15724800
Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0Configurationburlusescfitallfor managing its
most commonly configured settings. It will search/etc/burland then~/.local/etc/burlfor aburl.ymlorburl.jsonsettings file, and/or
read its configuration from a series of environment variables.Example yaml file:admin:
  rough_count_min: 1000
api:
  page_size: 25
app:
  burl_blacklist:
  - admin
  - api
  - static
  - media
  debug: false
  default_redirect_url: https://www.wikipedia.org/
  hashid_alphabet: abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789
  media_root: /Users/burl/.local/var/burl/media
  static_root: /Users/burl/.local/share/burl/static
  time_zone: America/Los_Angeles
db:
  default:
    engine: django.db.backends.postgresql_psycopg2
    host: 127.0.0.1
    name: burl
    password: burl
    port: 5432
    user: burl
http:
  secure_proxy_ssl_header_name: HTTP_X_FORWARDED_PROTO
  secure_proxy_ssl_header_value: http
  use_x_forwarded_hosts: true
logging:
  app:
    level: warn
  burl:
    level: info
  log_dir: /Users/burl/.local/var/log/burl
mail:
  default_from_email: nobody@burl.test
  sendgrid_api_key: ''
security:
  allowed_hosts:
  - localhost
  - 127.0.0.1
  cors:
    allow_all_origins: false
    allowed_origin_regexes: []
    allowed_origins: []
  jwt:
    access_lifetime: 600
    refresh_lifetime: 86400
  secret_key: jeirainooyieShaequeeng8av9gah6geiv1ooTh6quoo9meireeRayoo6un7xah
  sendgrid_api_key: ''Corresponding environment variables:BURL__ADMIN__ROUGH_COUNT_MIN
BURL__API__PAGE_SIZE
BURL__APP__BURL_BLACKLIST
BURL__APP__DEBUG
BURL__APP__DEFAULT_REDIRECT_URL
BURL__APP__HASHID_ALPHABET
BURL__APP__MEDIA_ROOT
BURL__APP__STATIC_ROOT
BURL__APP__TIME_ZONE
BURL__DB__DEFAULT__ENGINE
BURL__DB__DEFAULT__HOST
BURL__DB__DEFAULT__NAME
BURL__DB__DEFAULT__PASSWORD
BURL__DB__DEFAULT__PORT
BURL__DB__DEFAULT__USER
BURL__HTTP__SECURE_PROXY_SSL_HEADER_NAME
BURL__HTTP__SECURE_PROXY_SSL_HEADER_VALUE
BURL__HTTP__USE_X_FORWARDED_HOST
BURL__LOGGING__APP__LEVEL
BURL__LOGGING__BURL__LEVEL
BURL__LOGGING__LOG_DIR
BURL__MAIL__DEFAULT_FROM_EMAIL
BURL__MAIL__SENDGRID_API_KEY
BURL__SECURITY__ALLOWED_HOSTS
BURL__SECURITY__CORS__ALLOWED_ORIGINS
BURL__SECURITY__CORS__ALLOWED_ORIGIN_REGEXES
BURL__SECURITY__CORS__ALLOW_ALL_ORIGINS
BURL__SECURITY__JWT__ACCESS_LIFETIME
BURL__SECURITY__JWT__REFRESH_LIFETIME
BURL__SECURITY__SECRET_KEY
BURL__SECURITY__SENDGRID_API_KEYOf course, per the django convention, you can always set theDJANGO_SETTINGS_MODULEenvironment variable to a python module of your
choice, to further extend or bypass all ofburl’s settings and configuration
mechanisms if needed.Configuration NotesEmailIf you want working email (e.g. for password resets) the only supported option
at this time is to use sendgrid.  Set thesecurity.sendgrid_api_keysetting
(BURL__SECURITY__SENDGRID_API_KEYenvironment variable) to enable sendgrid
support. Otherwise all email is printed to the console and never sent.DevelopmentImplementationburlis a reference implementation ofdjango-burl, which implements most
of the functionality found inburl. Please review django-burl’s documentation
for details.burladds JWT authentication to django-burl viaSimple JWT.The current Swagger UI (api documentation) can be found at/api/v2/swaggerof the running service.The django admin can be found as usual at/admin.code requirementsburlrequires python 3.7 or newer.  Python 2 is not supported.burlshould run anywhere python will run, most easily on a unix-like system.database requirementsburlstrongly recommends using a postgresql database via python’spsycopg2library.You will need a C compiler, python header files, and postgres development
libraries on your system to build the postgrespsycopg2module needed
for postgresql.Installationburlis made to be installed via the standard python installation methods.
You can install it as simply as running:pip install burlIt is recommended, however, that you installburlin a virtualenv or
Docker container. For development, in particular, the easiest way to set
everything up is to usepipenv(see below).Once you have installedburl, you will need to create a database for its
use. The default configuration expects a database calledburl, owned by
a user namedburl, with a password ofburl. You should alter these
settings by using the configuration mechanisms described above.Once your database is configured, run the database migrations to create:burl-manager migrateThen create a new superuser:burl-manager createsuperuserNow you should be ready to runburl!  You can run a test/development server
by runningburl-managerrunserverto ensure that everything is working. In
production, you should deploy behind a WSGI server.Deploymentburlis a straightforward django app, with nothing fancy.You can deploy burl with any WSGI-compliant web server. Runninggunicornas the backend WSGI server, with an nginx
reverse proxy in front of it, is a common and well-supported configuration.Deploying Djangohas some generic information about deploying django applications that you may
find useful if you are new to this stack.DockerThe included Dockerfile builds a container that bundles burl with gunicorn and
exposes gunicorn on port 8000.  It builds with uid65432by default, which
you can change on thedocker buildcommand line, e.g.:docker build --build-arg uid=23456 -t burl .This container does not include postgres or nginx. You will need postgres to run
burl, and you will want to put nginx in front of the container.Once you have a built container, it can be activated as follows:docker run -dit -p 8000:8000 --env-file /etc/burl/env --add-host=dbhost:10.0.0.10 \
    --restart unless-stopped burl:latest burlToolingburluses a modern python toolchain, consisting of:pipenvfor managing dependencies,pbrbuild system,docker support,semantic version numbers,git flow branching scheme.To start coding, first installpipenv, then clone this repo and runpipenv install-d. This will set up a virtualenv, install all of
the dependencies, and install burl in editable mode. You should now be
able to run commands likepipenv shell,pipenv runburl-managertest,
etc.When usingpipenvyou can make use of a.envfile in the source root,
and set the requisite environment variables (above) there. This file is
ignored in.gitignoreand local to your environment.See:Why Python devs should use PipenvTestsburlwas not developed using TDD, but has reasonable test coverage.
Tests are located in the standard places for django applications. New PRs
should include relevant tests whenever possible.