Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewelwell committed Jun 5, 2018
0 parents commit 4c9e12b
Show file tree
Hide file tree
Showing 126 changed files with 3,950 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
static/
**/staticfiles/*
*db.sqlite3*
venv
.venv
*.pyc
.idea
.vscode
*.log
checkstyle.txt
17 changes: 17 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
stages:
- deploydevelop
- deploymaster

deploydevelop:
image: ilyasemenov/gitlab-ci-git-push
stage: deploydevelop
script: git-push dokku@dokku1.solidstategroup.com:bullet-train-api-dev
only:
- develop

deploymaster:
image: ilyasemenov/gitlab-ci-git-push
stage: deploymaster
script: git-push dokku@dokku1.solidstategroup.com:bullet-train-api
only:
- master
2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
release: python src/manage.py migrate
web: gunicorn --bind 0.0.0.0:${PORT:-8000} -w 3 --pythonpath src app.wsgi
7 changes: 7 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"scripts": {
"dokku": {
"predeploy": "python src/manage.py migrate --noinput"
}
}
}
26 changes: 26 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: '3'
services:
db:
image: postgres
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: bullettrain
api:
build:
context: .
dockerfile: docker/Dockerfile
command: bash -c "python manage.py migrate --noinput
&& python manage.py collectstatic --noinput
&& gunicorn --bind 0.0.0.0:8000 -w 3 app.wsgi"
environment:
DJANGO_DB_NAME: bullettrain
DJANGO_DB_USER: postgres
DJANGO_DB_PASSWORD: password
DJANGO_DB_PORT: 5432
DJANGO_ALLOWED_HOST: localhost
ports:
- "8000:8000"
depends_on:
- db
links:
- db:db
15 changes: 15 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:2.7

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY requirements-docker.txt ./
RUN pip install -r requirements-docker.txt
COPY src/ .

ENV DJANGO_SETTINGS_MODULE=app.settings.master-docker

EXPOSE 8000
Binary file added hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 113 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<img width="100%" src="./hero.png"/>

# Bullet Train REST API

## Development Environment

```
pip install virtualenv
virtualenv .venv
source .venv/bin/activate
pip install -r requirements-local.txt
python src/manage.py migrate
python src/manage.py runserver
```

The application can also be run locally using Docker Compose if required, however, it's beneficial
to run locally using the above steps as it gives you hot reloading. To run using docker compose,
simply run the following command from the project root:

```
docker-compose up
```

## Initialising
Once the app has been deployed, you can initialise it to create a super user by hitting the
`/api/auth/init` endpoint. This will create a super user with the details configured in
`app.settings.common` with the following parameters:

```
ADMIN_USERNAME,
ADMIN_EMAIL,
ADMIN_INITIAL_PASSWORD
```

These can be updated before deployment, or equally, once initialised, you can log in and update
these details.

## Databases
Databases are configured in app/settings/\<env\>.py

We use sqlite locally as it's easy to get set up and doesn't require any additional dependencies,
etc. In production, the app is configured to use PostgreSQL when running using a Heroku-ish
platform. NoSQL database systems will require some more complicated set up as Django is not
designed for use with NoSQL databases.

When running on a Heroku-ish platform, the application reads the database connection in production
from an environment variable called `DATABASE_URL`. This should be configured in the Heroku-ish
application configuration.

When running using Docker, it reads the database configuration from the settings located at
`app.settings.master-docker`

## Deploying

### Using Heroku-ish Platform (e.g. Heroku, Dokku, Flynn)
The application should run on any Heroku-ish platform (e.g. Dokku, Flynn) by simply adding the
required git repo and pushing the code. The code for running the app is contained in the Procfile.

To get it running, you'll need to update the ALLOWED_HOSTS constant in the relevant settings file.
If you're running the application using a Heroku-ish platform, you'll need to edit this in
`app.settings.master`. If you're deploying itusing Docker, you'll need to update this value in
`app.settings.master-docker`.

NOTE: It is important to also set an environment variable on whatever platform you are using for
`DJANGO_SECRET_KEY`. There is a function to create one in `app.settings.common` if none exists in
the environment variables, however, this is not suitable for use in production. To generate a new
secret key, you can use the function defined in `src/secret-key-gen.py` by simply running it from a
command prompt:

```
python secret-key-gen.py
```

### Using Docker
The application can be configured to run using docker with simply by running the following command:

```
docker-compose up
```

This will use some default settings created in the `docker-compose.yml` file located in the root of
the project. These should be changed before using in any production environments.

## Adding dependencies
To add a python dependency, run the following commands:

```
pip install <package name>
```

The dependency then needs to be added to the relevant requirements*.txt files as necessary.

## Stack

- Python 2.7.14
- Django 1.11.13
- DjangoRestFramework 3.8.2

## Contributing

Please read [CONTRIBUTING.md](https://gist.github.com/kyle-ssg/c36a03aebe492e45cbd3eefb21cb0486)
for details on our code of conduct, and the process for submitting pull requests to us.

## Getting Help

If you encounter a bug or feature request we would like to hear about it. Before you submit an
issue please search existing issues in order to prevent duplicates.

## Get in touch

If you have any questions about our projects you can email
<a href="mailto:projects@solidstategroup.com">projects@solidstategroup.com</a>.

18 changes: 18 additions & 0 deletions requirements-docker.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
appdirs==1.4.0
Django==1.11.13
django-cors-headers==2.0.2
djangorestframework==3.8.2
gunicorn==19.6.0
packaging==16.8
psycopg2-binary==2.7.4
pyparsing==2.1.10
requests==2.13.0
six==1.10.0
whitenoise==3.2.3
drf-nested-routers==0.90.2
shortuuid==0.5.0
django-rest-auth==0.9.3
django-allauth==0.36.0
sendgrid-django==4.2.0
coreapi==2.3.3
django-rest-swagger==2.2.0
17 changes: 17 additions & 0 deletions requirements-local.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
appdirs==1.4.0
Django==1.11.13
django-cors-headers==2.0.2
djangorestframework==3.8.2
gunicorn==19.6.0
packaging==16.8
pyparsing==2.1.10
requests==2.13.0
six==1.10.0
whitenoise==3.2.3
drf-nested-routers==0.90.2
shortuuid==0.5.0
django-rest-auth==0.9.3
django-allauth==0.36.0
sendgrid-django==4.2.0
coreapi==2.3.3
django-rest-swagger==2.2.0
19 changes: 19 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
appdirs==1.4.0
Django==1.11.13
django-cors-headers==2.0.2
djangorestframework==3.8.2
gunicorn==19.6.0
packaging==16.8
pyparsing==2.1.10
requests==2.13.0
six==1.10.0
whitenoise==3.2.3
dj-database-url==0.4.2
drf-nested-routers==0.90.2
shortuuid==0.5.0
django-rest-auth==0.9.3
django-allauth==0.36.0
sendgrid-django==4.2.0
psycopg2-binary==2.7.4
coreapi==2.3.3
django-rest-swagger==2.2.0
1 change: 1 addition & 0 deletions runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-2.7.14
Empty file added src/api/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions src/api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from __future__ import unicode_literals

from django.apps import AppConfig


class ApiConfig(AppConfig):
name = 'api'
99 changes: 99 additions & 0 deletions src/api/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-04-20 12:59
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Environment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=2000)),
('created_date', models.DateTimeField(auto_now_add=True, verbose_name=b'DateCreated')),
('api_key', models.UUIDField(default=uuid.uuid4)),
],
),
migrations.CreateModel(
name='Feature',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=2000)),
('created_date', models.DateTimeField(auto_now_add=True, verbose_name=b'DateCreated')),
],
),
migrations.CreateModel(
name='FeatureState',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('enabled', models.BooleanField()),
('environment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='featurestates', to='api.Environment')),
('feature', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='featurestates', to='api.Feature')),
],
),
migrations.CreateModel(
name='FFAdminUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.CreateModel(
name='Identity',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('identifier', models.CharField(max_length=2000)),
('created_date', models.DateTimeField(auto_now_add=True, verbose_name=b'DateCreated')),
('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='identities', to='api.Environment')),
],
options={
'verbose_name_plural': 'Identities',
},
),
migrations.CreateModel(
name='IdentityFeature',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('enabled', models.BooleanField()),
('feature', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='identityfeatures', to='api.Feature')),
('identity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='identityfeatures', to='api.Identity')),
],
),
migrations.CreateModel(
name='Organisation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=2000)),
],
),
migrations.CreateModel(
name='Project',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=2000)),
('created_date', models.DateTimeField(auto_now_add=True, verbose_name=b'DateCreated')),
('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='api.Organisation')),
],
),
migrations.AddField(
model_name='feature',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='features', to='api.Project'),
),
migrations.AddField(
model_name='environment',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='environments', to='api.Project'),
),
]
24 changes: 24 additions & 0 deletions src/api/migrations/0002_auto_20170619_1243.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-06-19 12:43
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('api', '0001_initial'),
]

operations = [
migrations.RenameField(
model_name='identity',
old_name='version',
new_name='environment',
),
migrations.AlterUniqueTogether(
name='identityfeature',
unique_together=set([('feature', 'identity')]),
),
]
Loading

0 comments on commit 4c9e12b

Please sign in to comment.