Skip to content

Commit

Permalink
Inital beta release
Browse files Browse the repository at this point in the history
  • Loading branch information
Craig committed Apr 19, 2021
1 parent 7fc4e5c commit b1ae366
Show file tree
Hide file tree
Showing 24 changed files with 648 additions and 123 deletions.
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.git/
.gitignore
.idea/
.DS_Store/
*venv*/
.env
*.iml
*.md
.coverage
__pycache__/
*.py[cod]
.Python
*.egg-info/
*.egg
build/
dist/
static/
docker-compose.yml
146 changes: 25 additions & 121 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,129 +1,33 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# IDE stuff
.idea/
*.iml

# because macs
*.DS_Store

# C extensions
*.so
# environments
*venv*/
.tox/
*.pid
.env

# Distribution / packaging
# python stuff
__pycache__/
*.py[cod]
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot
build/
dist/

# Django stuff:
# Django stuff
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache
local_*.yaml
/configs/local*.yaml
static/
media/

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/
# pytest
.pytest_cache/
.coverage
pytest.ini
5 changes: 5 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog


## [1.0.0-beta] - 19/04/2021
- Initial working release
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM tecktron/python-bjoern:latest
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get clean && apt-get update && \
apt-get -y install --no-install-recommends \
apt-utils \
build-essential \
libpq-dev \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*

ENV MODULE_NAME=webhook_catchall.wsgi

COPY . /app
RUN chmod +x /app/prestart.sh
WORKDIR /app/

RUN python -m pip install pip --no-cache-dir --upgrade
RUN pip install -r /app/requirements.txt
103 changes: 101 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,101 @@
# webhook-catchall
Generic HTTP service based in Django designed to catch webhooks for testing
# Webhook Catchall
A simple HTTP service based on Django that was built to catch and show webhook data in a testing environment.
Includes a Django admin page what shows the url that was hit, and the data that was received.

**THIS IS FOR DEVELOPMENT PURPOSES ONLY IT IS NOT RECOMMENDED FOR PRODUCTION USE**

## Requirements
- A Postgres Database.
- Python 3.8+ or Docker

## Installation

There are 2 ways to use this:
1. Use the Docker image (easiest)
2. Run this as a local Python service using the built in Django server

### Docker Service
The latest docker image is available at my docker hub. [You can find it here]()

#### Options
The image provides options to change the database settings via environment variables
so that you can adjust to fit your system. The variables are:
- `DB_NAME`: The name of the database (e.g., `webhook_catchall`)
- `DB_USER`: The username of the database (e.g., `postgres`)
- `DB_PASS`: The password of the database (e.g., `postgres`)
- `DB_HOST`: The host of the database (e.g., `127.0.0.1`)
- `DB_PORT`: The port of the database (e.g., `5432`)

You can also change the default admin username and password as well. To do so simply pass in the
environment params of `ADMIN_USER` and `ADMIN_PASS` (defaults to `admin`:`admin`)

##### Demo docker-compose.yml
Included in the project is an example `docker-compose.yml` that will bring up the project
with a postgres database and have it running on port 8181. You can then simply point your
webhooks to `http://localhost:8181/`, and your browser to `http://localhost:8181/admin/` to login
with the default admin to see what was captured.


### Local Django server
You can of course run this locally using Django's build in test server. Please don't
forget to update parameters here with those of your system and choosing.

1. Clone this repo.
2. Create a local Python virtual environment and activate it (e.g., `python -m venv ./.venv && source ./.venv/bin/activate`)
3. Install the requirements using pip (e.g., `pip install -r requirements.txt`)
4. Create a file called `.env` in the project root (this file is git ignored FYI)
5. Copy this code block and replace it with the settings from your database setup:
```bash
DB_NAME=webhook_catchall
DB_USER=postgres
DB_PASS=postgres
DB_HOST=127.0.0.1
DB_PORT=5432
```
6. Run the Django migrations: `python manage.py migrate`
7. Run Django's static collection: `python manage.py collectstatic`
8. Run the `create_default_superuser` management command to create the admin user:
`python manage.py create_default_superuser --username="admin" --password="admin"`
9. Run the Django testserver: `python manage.py testserver 127.0.0.2:8181` to start the server.
10. Open your browser to `http://localhost:8181/admin/` and login to the admin.
## Usage
Once you have the service up and running, it will support receiving data from any HTTP method on
any path (except those being with `/admin/` or `/static/`). The system will dump all data into a
`TEXT` field and additionally attempts to store the incoming data that has the `Content-Type`
header of `application/json` into a JSON field for easy viewing. It also will keep track of the
method used, the time the webhook was received, the incoming path, any query parameters as well as
any headers in the request. The service will always save the data no matter what and return a 204
response (no content) unless it fails to decode the json, in which case it will return a 400
instead with the error from the json decoder and the data only stored in the `TEXT` field.
### Example:
`curl -X POST http://127.0.0.1:8181/foo/bar?process=webhook -H "Content-Type: application/json" -d "{\"test\":{\"data\": \"nested\"}}"`
You can login to the Django Admin and see all the details of the call. The view of the data in the
admin is read-only.
## Help and support
If you need help or find a bug or would like to ask for a feature (you could build it, see
contributing below). Please first search to see if the issue exists on the github page. If not,
please open a new ticket and explain in as much detail as possible how to recreate the issue or
what feature you'd like to see.

## Contributing and development
This is an opensource project, contributions are welcome. Please follow the guidelines to
contribute to this project.

### Setup
1. Use `pip` to install the additional `dev-requirements.txt`.

### Coding standards
Before submitting any code please be sure you have done the following:
- Run coding stands tools, these are isort, black and flake8. They should all pass.
- Run tox and check all tests have passed and that your code coverage is 95% or above.

### Testing
Every bit of code you submit must be fully tested.
All testing is done using pytest, please follow pytest style testing (not unittest).
You can simply use tox to run the tests: `tox -e py39`. This supports environments
`py36` - `py39`.
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0-beta
15 changes: 15 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pip
tox
tox-pip-extensions
isort
flake8
factory-boy
pytest
pytest-django
pytest-cov
pytest-mock
pytest-xdist
freezegun
black
django-coverage-plugin

21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: "3.4"
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres

django:
build: .
environment:
- DB_NAME=webhook_catchall
- DB_USER=postgres
- DB_PASS=postgres
- DB_HOST=db
- DB_PORT=5432
ports:
- "8181:80"
links:
- db
22 changes: 22 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webhook_catchall.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == "__main__":
main()
32 changes: 32 additions & 0 deletions prestart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/sh
# Borrowed from https://docs.docker.com/compose/startup-order/
# wait-for-postgres.sh

x=0
PGCONNECT=postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/postgres
printenv
echo $PGCONNECT
until psql $PGCONNECT -c '\q'; do
if [ $x -gt 10 ]; then
echo "Cannot find postgres, aborting"
exit 8
fi
echo "Postgres is unavailable - sleeping..."
sleep 3
x=$(($x+1))
done

echo "Postgres is up!"
cd /app || exit 1
psql ${PGCONNECT} -tc "SELECT 1 FROM pg_database WHERE datname = '${DB_NAME}'" | grep -q 1 || psql ${PGCONNECT} -c "CREATE DATABASE \"${DB_NAME}\" WITH OWNER '${DB_USER}'"

ADMIN_USER=${ADMIN_USER:-"admin"}
ADMIN_PASS=${ADMIN_PASS:-"admin"}

echo "Running migrations"
python manage.py migrate
echo "Creating default user"
python manage.py create_default_superuser --username="${ADMIN_USER}" --password="${ADMIN_PASS}"
echo "collecting static"
mkdir -p /app/static
python manage.py collectstatic --no-input
Loading

0 comments on commit b1ae366

Please sign in to comment.