Skip to content

Commit

Permalink
Add black in pre-commit and also formatted exiting code as per black (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
theskumar authored Sep 25, 2019
1 parent c8fe2cb commit 8b6aa96
Show file tree
Hide file tree
Showing 28 changed files with 632 additions and 574 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.

## [2.x]

- Add black in pre-commit and also formatted exiting code as per black. ([@theskumar])
- Upgrade to run on Python 3.7 ([@theskumar])
- Update celery concurrency to default to number of CPUs ([@theskumar])
- Upgrade to Postgres 11 and Postgis 2.5. ([@CuriousLearner])
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ Project template for django based projects, optimized for making REST API with d

- Django 2.2.x
- Python 3.7.x
- Support for [black](https://pypi.org/project/black/)!
- [12-Factor][12factor] based settings management via [django-environ], reads settings from `.env` if present.
- Supports PostreSQL 11.0 (support of postgis-2.5 is available).
- Ready to deploy on Heroku (optional) and Ubuntu 16 LTS via [Ansible](Optional)
- [Django Rest Framework][drf] 3.9.x. ready.
- Ready to deploy on Heroku (optional) and Ubuntu 18 LTS via [Ansible](Optional)
- [Django Rest Framework][drf] 3.9.x.
- Uses `django_sites` instead of `django.contrib.sites`
- Uses [mkdocs] for project documentation. Optionally, password protect the docs when deployed.
- Uses [pytest] as test runner.
Expand Down
5 changes: 3 additions & 2 deletions {{cookiecutter.github_repository}}/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ indent_size = 4

[*.py]
# https://github.com/timothycrosley/isort/wiki/isort-Settings
line_length=120
line_length=88
known_first_party={{ cookiecutter.main_module }}
multi_line_output=3
include_trailing_comma=True
default_section=THIRDPARTY
import_heading_stdlib=Standard Library
import_heading_firstparty={{ cookiecutter.project_name }} Stuff
import_heading_thirdparty=Third Party Stuff
skip_glob=*/migrations/*
skip_glob=*/migrations/**,*/venv/**,*/docs/**

[*.{html,css,scss,json,yml}]
indent_style = space
Expand Down
4 changes: 1 addition & 3 deletions {{cookiecutter.github_repository}}/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ repos:
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v1.4.0
hooks:
- id: flake8
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-case-conflict
Expand All @@ -14,8 +13,7 @@ repos:
- id: check-json
- id: pretty-format-json
- id: check-added-large-files
- id: double-quote-string-fixer
- id: fix-encoding-pragma
- id: flake8

- repo: git://github.com/CuriousLearner/pre-commit-python-sorter
sha: 5294cde9d51cff119af537e987c30c320e9fbe2f
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.github_repository}}/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Before you submit a pull request, check that it meets these guidelines:
## Coding conventions

- Read and pay attention to current code in the repository
- For the Python part, we follow pep8 in most cases. We use [flake8][flake8] to check for linting errors. Once you're ready to commit changes, check your code with `flake8`.
- For the Python part, we follow [black](https://pypi.org/project/black/) for formating code. We use modified configuration of [flake8][flake8] to check for linting errors that complies formating standards of `black`. Once you're ready to commit changes, format your code with `black` and check your code with `flake8`. Optionally, setup `pre-commit` with `pre-install --install` to do it automatically before commit.
- Install a plugin for [EditorConfig][editorconfig] and let it handle some of the formating issues for you.
- For the Django part, we follow standard [Django coding style][django-coding style].
- And always remember the Zen.
Expand Down
126 changes: 62 additions & 64 deletions {{cookiecutter.github_repository}}/fabfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,16 @@
# ==========================================================================
# Settings
# ==========================================================================
env.project_name = '{{ cookiecutter.main_module }}'
env.project_name = "{{ cookiecutter.main_module }}"
env.apps_dir = join(HERE, env.project_name)
env.docs_dir = join(HERE, 'docs')
env.static_dir = join(env.apps_dir, 'static')
env.virtualenv_dir = join(HERE, 'venv')
env.requirements_file = join(HERE, 'requirements/development.txt')
env.docs_dir = join(HERE, "docs")
env.static_dir = join(env.apps_dir, "static")
env.virtualenv_dir = join(HERE, "venv")
env.requirements_file = join(HERE, "requirements/development.txt")
env.shell = "/bin/bash -l -i -c"
{%- if cookiecutter.webpack.lower() == 'y' %}
env.webpack_config_path = join(env.static_dir, 'webpack.config.js')
env.webpack_server_path = join(env.static_dir, 'server.js')
{%- endif %}

{% if cookiecutter.add_ansible.lower() == 'y' -%}env.use_ssh_config = True
env.dotenv_path = join(HERE, '.env')
env.dotenv_path = join(HERE, ".env")
env.config_setter = local{% endif %}


Expand All @@ -44,61 +40,61 @@ def init(vagrant=False):

install_requirements()
{%- if cookiecutter.webpack.lower() == 'y' %}
local('npm install')
local('npm run build')
local("npm install")
local("npm run build")
{%- endif %}
{%- if cookiecutter.add_pre_commit.lower() == 'y' %}
add_pre_commit()
{%- endif %}
if not os.getenv('CI', 'False').lower() == 'true':
local('createdb %(project_name)s' % env) # create postgres database
manage('migrate')
if not os.getenv("CI", "False").lower() == "true":
local("createdb %(project_name)s" % env) # create postgres database
manage("migrate")


def install_requirements(file=env.requirements_file):
"""Install project dependencies."""
verify_virtualenv()
# activate virtualenv and install
with virtualenv():
local('pip install -r %s' % file)
{%- if cookiecutter.add_pre_commit.lower() == 'y' %}
local("pip install -r %s" % file)
{%- if cookiecutter.add_pre_commit.lower() == "y" %}


def add_pre_commit():
verify_virtualenv()
# activate virtualenv and install pre-commit hooks
with virtualenv():
local('pre-commit install')
local("pre-commit install")
{%- endif %}


def serve_docs(options=''):
"""Start a local server to view documentation changes."""
with fab.lcd(HERE) and virtualenv():
local('mkdocs serve {}'.format(options))
local("mkdocs serve {}".format(options))


def shell():
manage('shell_plus')
manage("shell_plus")


def test(options='--pdb --cov'):
def test(options="--pdb --cov"):
"""Run tests locally. By Default, it runs the test using --ipdb.
You can skip running it using --ipdb by running - `fab test:""`
"""
with virtualenv():
local('flake8 .')
local('pytest %s' % options)
local("flake8 .")
local("pytest %s" % options)


def serve(host='127.0.0.1:8000'):
def serve(host="127.0.0.1:8000"):
"""Run local developerment server, making sure that dependencies and
database migrations are upto date.
"""
install_requirements()
migrate()
manage('runserver %s' % host)
{%- if cookiecutter.add_celery.lower() == 'y' %}
manage("runserver %s" % host)
{%- if cookiecutter.add_celery.lower() == "y" %}


def celery():
Expand All @@ -107,61 +103,61 @@ def celery():
"""
install_requirements()
migrate()
local('celery worker -A {{ cookiecutter.main_module }} -B -l INFO --concurrency=2')
local("celery worker -A {{ cookiecutter.main_module }} -B -l INFO")
{%- endif %}


def makemigrations(app=''):
def makemigrations(app=""):
"""Create new database migration for an app."""
manage('makemigrations %s' % app)
manage("makemigrations %s" % app)


def migrate():
"""Apply database migrations."""
manage('migrate')
manage("migrate")


def createapp(appname):
"""fab createapp <appname>
"""
path = join(env.apps_dir, appname)
local('mkdir %s' % path)
manage('startapp %s %s' % (appname, path))
local("mkdir %s" % path)
manage("startapp %s %s" % (appname, path))
{%- if cookiecutter.webpack.lower() == 'y' %}


def watch():
local('node %s' % env.webpack_server_path)
local("node %s" % env.webpack_server_path)
{%- endif %}


{% if cookiecutter.add_ansible.lower() == 'y' -%}
# Enviroments & Deployments
# ---------------------------------------------------------
def dev():
env.host_group = 'dev'
env.remote = 'origin'
env.branch = 'master'
env.hosts = ['dev.{{ cookiecutter.main_module }}.com']
env.dotenv_path = '/home/ubuntu/dev/{{ cookiecutter.main_module }}/.env'
env.host_group = "dev"
env.remote = "origin"
env.branch = "master"
env.hosts = ["dev.{{ cookiecutter.main_module }}.com"]
env.dotenv_path = "/home/ubuntu/dev/{{ cookiecutter.main_module }}/.env"
env.config_setter = fab.run


def qa():
env.host_group = 'qa'
env.remote = 'origin'
env.branch = 'qa'
env.hosts = ['qa.{{ cookiecutter.main_module }}.com']
env.dotenv_path = '/home/ubuntu/qa/{{ cookiecutter.main_module }}/.env'
env.host_group = "qa"
env.remote = "origin"
env.branch = "qa"
env.hosts = ["qa.{{ cookiecutter.main_module }}.com"]
env.dotenv_path = "/home/ubuntu/qa/{{ cookiecutter.main_module }}/.env"
env.config_setter = fab.run


def prod():
env.host_group = 'production'
env.remote = 'origin'
env.branch = 'prod'
env.hosts = ['prod.{{ cookiecutter.main_module }}.com']
env.dotenv_path = '/home/ubuntu/prod/{{ cookiecutter.main_module }}/.env'
env.host_group = "production"
env.remote = "origin"
env.branch = "prod"
env.hosts = ["prod.{{ cookiecutter.main_module }}.com"]
env.dotenv_path = "/home/ubuntu/prod/{{ cookiecutter.main_module }}/.env"
env.config_setter = fab.run


Expand All @@ -174,8 +170,9 @@ def config(action=None, key=None, value=None):
fab [prod] config:list
"""
import dotenv

command = dotenv.get_cli_string(env.dotenv_path, action, key, value)
env.config_setter('touch %(dotenv_path)s' % env)
env.config_setter("touch %(dotenv_path)s" % env)

if env.config_setter == local:
with virtualenv():
Expand All @@ -186,19 +183,19 @@ def config(action=None, key=None, value=None):


def restart_servers():
services = ['uwsgi-emperor.service', ]
services = ["uwsgi-emperor.service"]
for service in services:
fab.sudo('systemctl restart {0}'.format(service))
fab.sudo("systemctl restart {0}".format(service))


def configure(tags='', skip_tags='deploy'):
def configure(tags="", skip_tags="deploy"):
"""Setup a host using ansible scripts
Usages: fab [prod|qa|dev] configure
"""
fab.require('host_group')
cmd = 'ansible-playbook -i hosts site.yml --limit=%(host_group)s' % env
with fab.lcd('provisioner'):
fab.require("host_group")
cmd = "ansible-playbook -i hosts site.yml --limit=%(host_group)s" % env
with fab.lcd("provisioner"):
if tags:
cmd += " --tags '%s'" % tags
if skip_tags:
Expand All @@ -207,36 +204,36 @@ def configure(tags='', skip_tags='deploy'):


def deploy():
configure(tags='deploy', skip_tags='')
configure(tags="deploy", skip_tags="")


def deploy_docs():
"""Deploy documentation to server via ansible.
"""
configure(tags='documentation', skip_tags=''){% else %}
configure(tags="documentation", skip_tags=""){% else %}


def deploy_docs():
"""Deploy documentation to github pages.
"""
with fab.lcd(HERE) and virtualenv():
local('mkdocs gh-deploy')
local('rm -rf _docs_html'){% endif %}
local("mkdocs gh-deploy")
local("rm -rf _docs_html"){% endif %}


# Helpers
# ---------------------------------------------------------
def manage(cmd, venv=True):
with virtualenv():
local('python manage.py %s' % cmd)
local("python manage.py %s" % cmd)


@_contextmanager
def virtualenv():
"""Activates virtualenv context for other commands to run inside it.
"""
with fab.cd(HERE):
with fab.prefix('source %(virtualenv_dir)s/bin/activate' % env):
with fab.prefix("source %(virtualenv_dir)s/bin/activate" % env):
yield


Expand All @@ -245,8 +242,9 @@ def verify_virtualenv():
It also creates local virtualenv directory if it's not present
"""
from distutils import spawn
if not spawn.find_executable('virtualenv'):
local('sudo pip install virtualenv')

if not spawn.find_executable("virtualenv"):
local("sudo pip install virtualenv")

if not isdir(env.virtualenv_dir):
local('virtualenv %(virtualenv_dir)s -p $(which python3)' % env)
local("virtualenv %(virtualenv_dir)s -p $(which python3)" % env)
2 changes: 1 addition & 1 deletion {{cookiecutter.github_repository}}/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# Read .env file and set key/value inside it as environement variables
# see: http://github.com/theskumar/python-dotenv
load_dotenv(os.path.join(os.path.dirname(__file__), '.env'))
load_dotenv(os.path.join(os.path.dirname(__file__), ".env"))

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.development")

Expand Down
6 changes: 3 additions & 3 deletions {{cookiecutter.github_repository}}/settings/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Standard Library
import sys

if 'test' in sys.argv:
print('\033[1;91mNo django tests.\033[0m')
print('Try: \033[1;33mpytest\033[0m')
if "test" in sys.argv:
print("\033[1;91mNo django tests.\033[0m")
print("Try: \033[1;33mpytest\033[0m")
sys.exit(0)
Loading

0 comments on commit 8b6aa96

Please sign in to comment.