Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use poetry everywhere #463

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,9 @@ jobs:
with:
python-version: "3.9"
cache: "pip"
- name: Install cookiecutter
- name: Install cookiecutter and poetry
run: |
python -m pip install --upgrade pip
pip3 install cookiecutter==1.7.3
- name: Install poetry
run: |
pip3 install poetry==1.2.0
pip3 install cookiecutter==2.1.1 poetry==1.7.1
- name: Run tests
run: |
./run_test.sh
run: bash run_test.sh
30 changes: 2 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

- Django 4.1.x
- Python 3.9.x
- [Poetry][poetry] Support
- Dependency management via [Poetry][poetry]
- 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 13.0 (support of postgis-3.0 is available).
Expand Down Expand Up @@ -55,7 +55,7 @@ If you opt to setup the project automatically, it will also:
- initialize a git repo and bump initial tag and version.
- create a virtualenv in the folder `venv` inside the project.
- install all the python dependencies inside it.
- create `poetry.lock` file after resolving dependencies and then generate `requirements.txt` and `requirements_dev.txt` for production and dev use respectively, for backward-compatibility.
- create `poetry.lock` file after resolving dependencies.
- create a postgres database and run the initial migration against it.

then only thing you'll need to do is:
Expand All @@ -67,32 +67,6 @@ Don't forget to carefully look at the generated README. Awesome, right?

You can also explore the [wiki] section for details on advance setup and usages.

## Managing dependencies

### Poetry

To guarantee repeatable installations, all project dependencies are managed using [Poetry](https://python-poetry.org/). The project’s direct dependencies are listed in `pyproject.toml`.
Running `poetry lock` generates `poetry.lock` which has all versions pinned.

You can install Poetry by using `pip install --pre poetry` or by following the official installation guide [here](https://github.com/python-poetry/poetry#installation).

*Tip:* We recommend that you use this workflow and keep `pyproject.toml` as well as `poetry.lock` under version control to make sure all computers and environments run exactly the same code.

### Other tools

For compatibility, `requirements.txt` and `requirements_dev.txt` can be updated by running

```bash
poetry export -f requirements.txt -o requirements.txt
poetry export -f requirements.txt -o requirements_dev.txt --with dev
```

or

```bash
make generate_requirements
```

## Articles

- [Setting up Django projects in a breeze](https://medium.com/fueled-engineering/setting-up-django-projects-in-a-breeze-36c715cc9a6f)
Expand Down
8 changes: 4 additions & 4 deletions hooks/post_gen_project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ green=`tput setaf 2`
reset=`tput sgr0`

# Ensure newline at EOF
find . ! -path "*/venv/*" -type f -name "*.py" -exec bash -c "tail -n1 {} | read -r _ || echo >> {}" \;
find . ! -path "*/.venv/*" -type f -name "*.py" -exec bash -c "tail -n1 {} | read -r _ || echo >> {}" \;

echo "${green}[Finished]${reset}"

echo "==> Setup project dependencies? It will:"
echo " - Create virtualenv at './{{ cookiecutter.github_repository }}/venv/'."
echo " - Install development requirements inside virtualenv."
echo " - Install development requirements using poetry"
echo " - Create a postgres database named '{{ cookiecutter.main_module }}'."
echo " - Run './manage.py migrate'."
echo " - Initialize git."
Expand All @@ -26,7 +26,7 @@ else
fi

if echo "{{ cookiecutter.add_heroku }}" | grep -iq "^n"; then
rm -rf uwsgi.ini Procfile runtime.txt bin/post_compile
rm -rf uwsgi.ini Procfile bin/post_compile
fi

if echo "{{ cookiecutter.add_fly }}" | grep -iq "^n"; then
Expand All @@ -35,7 +35,7 @@ if echo "{{ cookiecutter.add_fly }}" | grep -iq "^n"; then
fi

if echo "{{ cookiecutter.add_ansible }}" | grep -iq "^n"; then
rm -rf provisioner Vagrantfile ansible.cfg
rm -rf provisioner ansible.cfg
fi

if echo "{{ cookiecutter.add_celery }}" | grep -iq "^n"; then
Expand Down
23 changes: 12 additions & 11 deletions {{cookiecutter.github_repository}}/.github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,22 @@ jobs:
sudo apt-get update
sudo apt-get install postgresql-13-postgis-3-scripts
{%- endif %}

- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: '3.9'
cache: 'pip'
- name: Install poetry
run: |
pip3 install poetry==1.2.0
- name: Install requirements

- name: Install python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade pip poetry wheel
poetry install --with dev
- name: Run tests
run: |
poetry run pytest --cov -v --tb=native
- name: Linting
run: |
make lint

- name: Run Linting
run: make lint

- name: Run Python tests
run: poetry run pytest --cov -v --tb=native


28 changes: 7 additions & 21 deletions {{cookiecutter.github_repository}}/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ SHELL := bash

PROJECT_NAME={{cookiecutter.main_module}}
DB_NAME=$(PROJECT_NAME)
{% if cookiecutter.add_ansible.lower() == 'y' -%}
INVENTORY=provisioner/hosts
PLAYBOOK=provisioner/site.yml
{%- endif %}
ENV_PREFIX=$(shell echo 'poetry run ')


Expand Down Expand Up @@ -36,32 +38,14 @@ run_all: ## Run all the servers in parallel, requires GNU Make
make -j django docs{% if cookiecutter.add_celery == 'y' %} celery{% endif %} redis
.PHONY: run_all

virtualenv: ## Create a virtual environment.
@echo "creating virtualenv using poetry..."
@pip install -U pip poetry
@poetry env use python3
@echo
@echo "!!! Please run 'poetry shell' to enable the environment !!!"


regenerate: ## Delete and create new database.
-dropdb $(DB_NAME)
createdb $(DB_NAME)
${ENV_PREFIX}python manage.py migrate
.PHONY: regenerate

generate_requirements:
poetry export -f requirements.txt -o requirements_dev.txt --with dev
poetry export -f requirements.txt -o requirements.txt

update_libs: ## update libs + generate new lockfile & requirements
poetry update
make generate_requirements
.PHONY: update-libs

install: virtualenv ## Install and setup project dependencies
python3 -m pip install --upgrade pip wheel
make generate_requirements
install: ## Install dependencies, create db and migrate
python3 -m pip install --upgrade pip wheel poetry
poetry install
${ENV_PREFIX}pre-commit install
ifneq ($(CI),True)
Expand Down Expand Up @@ -99,7 +83,7 @@ djurls: ## Displays all the django urls
shell: ## Enter the django shell
${ENV_PREFIX}python manage.py shell_plus

docs: virtualenv ## Start documentation server locally
docs: ## Start documentation server locally
${ENV_PREFIX}mkdocs serve

{%- if cookiecutter.add_celery == 'y' %}
Expand All @@ -110,6 +94,7 @@ celery: install ## Start celery worker
redis: ## Start redis server
redis-server

{% if cookiecutter.add_ansible.lower() == 'y' %}
# Ansible related things
# ------------------------------------------------------
# Usages:
Expand Down Expand Up @@ -138,3 +123,4 @@ deploy_qa: deploy

deploy_prod: ENV=prod ## Deploy to production server
deploy_prod: deploy
{%- endif %}
15 changes: 0 additions & 15 deletions {{cookiecutter.github_repository}}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ You can install Poetry by using `pip install --pre poetry` or by following the o

_Tip:_ We recommend that you use this workflow and keep `pyproject.toml` as well as `poetry.lock` under version control to make sure all computers and environments run exactly the same code.

### Other tools

For compatibility, `requirements.txt` and `requirements_dev.txt` can be updated by running

```bash
poetry export --without-hashes -f requirements.txt -o requirements.txt
```

and

```bash
poetry export --without-hashes -f requirements.txt -o requirements_dev.txt --with dev
```

, respectively.

## Deploying Project

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ FROM python:${PYTHON_VERSION} as python

ARG BUILD_ENVIRONMENT=local
ARG APP_HOME=/app

ENV POETRY_VERSION=1.3.2
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Run these commands to deploy this project on Heroku (substitue all references of
```
heroku create --ssh-git <heroku-app-name>

heroku buildpacks:add https://github.com/moneymeets/python-poetry-buildpack.git --app=<heroku-app-name>
heroku buildpacks:set heroku/python --app=<heroku-app-name>

heroku addons:create heroku-postgresql{% if cookiecutter.add_postgis == 'y' %}:standard-0{% endif %} --app=<heroku-app-name>
Expand Down
4 changes: 0 additions & 4 deletions {{cookiecutter.github_repository}}/provisioner/hosts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ vm=0
user=ubuntu
project_namespace={% raw %}{{ project_name }}-{{ deploy_env }}{% endraw %}
project_path=/home/ubuntu/{% raw %}{{ deploy_env }}{% endraw %}/{{ cookiecutter.github_repository }}
venv_path={% raw %}{{ project_path }}/venv{% endraw %}
use_letsencrypt={{ 'True' if cookiecutter.letsencrypt.lower() == 'y' else 'False' }}
letsencrypt_email={{ cookiecutter.letsencrypt_email }}
django_requirements_file=requirements.txt
django_settings="settings.production"

[vagrant]
Expand All @@ -17,8 +15,6 @@ vm=1
deploy_env=vagrant
user=vagrant
project_path=/home/vagrant/{{ cookiecutter.github_repository }}
venv_path=/home/vagrant/venv
django_requirements_file=requirements_dev.txt
django_settings="settings.development"
use_letsencrypt=False
pg_db={{ cookiecutter.main_module }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@
file: path={{ celery_log_dir }} state=directory owner={{celery_user}} group={{celery_group}} mode=751 recurse=yes
tags: ['configure', 'celery']

- name: ensure python virtualenv exist
command: python3 -m venv {{ venv_path }} creates={{ venv_path }}
become: false
tags: ['celery']

- name: ensure celery package is installed
pip: name=celery state=present executable={{ venv_path }}/bin/pip
become: false
tags: ['celery']

- name: copy celery service
template: src=celery.service.j2 dest=/etc/systemd/system/celery-{{ project_namespace }}.service
tags: ['celery']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Group={{ celery_group }}
Type=forking
Restart=always
WorkingDirectory={{ project_path }}
ExecStart={{ venv_path }}/bin/celery -A {{ project_name }} multi start worker-{{ project_namespace }} -l {{ celery_log_level }} \
ExecStart=poetry run celery -A {{ project_name }} multi start worker-{{ project_namespace }} -l {{ celery_log_level }} \
--logfile={{ celery_log_file }} --pidfile={{ celery_pid_file }} --schedule={{ celerybeat_schedule_file}}
ExecStop={{ venv_path }}/bin/celery multi stopwait worker-{{ project_namespace }} --pidfile={{ celery_pid_file }}
ExecReload={{ venv_path }}/bin/celery -A {{ project_name }} multi restart worker-{{ project_namespace }} -l {{ celery_log_level }} \
ExecStop=poetry run celery multi stopwait worker-{{ project_namespace }} --pidfile={{ celery_pid_file }}
ExecReload=poetry run celery -A {{ project_name }} multi restart worker-{{ project_namespace }} -l {{ celery_log_level }} \
--logfile={{ celery_log_file }} --pidfile={{ celery_pid_file }} --schedule={{ celerybeat_schedule_file}}

[Install]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RuntimeDirectory={{ celery_runtime_dir }}
Group={{ celery_group }}
Restart=always
WorkingDirectory={{ project_path }}
ExecStart={{ venv_path }}/bin/celery -A {{ project_name }} beat -l {{ celery_log_level }} \
ExecStart=poetry run celery -A {{ project_name }} beat -l {{ celery_log_level }} \
--logfile={{ celerybeat_log_file }} --pidfile={{ celerybeat_pid_file }} --schedule={{ celerybeat_schedule_file}}

[Install]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ base_ubuntu:
- python3.9
- python3.9-dev
- python-setuptools
- python3-venv
- python3-pip
- sysstat
- vim
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
{% raw %}---

# Uncomment following if ipv6 is not available or not tunelled through ipv4 properly
# Disable ipv6 when running in VM(vagrant)
#- name: Disable ipv6 for all interfaces
# sysctl: name="net.ipv6.conf.all.disable_ipv6" value=1 state=present
# when: vm == 1
#
#- name: Disable ipv6 for default interface
# sysctl: name="net.ipv6.conf.default.disable_ipv6" value=1 state=present
# when: vm == 1
#
#- name: Disable ipv6 for local interface
# sysctl: name="net.ipv6.conf.lo.disable_ipv6" value=1 state=present
# when: vm == 1
- name: Set hostname
action: shell hostnamectl set-hostname {{ domain_name }}
when: vm == 0

- name: set system locale
command: update-locale LC_ALL={{ lc_all }} LANG={{ lc_lang }} LC_CTYPE={{ lc_ctype }} LC_COLLATE={{ lc_collate }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,13 @@ pg_hstore: False
pg_db: "{{ project_namespace }}"
pg_user: dev
pg_password: password
django_requirements_file: requirements.txt
{% endraw %}

{%- if cookiecutter.add_asgi.lower() == 'y' %}
# asgi related variables
asgi_user: www-data
asgi_group: www-data
asgi_workers: 2
{% raw %}
asgi_socket: /tmp/django-{{ domain_name }}-asgi.sock
{% endraw %}
asgi_user: www-data
asgi_group: www-data
asgi_workers: 2
{% raw %}asgi_socket: /tmp/django-{{ domain_name }}-asgi.sock{% endraw %}
{% else %}
# uwsgi related variables
uwsgi_user: www-data
Expand All @@ -35,8 +28,7 @@ uwsgi_emperor_pid_file: /run/uwsgi-emperor.pid
{% raw %}
uwsgi_socket: "/tmp/uwsgi-{{ project_namespace }}.sock"
uwsgi_pid_file: "/tmp/uwsgi-{{ project_namespace }}.pid"

{% endraw %}
uwsgi_log_dir: /var/log/uwsgi
uwsgi_log_file: "{{ uwsgi_log_dir }}/{{ project_namespace }}.log"
{% endraw %}
{% endif %}
Loading
Loading