diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c2492d319637f293dc56dfccdd4f5c36e270d918
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,24 @@
+name: Release python package
+
+on:
+  push:
+    branches:
+    - master
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: '3.8'
+    - name: Install deps
+      uses: knowsuchagency/poetry-install@v1
+      env:
+        POETRY_VIRTUALENVS_CREATE: false
+    - name: Release package
+      env:
+        POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
+      run: poetry publish --build
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 485dee64bcfb48793379b200a1afd14e85a8aaf4..2b839523f3b848599603fd7de2e9d5ec11056b2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,140 @@
 .idea
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+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/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .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/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
diff --git a/README.md b/README.md
index 7e867d16706109e831a741d4fba86a6a7df4d7ff..53ba166bc7bdf4e9a646f44413d5d03beebb70d4 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@
 ⚠️ [Git](https://git-scm.com/downloads), [Python](https://www.python.org/), and [Docker-compose](https://docs.docker.com/compose/install/) must be installed and accessible ⚠️
 
 ```bash
-python3 -m pip install cookiecutter
-cookiecutter gh:s3rius/FastAPI-template
+python3 -m pip install fastapi_template
+fastapi_template
 # Answer prompts questions
 # ???
 # 🍪 Enjoy your new project 🍪
@@ -22,7 +22,4 @@ Currently supported features:
 - systemd units
 - Example (dummy) SQLAlchemy model
 - Elastic Search support
-- Scheduler support
-
-Planned features:
-- Add Makefile support
+- Scheduler support
\ No newline at end of file
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
deleted file mode 100644
index 2715205b7d8e4fff6868e5c2877b71a95848fbd7..0000000000000000000000000000000000000000
--- a/hooks/post_gen_project.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-import os
-import shutil
-import subprocess
-import sys
-
-import json
-
-MANIFEST = "conditional_files.json"
-FIRST_RUN_WIN = "first_run.bat"
-FIRST_RUN = "first_run.sh"
-
-
-def delete_resource(resource):
-    if os.path.isfile(resource):
-        print("removing file: {}".format(resource))
-        os.remove(resource)
-    elif os.path.isdir(resource):
-        print("removing directory: {}".format(resource))
-        shutil.rmtree(resource)
-
-
-def delete_resources_for_disabled_features():
-    with open(MANIFEST) as manifest_file:
-        manifest = json.load(manifest_file)
-        for feature in manifest['features']:
-            if not feature['enabled'] == "true":
-                print("removing resources for disabled feature {}...".format(feature['name']))
-                for resource in feature['resources']:
-                    delete_resource(resource)
-    print("cleanup complete, removing manifest...")
-    delete_resource(MANIFEST)
-
-
-def init_repo():
-    if sys.platform == 'win32':
-        subprocess.run([FIRST_RUN_WIN])
-        return
-    else:
-        subprocess.run(['sh', FIRST_RUN])
-    delete_resource(FIRST_RUN)
-    delete_resource(FIRST_RUN_WIN)
-    subprocess.run(['git', 'add', '.'])
-
-
-if __name__ == "__main__":
-    delete_resources_for_disabled_features()
-    init_repo()
diff --git a/main.py b/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6b3063181a082217f77a89a9225777c88ee0bc3
--- /dev/null
+++ b/main.py
@@ -0,0 +1,24 @@
+from pathlib import Path
+
+from cookiecutter.exceptions import FailedHookException, OutputDirExistsException
+from cookiecutter.main import cookiecutter
+from termcolor import cprint
+
+script_dir = Path(__file__).parent
+
+
+def main():
+    try:
+        cookiecutter(template=f"{script_dir}/template")
+    except (FailedHookException, OutputDirExistsException) as exc:
+        if isinstance(exc, OutputDirExistsException):
+            cprint(
+                "Directory with such name already exists!",
+                "red"
+            )
+        return
+    cprint("Project successfully generated. You can read information about usage in README.md")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/poetry.lock b/poetry.lock
new file mode 100644
index 0000000000000000000000000000000000000000..9f69da846f5e7212a55e1efbe0d96dfb9fb8bbb6
--- /dev/null
+++ b/poetry.lock
@@ -0,0 +1,556 @@
+[[package]]
+name = "appdirs"
+version = "1.4.4"
+description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "arrow"
+version = "0.17.0"
+description = "Better dates & times for Python"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+python-dateutil = ">=2.7.0"
+
+[[package]]
+name = "binaryornot"
+version = "0.4.4"
+description = "Ultra-lightweight pure Python package to check if a file is binary or text."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+chardet = ">=3.0.2"
+
+[[package]]
+name = "cached-property"
+version = "1.5.2"
+description = "A decorator for caching properties in classes."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "certifi"
+version = "2020.11.8"
+description = "Python package for providing Mozilla's CA Bundle."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "cffi"
+version = "1.14.3"
+description = "Foreign Function Interface for Python calling C code."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+pycparser = "*"
+
+[[package]]
+name = "cfgv"
+version = "3.2.0"
+description = "Validate configuration and produce human readable error messages."
+category = "main"
+optional = false
+python-versions = ">=3.6.1"
+
+[[package]]
+name = "chardet"
+version = "3.0.4"
+description = "Universal encoding detector for Python 2 and 3"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "click"
+version = "7.1.2"
+description = "Composable command line interface toolkit"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[[package]]
+name = "cookiecutter"
+version = "1.7.2"
+description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+binaryornot = ">=0.4.4"
+click = ">=7.0"
+Jinja2 = "<3.0.0"
+jinja2-time = ">=0.2.0"
+MarkupSafe = "<2.0.0"
+poyo = ">=0.5.0"
+python-slugify = ">=4.0.0"
+requests = ">=2.23.0"
+six = ">=1.10"
+
+[[package]]
+name = "distlib"
+version = "0.3.1"
+description = "Distribution utilities"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "filelock"
+version = "3.0.12"
+description = "A platform independent file lock."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "identify"
+version = "1.5.9"
+description = "File identification library for Python"
+category = "main"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
+
+[package.extras]
+license = ["editdistance"]
+
+[[package]]
+name = "idna"
+version = "2.10"
+description = "Internationalized Domain Names in Applications (IDNA)"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[[package]]
+name = "jinja2"
+version = "2.11.2"
+description = "A very fast and expressive template engine."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+MarkupSafe = ">=0.23"
+
+[package.extras]
+i18n = ["Babel (>=0.8)"]
+
+[[package]]
+name = "jinja2-time"
+version = "0.2.0"
+description = "Jinja2 Extension for Dates and Times"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+arrow = "*"
+jinja2 = "*"
+
+[[package]]
+name = "markupsafe"
+version = "1.1.1"
+description = "Safely add untrusted strings to HTML/XML markup."
+category = "main"
+optional = false
+python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
+
+[[package]]
+name = "nodeenv"
+version = "1.5.0"
+description = "Node.js virtual environment builder"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "poyo"
+version = "0.5.0"
+description = "A lightweight YAML Parser for Python. 🐓"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[[package]]
+name = "pre-commit"
+version = "2.8.2"
+description = "A framework for managing and maintaining multi-language pre-commit hooks."
+category = "main"
+optional = false
+python-versions = ">=3.6.1"
+
+[package.dependencies]
+cfgv = ">=2.0.0"
+identify = ">=1.0.0"
+nodeenv = ">=0.11.1"
+pyyaml = ">=5.1"
+toml = "*"
+virtualenv = ">=20.0.8"
+
+[[package]]
+name = "pycparser"
+version = "2.20"
+description = "C parser in Python"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[[package]]
+name = "pygit2"
+version = "1.4.0"
+description = "Python bindings for libgit2."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+cached-property = "*"
+cffi = ">=1.4.0"
+
+[[package]]
+name = "python-dateutil"
+version = "2.8.1"
+description = "Extensions to the standard Python datetime module"
+category = "main"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
+
+[package.dependencies]
+six = ">=1.5"
+
+[[package]]
+name = "python-slugify"
+version = "4.0.1"
+description = "A Python Slugify application that handles Unicode"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+text-unidecode = ">=1.3"
+
+[package.extras]
+unidecode = ["Unidecode (>=1.1.1)"]
+
+[[package]]
+name = "pyyaml"
+version = "5.3.1"
+description = "YAML parser and emitter for Python"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[[package]]
+name = "requests"
+version = "2.25.0"
+description = "Python HTTP for Humans."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+chardet = ">=3.0.2,<4"
+idna = ">=2.5,<3"
+urllib3 = ">=1.21.1,<1.27"
+
+[package.extras]
+security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
+socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
+
+[[package]]
+name = "six"
+version = "1.15.0"
+description = "Python 2 and 3 compatibility utilities"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+
+[[package]]
+name = "termcolor"
+version = "1.1.0"
+description = "ANSII Color formatting for output in terminal."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "text-unidecode"
+version = "1.3"
+description = "The most basic Text::Unidecode port"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "toml"
+version = "0.10.2"
+description = "Python Library for Tom's Obvious, Minimal Language"
+category = "main"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+
+[[package]]
+name = "urllib3"
+version = "1.26.2"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
+
+[package.extras]
+brotli = ["brotlipy (>=0.6.0)"]
+secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
+socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+
+[[package]]
+name = "virtualenv"
+version = "20.1.0"
+description = "Virtual Python Environment builder"
+category = "main"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
+
+[package.dependencies]
+appdirs = ">=1.4.3,<2"
+distlib = ">=0.3.1,<1"
+filelock = ">=3.0.0,<4"
+six = ">=1.9.0,<2"
+
+[package.extras]
+docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"]
+testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
+
+[metadata]
+lock-version = "1.1"
+python-versions = "^3.8"
+content-hash = "33b8d26680a3c261f42bc2a403e6fad6800e544608213bf58e35f8aec070e6d6"
+
+[metadata.files]
+appdirs = [
+    {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
+    {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
+]
+arrow = [
+    {file = "arrow-0.17.0-py2.py3-none-any.whl", hash = "sha256:e098abbd9af3665aea81bdd6c869e93af4feb078e98468dd351c383af187aac5"},
+    {file = "arrow-0.17.0.tar.gz", hash = "sha256:ff08d10cda1d36c68657d6ad20d74fbea493d980f8b2d45344e00d6ed2bf6ed4"},
+]
+binaryornot = [
+    {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"},
+    {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
+]
+cached-property = [
+    {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
+    {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"},
+]
+certifi = [
+    {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"},
+    {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"},
+]
+cffi = [
+    {file = "cffi-1.14.3-2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc"},
+    {file = "cffi-1.14.3-2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768"},
+    {file = "cffi-1.14.3-2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d"},
+    {file = "cffi-1.14.3-2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1"},
+    {file = "cffi-1.14.3-2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca"},
+    {file = "cffi-1.14.3-2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a"},
+    {file = "cffi-1.14.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c"},
+    {file = "cffi-1.14.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730"},
+    {file = "cffi-1.14.3-cp27-cp27m-win32.whl", hash = "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d"},
+    {file = "cffi-1.14.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05"},
+    {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b"},
+    {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171"},
+    {file = "cffi-1.14.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f"},
+    {file = "cffi-1.14.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4"},
+    {file = "cffi-1.14.3-cp35-cp35m-win32.whl", hash = "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d"},
+    {file = "cffi-1.14.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d"},
+    {file = "cffi-1.14.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3"},
+    {file = "cffi-1.14.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808"},
+    {file = "cffi-1.14.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537"},
+    {file = "cffi-1.14.3-cp36-cp36m-win32.whl", hash = "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0"},
+    {file = "cffi-1.14.3-cp36-cp36m-win_amd64.whl", hash = "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e"},
+    {file = "cffi-1.14.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1"},
+    {file = "cffi-1.14.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579"},
+    {file = "cffi-1.14.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394"},
+    {file = "cffi-1.14.3-cp37-cp37m-win32.whl", hash = "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc"},
+    {file = "cffi-1.14.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869"},
+    {file = "cffi-1.14.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e"},
+    {file = "cffi-1.14.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828"},
+    {file = "cffi-1.14.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9"},
+    {file = "cffi-1.14.3-cp38-cp38-win32.whl", hash = "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522"},
+    {file = "cffi-1.14.3-cp38-cp38-win_amd64.whl", hash = "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15"},
+    {file = "cffi-1.14.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d"},
+    {file = "cffi-1.14.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c"},
+    {file = "cffi-1.14.3-cp39-cp39-win32.whl", hash = "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b"},
+    {file = "cffi-1.14.3-cp39-cp39-win_amd64.whl", hash = "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3"},
+    {file = "cffi-1.14.3.tar.gz", hash = "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591"},
+]
+cfgv = [
+    {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"},
+    {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"},
+]
+chardet = [
+    {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
+    {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"},
+]
+click = [
+    {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
+    {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
+]
+cookiecutter = [
+    {file = "cookiecutter-1.7.2-py2.py3-none-any.whl", hash = "sha256:430eb882d028afb6102c084bab6cf41f6559a77ce9b18dc6802e3bc0cc5f4a30"},
+    {file = "cookiecutter-1.7.2.tar.gz", hash = "sha256:efb6b2d4780feda8908a873e38f0e61778c23f6a2ea58215723bcceb5b515dac"},
+]
+distlib = [
+    {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"},
+    {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"},
+]
+filelock = [
+    {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
+    {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
+]
+identify = [
+    {file = "identify-1.5.9-py2.py3-none-any.whl", hash = "sha256:5dd84ac64a9a115b8e0b27d1756b244b882ad264c3c423f42af8235a6e71ca12"},
+    {file = "identify-1.5.9.tar.gz", hash = "sha256:c9504ba6a043ee2db0a9d69e43246bc138034895f6338d5aed1b41e4a73b1513"},
+]
+idna = [
+    {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
+    {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
+]
+jinja2 = [
+    {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"},
+    {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"},
+]
+jinja2-time = [
+    {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"},
+    {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"},
+]
+markupsafe = [
+    {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
+    {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
+    {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
+    {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
+    {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
+    {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
+    {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
+    {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
+    {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
+    {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
+    {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
+    {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
+    {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
+    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
+    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
+    {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
+    {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
+    {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
+    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
+    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
+    {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
+    {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
+    {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
+    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
+    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
+    {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
+    {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
+    {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
+]
+nodeenv = [
+    {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"},
+    {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"},
+]
+poyo = [
+    {file = "poyo-0.5.0-py2.py3-none-any.whl", hash = "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a"},
+    {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"},
+]
+pre-commit = [
+    {file = "pre_commit-2.8.2-py2.py3-none-any.whl", hash = "sha256:22e6aa3bd571debb01eb7d34483f11c01b65237be4eebbf30c3d4fb65762d315"},
+    {file = "pre_commit-2.8.2.tar.gz", hash = "sha256:905ebc9b534b991baec87e934431f2d0606ba27f2b90f7f652985f5a5b8b6ae6"},
+]
+pycparser = [
+    {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
+    {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
+]
+pygit2 = [
+    {file = "pygit2-1.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b422e417739def0a136a6355723dfe8a5ffc83db5098076f28a14f1d139779c1"},
+    {file = "pygit2-1.4.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32eb863d6651d4890ced318505ea8dc229bd9637deaf29c898de1ab574d727a0"},
+    {file = "pygit2-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:0d298098e286eeda000e49ca7e1b41f87300e10dd8b9d06b32b008bd61f50b83"},
+    {file = "pygit2-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9c8d5881eb709e2e2e13000b507a131bd5fb91a879581030088d0ddffbcd19af"},
+    {file = "pygit2-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ddb7a1f6d38063e8724abfa1cfdfb0f9b25014b8bca0546274b7a84b873a3888"},
+    {file = "pygit2-1.4.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ec5c0365a9bdfcac1609d20868507b28685ec5ea7cc3a2c903c9b62ef2e0bbc0"},
+    {file = "pygit2-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:818c91b582109d90580c5da74af783738838353f15eb12eeb734d80a974b05a3"},
+    {file = "pygit2-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9c2f2d9ef59513007b66f6534b000792b614de3faf60313a0a68f6b8571aea85"},
+    {file = "pygit2-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8306a302487dac67df7af6a064bb37e8a8eb4138958f9560ff49ff162e185dab"},
+    {file = "pygit2-1.4.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d0d889144e9487d926fecea947c3f39ce5f477e521d7d467d2e66907e4cd657d"},
+    {file = "pygit2-1.4.0-cp38-cp38-win32.whl", hash = "sha256:41204b6f3406d9f53147710f3cc485d77181ba67f57c34d36b7c86de1c14a18c"},
+    {file = "pygit2-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:cf00481ddf053e549a6edd0216bdc267b292d261eae02a67bb3737de920cbf88"},
+    {file = "pygit2-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37d6d7d6d7804c42a0fe23425c72e38093488525092fc5e51a05684e63503ce7"},
+    {file = "pygit2-1.4.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:e9037a7d810750fe23c9f5641ef14a0af2525ff03e14752cd4f73e1870ecfcb0"},
+    {file = "pygit2-1.4.0-cp39-cp39-win32.whl", hash = "sha256:fdd8ba30cda277290e000322f505132f590cf89bd7d31829b45a3cb57447ec32"},
+    {file = "pygit2-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ee135eb2cd8b07ce1374f3596cc5c3213472d6389bad6a4c5d87d8e267e93e9"},
+    {file = "pygit2-1.4.0.tar.gz", hash = "sha256:cbeb38ab1df9b5d8896548a11e63aae8a064763ab5f1eabe4475e6b8a78ee1c8"},
+]
+python-dateutil = [
+    {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
+    {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
+]
+python-slugify = [
+    {file = "python-slugify-4.0.1.tar.gz", hash = "sha256:69a517766e00c1268e5bbfc0d010a0a8508de0b18d30ad5a1ff357f8ae724270"},
+]
+pyyaml = [
+    {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
+    {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"},
+    {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"},
+    {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"},
+    {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"},
+    {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"},
+    {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"},
+    {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"},
+    {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"},
+    {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"},
+    {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
+]
+requests = [
+    {file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"},
+    {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"},
+]
+six = [
+    {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
+    {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
+]
+termcolor = [
+    {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
+]
+text-unidecode = [
+    {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
+    {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
+]
+toml = [
+    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
+    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
+]
+urllib3 = [
+    {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"},
+    {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"},
+]
+virtualenv = [
+    {file = "virtualenv-20.1.0-py2.py3-none-any.whl", hash = "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2"},
+    {file = "virtualenv-20.1.0.tar.gz", hash = "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380"},
+]
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..87aee88370156f112e5dd15083433c47a5e6c0ea
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,24 @@
+[tool.poetry]
+name = "fastapi_template"
+version = "1.1.4"
+description = "Feature-rich robust FastAPI template"
+authors = ["Pavel Kirilin <win10@list.ru>"]
+packages = [
+    { include = "template" },
+]
+
+[tool.poetry.dependencies]
+python = "^3.8"
+cookiecutter = "^1.7.2"
+pre-commit = "^2.8.2"
+termcolor = "^1.1.0"
+pygit2 = "^1.4.0"
+
+[tool.poetry.dev-dependencies]
+
+[tool.poetry.scripts]
+fastapi_template = "main:main"
+
+[build-system]
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
diff --git a/cookiecutter.json b/template/cookiecutter.json
similarity index 93%
rename from cookiecutter.json
rename to template/cookiecutter.json
index ca30c04b03cf250102d6a49a58d5c520751477c0..6bc0e644d2c578956c9798c85e4693859c08ba52 100644
--- a/cookiecutter.json
+++ b/template/cookiecutter.json
@@ -1,6 +1,6 @@
 {
   "project_name": "new_fastapi_project",
-  "full_name": "Pavel Kirilin",
+  "full_name": "Your name",
   "email": "win10@list.ru",
   "project_description": "",
   "default_port": 8401,
diff --git a/hooks/__init__.py b/template/hooks/__init__.py
similarity index 100%
rename from hooks/__init__.py
rename to template/hooks/__init__.py
diff --git a/template/hooks/post_gen_project.py b/template/hooks/post_gen_project.py
new file mode 100644
index 0000000000000000000000000000000000000000..412b32a75de51bca7f3e7d83f1c1116b456df5fa
--- /dev/null
+++ b/template/hooks/post_gen_project.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+import json
+import os
+import shutil
+from argparse import Namespace
+
+import pre_commit.constants as pre_commit_constants
+import pre_commit.main as pre_commit
+from pygit2 import init_repository
+from termcolor import cprint
+
+MANIFEST = "conditional_files.json"
+
+
+def delete_resource(resource):
+    if os.path.isfile(resource):
+        print("removing file: {}".format(resource))
+        os.remove(resource)
+    elif os.path.isdir(resource):
+        print("removing directory: {}".format(resource))
+        shutil.rmtree(resource)
+
+
+def delete_resources_for_disabled_features():
+    with open(MANIFEST) as manifest_file:
+        manifest = json.load(manifest_file)
+        for feature in manifest['features']:
+            if not feature['enabled'] == "true":
+                print("removing resources for disabled feature {}...".format(feature['name']))
+                for resource in feature['resources']:
+                    delete_resource(resource)
+    print("cleanup complete, removing manifest...")
+    delete_resource(MANIFEST)
+
+
+def init_repo():
+    store = pre_commit.Store()
+    repo_path = os.getcwd()
+    repo = init_repository(repo_path)
+    cprint("Git repository initialized.", "green")
+    repo.index.add_all()
+    repo.index.write()
+    cprint("Added files to index.", "green")
+    pre_commit.install(
+        config_file=pre_commit_constants.CONFIG_FILE,
+        store=store,
+        hook_types=["pre-commit"],
+        overwrite=False
+    )
+    cprint("pre-commit installed.", "green")
+    run_namespace = Namespace(
+        all_files=True,
+        files=[],
+        hook_stage='commit',
+        from_ref=None,
+        to_ref=None,
+        remote_name=None,
+        checkout_type=None,
+        hook=None,
+        verbose=False,
+        color=True,
+        show_diff_on_failure=False
+    )
+    pre_commit.run(
+        config_file=pre_commit_constants.CONFIG_FILE,
+        store=store,
+        args=run_namespace
+    )
+    repo.index.add_all()
+    repo.index.write()
+
+
+if __name__ == "__main__":
+    delete_resources_for_disabled_features()
+    init_repo()
diff --git a/hooks/pre_gen_project.py b/template/hooks/pre_gen_project.py
similarity index 100%
rename from hooks/pre_gen_project.py
rename to template/hooks/pre_gen_project.py
diff --git a/{{cookiecutter.project_name}}/.gitignore b/template/{{cookiecutter.project_name}}/.gitignore
similarity index 100%
rename from {{cookiecutter.project_name}}/.gitignore
rename to template/{{cookiecutter.project_name}}/.gitignore
diff --git a/{{cookiecutter.project_name}}/.gitlab-ci.yml b/template/{{cookiecutter.project_name}}/.gitlab-ci.yml
similarity index 100%
rename from {{cookiecutter.project_name}}/.gitlab-ci.yml
rename to template/{{cookiecutter.project_name}}/.gitlab-ci.yml
diff --git a/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/template/{{cookiecutter.project_name}}/.pre-commit-config.yaml
similarity index 100%
rename from {{cookiecutter.project_name}}/.pre-commit-config.yaml
rename to template/{{cookiecutter.project_name}}/.pre-commit-config.yaml
diff --git a/{{cookiecutter.project_name}}/Dockerfile b/template/{{cookiecutter.project_name}}/Dockerfile
similarity index 100%
rename from {{cookiecutter.project_name}}/Dockerfile
rename to template/{{cookiecutter.project_name}}/Dockerfile
diff --git a/{{cookiecutter.project_name}}/README.md b/template/{{cookiecutter.project_name}}/README.md
similarity index 100%
rename from {{cookiecutter.project_name}}/README.md
rename to template/{{cookiecutter.project_name}}/README.md
diff --git a/{{cookiecutter.project_name}}/alembic.ini b/template/{{cookiecutter.project_name}}/alembic.ini
similarity index 100%
rename from {{cookiecutter.project_name}}/alembic.ini
rename to template/{{cookiecutter.project_name}}/alembic.ini
diff --git a/{{cookiecutter.project_name}}/conditional_files.json b/template/{{cookiecutter.project_name}}/conditional_files.json
similarity index 100%
rename from {{cookiecutter.project_name}}/conditional_files.json
rename to template/{{cookiecutter.project_name}}/conditional_files.json
diff --git a/{{cookiecutter.project_name}}/deploy.sh b/template/{{cookiecutter.project_name}}/deploy.sh
similarity index 100%
rename from {{cookiecutter.project_name}}/deploy.sh
rename to template/{{cookiecutter.project_name}}/deploy.sh
diff --git a/{{cookiecutter.project_name}}/docker-compose.prod.yml b/template/{{cookiecutter.project_name}}/docker-compose.prod.yml
similarity index 100%
rename from {{cookiecutter.project_name}}/docker-compose.prod.yml
rename to template/{{cookiecutter.project_name}}/docker-compose.prod.yml
diff --git a/{{cookiecutter.project_name}}/docker-compose.yml b/template/{{cookiecutter.project_name}}/docker-compose.yml
similarity index 100%
rename from {{cookiecutter.project_name}}/docker-compose.yml
rename to template/{{cookiecutter.project_name}}/docker-compose.yml
diff --git a/{{cookiecutter.project_name}}/envs/example.env b/template/{{cookiecutter.project_name}}/envs/example.env
similarity index 100%
rename from {{cookiecutter.project_name}}/envs/example.env
rename to template/{{cookiecutter.project_name}}/envs/example.env
diff --git a/{{cookiecutter.project_name}}/envs/test.env b/template/{{cookiecutter.project_name}}/envs/test.env
similarity index 100%
rename from {{cookiecutter.project_name}}/envs/test.env
rename to template/{{cookiecutter.project_name}}/envs/test.env
diff --git a/{{cookiecutter.project_name}}/main.py b/template/{{cookiecutter.project_name}}/main.py
similarity index 91%
rename from {{cookiecutter.project_name}}/main.py
rename to template/{{cookiecutter.project_name}}/main.py
index 262ac78c298c40ae7c1dfe3f3f1db00fb0345cdd..90b61689af6294a0f1623de73b5b44104846f864 100644
--- a/{{cookiecutter.project_name}}/main.py
+++ b/template/{{cookiecutter.project_name}}/main.py
@@ -30,7 +30,7 @@ def parse_args() -> argparse.Namespace:
     parser = argparse.ArgumentParser()
     parser.add_argument("--host", type=str, default="0.0.0.0")
     parser.add_argument("--port", type=int, default=8000)
-    parser.add_argument("--pid-file", type=str, default="/tmp/fastapi_service.pid")
+    parser.add_argument("--pid-file", type=str, default="/tmp/{{cookiecutter.project_name}}.pid")
     return parser.parse_args()
 
 
@@ -38,7 +38,7 @@ if __name__ == "__main__":
     args = parse_args()
     options = {
         "bind": f"{args.host}:{args.port}",
-        "workers": 1,
+        "workers": 4,
         "worker_class": "uvicorn.workers.UvicornWorker",
         "pidfile": args.pid_file,
     }
diff --git a/{{cookiecutter.project_name}}/migrations/__init__.py b/template/{{cookiecutter.project_name}}/migrations/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/migrations/__init__.py
rename to template/{{cookiecutter.project_name}}/migrations/__init__.py
diff --git a/{{cookiecutter.project_name}}/migrations/env.py b/template/{{cookiecutter.project_name}}/migrations/env.py
similarity index 100%
rename from {{cookiecutter.project_name}}/migrations/env.py
rename to template/{{cookiecutter.project_name}}/migrations/env.py
diff --git a/{{cookiecutter.project_name}}/migrations/script.py.mako b/template/{{cookiecutter.project_name}}/migrations/script.py.mako
similarity index 100%
rename from {{cookiecutter.project_name}}/migrations/script.py.mako
rename to template/{{cookiecutter.project_name}}/migrations/script.py.mako
diff --git a/{{cookiecutter.project_name}}/migrations/versions/7ae297ab5ac1_created_dummy_model.py b/template/{{cookiecutter.project_name}}/migrations/versions/7ae297ab5ac1_created_dummy_model.py
similarity index 100%
rename from {{cookiecutter.project_name}}/migrations/versions/7ae297ab5ac1_created_dummy_model.py
rename to template/{{cookiecutter.project_name}}/migrations/versions/7ae297ab5ac1_created_dummy_model.py
diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/template/{{cookiecutter.project_name}}/pyproject.toml
similarity index 100%
rename from {{cookiecutter.project_name}}/pyproject.toml
rename to template/{{cookiecutter.project_name}}/pyproject.toml
diff --git a/{{cookiecutter.project_name}}/pytest.ini b/template/{{cookiecutter.project_name}}/pytest.ini
similarity index 100%
rename from {{cookiecutter.project_name}}/pytest.ini
rename to template/{{cookiecutter.project_name}}/pytest.ini
diff --git a/{{cookiecutter.project_name}}/scheduler.py b/template/{{cookiecutter.project_name}}/scheduler.py
similarity index 100%
rename from {{cookiecutter.project_name}}/scheduler.py
rename to template/{{cookiecutter.project_name}}/scheduler.py
diff --git a/{{cookiecutter.project_name}}/src/__init__.py b/template/{{cookiecutter.project_name}}/src/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/__init__.py
rename to template/{{cookiecutter.project_name}}/src/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/api/__init__.py b/template/{{cookiecutter.project_name}}/src/api/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/__init__.py
rename to template/{{cookiecutter.project_name}}/src/api/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/api/dummy_db/__init__.py b/template/{{cookiecutter.project_name}}/src/api/dummy_db/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/dummy_db/__init__.py
rename to template/{{cookiecutter.project_name}}/src/api/dummy_db/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/api/dummy_db/routes.py b/template/{{cookiecutter.project_name}}/src/api/dummy_db/routes.py
similarity index 95%
rename from {{cookiecutter.project_name}}/src/api/dummy_db/routes.py
rename to template/{{cookiecutter.project_name}}/src/api/dummy_db/routes.py
index 9f4569308ed83f5119a87532c4c87f7f3bfb0410..886ed0759073f21610df125ad67eecf192b0c812 100644
--- a/{{cookiecutter.project_name}}/src/api/dummy_db/routes.py
+++ b/template/{{cookiecutter.project_name}}/src/api/dummy_db/routes.py
@@ -23,6 +23,10 @@ URL_PREFIX = "/dummy_db_obj"
 
 @router.put("/")
 async def create_dummy(dummy_obj: {% if cookiecutter.add_elastic_search == "True" -%}ElasticAdd{% else %}BaseDummyModel{% endif %}, session: Session = Depends(db_session)) -> None:
+    """
+    Add dummy object in database.
+    If you have elastic search feature enabled it will be added in your index.
+    """
     {% if cookiecutter.add_elastic_search == "True" -%}
     insert_query = DummyDBModel.create(**dummy_obj.dict()).returning(DummyDBModel.id)
     model_id = await session.scalar(insert_query)
diff --git a/{{cookiecutter.project_name}}/src/api/dummy_db/schema.py b/template/{{cookiecutter.project_name}}/src/api/dummy_db/schema.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/dummy_db/schema.py
rename to template/{{cookiecutter.project_name}}/src/api/dummy_db/schema.py
diff --git a/{{cookiecutter.project_name}}/src/api/httpbin/__init__.py b/template/{{cookiecutter.project_name}}/src/api/httpbin/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/httpbin/__init__.py
rename to template/{{cookiecutter.project_name}}/src/api/httpbin/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/api/httpbin/routes.py b/template/{{cookiecutter.project_name}}/src/api/httpbin/routes.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/httpbin/routes.py
rename to template/{{cookiecutter.project_name}}/src/api/httpbin/routes.py
diff --git a/{{cookiecutter.project_name}}/src/api/httpbin/schema.py b/template/{{cookiecutter.project_name}}/src/api/httpbin/schema.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/httpbin/schema.py
rename to template/{{cookiecutter.project_name}}/src/api/httpbin/schema.py
diff --git a/{{cookiecutter.project_name}}/src/api/redis_api/__init__.py b/template/{{cookiecutter.project_name}}/src/api/redis_api/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/redis_api/__init__.py
rename to template/{{cookiecutter.project_name}}/src/api/redis_api/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/api/redis_api/routes.py b/template/{{cookiecutter.project_name}}/src/api/redis_api/routes.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/redis_api/routes.py
rename to template/{{cookiecutter.project_name}}/src/api/redis_api/routes.py
diff --git a/{{cookiecutter.project_name}}/src/api/redis_api/schema.py b/template/{{cookiecutter.project_name}}/src/api/redis_api/schema.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/api/redis_api/schema.py
rename to template/{{cookiecutter.project_name}}/src/api/redis_api/schema.py
diff --git a/{{cookiecutter.project_name}}/src/exceptions.py b/template/{{cookiecutter.project_name}}/src/exceptions.py
similarity index 69%
rename from {{cookiecutter.project_name}}/src/exceptions.py
rename to template/{{cookiecutter.project_name}}/src/exceptions.py
index a7f117a82533a9b76b4ebd6ff6b9205454821219..ec7a868371e73cb0a978e9c2b3df86d84104fd1c 100644
--- a/{{cookiecutter.project_name}}/src/exceptions.py
+++ b/template/{{cookiecutter.project_name}}/src/exceptions.py
@@ -3,6 +3,13 @@ from httpx import Response
 
 
 class ServiceError(HTTPException):
+    """
+    This exception can be returned from handler as is.
+    If this exception is raised you can skip handling.
+
+    Your application will return normal response
+     with status_code=400 and human-readable message.
+    """
     def __init__(self, action: str, service_response: Response) -> None:
         try:
             error_data = service_response.json()
diff --git a/{{cookiecutter.project_name}}/src/models/__init__.py b/template/{{cookiecutter.project_name}}/src/models/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/models/__init__.py
rename to template/{{cookiecutter.project_name}}/src/models/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/models/dummy_db_model.py b/template/{{cookiecutter.project_name}}/src/models/dummy_db_model.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/models/dummy_db_model.py
rename to template/{{cookiecutter.project_name}}/src/models/dummy_db_model.py
diff --git a/{{cookiecutter.project_name}}/src/server.py b/template/{{cookiecutter.project_name}}/src/server.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/server.py
rename to template/{{cookiecutter.project_name}}/src/server.py
diff --git a/{{cookiecutter.project_name}}/src/services/__init__.py b/template/{{cookiecutter.project_name}}/src/services/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/__init__.py
rename to template/{{cookiecutter.project_name}}/src/services/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/services/db/__init__.py b/template/{{cookiecutter.project_name}}/src/services/db/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/db/__init__.py
rename to template/{{cookiecutter.project_name}}/src/services/db/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/services/db/base.py b/template/{{cookiecutter.project_name}}/src/services/db/base.py
similarity index 75%
rename from {{cookiecutter.project_name}}/src/services/db/base.py
rename to template/{{cookiecutter.project_name}}/src/services/db/base.py
index e590105b59fe6e6603606163028f589ba6a5826d..6584a3cda83673154366f74da4d43c1b4b525d84 100644
--- a/{{cookiecutter.project_name}}/src/services/db/base.py
+++ b/template/{{cookiecutter.project_name}}/src/services/db/base.py
@@ -10,7 +10,29 @@ from src.services.db.db_meta import meta
 
 @as_declarative(metadata=meta)
 class Base:
-    """Base class for all models"""
+    """
+    Base class for all models
+
+    It has some very cool methods which allows you
+    to ship autocompletion and type verification to SQLAlchemy models.
+
+    >>> class Model(Base):
+    >>>     name = sa.Column(sa.String())
+    >>>
+    >>>     @classmethod
+    >>>     def get_by_name(cls, name: str) -> sa.sql.Select:
+    >>>         return Model.select_query(cls.id).where(cls.name == name)
+    ...
+    >>> session.fetchall(Model.get_by_name("random_name"))
+
+    `id`, `created_at` and `updated_at` columns are created
+    automatically for all models.
+
+    Basic settings form models such as `__name__`, `__table__` and `__table_args__`
+    defined with types to allow mypy verify this data.
+
+    `__tablename__` generated automatically based on class name.
+    """
 
     __name__: str
     __table__: sa.Table
diff --git a/{{cookiecutter.project_name}}/src/services/db/db_meta.py b/template/{{cookiecutter.project_name}}/src/services/db/db_meta.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/db/db_meta.py
rename to template/{{cookiecutter.project_name}}/src/services/db/db_meta.py
diff --git a/{{cookiecutter.project_name}}/src/services/db/engine.py b/template/{{cookiecutter.project_name}}/src/services/db/engine.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/db/engine.py
rename to template/{{cookiecutter.project_name}}/src/services/db/engine.py
diff --git a/{{cookiecutter.project_name}}/src/services/db/session.py b/template/{{cookiecutter.project_name}}/src/services/db/session.py
similarity index 52%
rename from {{cookiecutter.project_name}}/src/services/db/session.py
rename to template/{{cookiecutter.project_name}}/src/services/db/session.py
index cfb036efaa71409fe4edff2e52d658b669c79f42..45b9fbedfe9b73d11c1271e347ab3d43a53776af 100644
--- a/{{cookiecutter.project_name}}/src/services/db/session.py
+++ b/template/{{cookiecutter.project_name}}/src/services/db/session.py
@@ -6,26 +6,53 @@ from src.services.db import db_engine
 
 
 class Session:
+    """
+    Database session object.
+    It used to acquire connection from pool
+    and execute many queries using one connection.
+    """
     def __init__(self, connection: SAConnection):
         self.connection = connection
 
     async def execute(self, query: Any) -> Any:
+        """
+        Simply execute SQLAlchemy generated query
+        or string query and return raw results.
+        """
         return await self.connection.execute(query)
 
     async def fetchone(self, query: Any) -> Any:
+        """
+        Get one object from database by query.
+        """
         cursor = await self.connection.execute(query)
         return await cursor.fetchone()
 
     async def scalar(self, query: Any) -> Any:
+        """
+        Scalar returns first column of the first result.
+        It's convenient fot such things as getting function result.
+
+        >>> session = Session(connection)
+        >>> session.scalar(Model.insert_query(**values).returning(Model.id))
+        UUID('7a9ffbfe-f871-42fb-a371-7bd29227a9ff')
+        """
         result = await self.fetchone(query)
         return result[0]
 
     async def fetchall(self, query: Any) -> List[Any]:
+        """
+        Get all matching objects from database by query.
+        """
         cursor = await self.connection.execute(query)
         return await cursor.fetchall()
 
 
 async def db_session() -> AsyncGenerator[Session, None]:
+    """
+    Dependency to acquire connection from database pool
+    and close it when handler function is proceeds.
+    """
     connection = await db_engine.client.acquire()
     session = Session(connection)
     try:
diff --git a/{{cookiecutter.project_name}}/src/services/elastic/__init__.py b/template/{{cookiecutter.project_name}}/src/services/elastic/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/elastic/__init__.py
rename to template/{{cookiecutter.project_name}}/src/services/elastic/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/services/elastic/client.py b/template/{{cookiecutter.project_name}}/src/services/elastic/client.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/elastic/client.py
rename to template/{{cookiecutter.project_name}}/src/services/elastic/client.py
diff --git a/{{cookiecutter.project_name}}/src/services/elastic/mixin.py b/template/{{cookiecutter.project_name}}/src/services/elastic/mixin.py
similarity index 74%
rename from {{cookiecutter.project_name}}/src/services/elastic/mixin.py
rename to template/{{cookiecutter.project_name}}/src/services/elastic/mixin.py
index ec33a446686d97c7a7e2c7e746162550d0bcaac6..0b217f981a20b90e4fcdfe859b89a90feac6da85 100644
--- a/{{cookiecutter.project_name}}/src/services/elastic/mixin.py
+++ b/template/{{cookiecutter.project_name}}/src/services/elastic/mixin.py
@@ -13,6 +13,17 @@ SearchModel = TypeVar("SearchModel", covariant=True, bound=ESReturnModel)
 
 
 class ElasticModelMixin(Generic[SearchModel]):
+    """
+    Mixin to simplify ElasticSearch integration with SQLAlchemy models.
+
+    It has three main variables to override in model.
+
+    1) __es_index_name - it's a name of the index in ElasticSearch where
+        data for model would be stored.
+    2) __es_search_fields - the list of fields use in search query.
+    3) __es_search_type - covariant of `SearchModel` to return from `elastic_filter`.
+        If you won't define it `elastic_filter` will return dict.
+    """
     __es_index_name: str = "default_index"
     __es_search_fields: List[str] = []
     __es_search_type: Optional[SearchModel] = None
@@ -21,6 +32,11 @@ class ElasticModelMixin(Generic[SearchModel]):
     async def elastic_add(
         cls, model_id: uuid.UUID, *, tags: Optional[str] = "", **kwargs: Any
     ) -> None:
+        """
+        Add object to elastic index.
+
+        >>> await Model.elastic_index(uuid.uuid4(), name="La", surname="Tex")
+        """
         ret = await elastic_client.index(
             index=cls.__es_index_name,
             body={"tags": tags.split(",") if tags else [], **kwargs},
@@ -33,6 +49,12 @@ class ElasticModelMixin(Generic[SearchModel]):
     async def elastic_filter(
         cls, *, query: str, offset: int, limit: int
     ) -> List[Union[SearchModel, Dict[str, Any]]]:
+        """
+        Filter existing models in ElasticSearch by string query.
+        This function uses __es_search_fields as fields for phrase_prefix query.
+
+        >>> await Model.elastic_filter(query="La")
+        """
         elastic_query = Search()
         if query:
             elastic_query = elastic_query.query(
@@ -56,6 +78,9 @@ class ElasticModelMixin(Generic[SearchModel]):
         model_id: uuid.UUID,
         **body: Any,
     ) -> None:
+        """
+        Update model in ElasticSearch by id.
+        """
         tags = body.get("tags", None)
         if tags is not None:
             body["tags"] = tags.split(",") if tags else []
@@ -72,6 +97,9 @@ class ElasticModelMixin(Generic[SearchModel]):
 
     @classmethod
     async def elastic_delete(cls, model_id: uuid.UUID) -> None:
+        """
+        Delete object from ElasticSearch index.
+        """
         try:
             await elastic_client.delete(index=cls.__es_index_name, id=str(model_id))
         except NotFoundError:
@@ -79,6 +107,9 @@ class ElasticModelMixin(Generic[SearchModel]):
 
     @classmethod
     async def elastic_create_index(cls) -> None:
+        """
+        Create index if it's not exists.
+        """
         if not await elastic_client.indices.exists(cls.__es_index_name):
             logger.debug(f"Creating elastic index {cls.__es_index_name}")
             await elastic_client.indices.create(cls.__es_index_name)
diff --git a/{{cookiecutter.project_name}}/src/services/elastic/schema.py b/template/{{cookiecutter.project_name}}/src/services/elastic/schema.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/elastic/schema.py
rename to template/{{cookiecutter.project_name}}/src/services/elastic/schema.py
diff --git a/{{cookiecutter.project_name}}/src/services/httpbin/__init__.py b/template/{{cookiecutter.project_name}}/src/services/httpbin/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/httpbin/__init__.py
rename to template/{{cookiecutter.project_name}}/src/services/httpbin/__init__.py
diff --git a/{{cookiecutter.project_name}}/src/services/httpbin/client.py b/template/{{cookiecutter.project_name}}/src/services/httpbin/client.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/httpbin/client.py
rename to template/{{cookiecutter.project_name}}/src/services/httpbin/client.py
diff --git a/{{cookiecutter.project_name}}/src/services/httpbin/schema.py b/template/{{cookiecutter.project_name}}/src/services/httpbin/schema.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/services/httpbin/schema.py
rename to template/{{cookiecutter.project_name}}/src/services/httpbin/schema.py
diff --git a/{{cookiecutter.project_name}}/src/services/redis.py b/template/{{cookiecutter.project_name}}/src/services/redis.py
similarity index 96%
rename from {{cookiecutter.project_name}}/src/services/redis.py
rename to template/{{cookiecutter.project_name}}/src/services/redis.py
index a21f10090d420616bb1b21b4f592ddb3e56d6bbb..33dfd60e3251c01eaf005f7c72659eb78732eebe 100644
--- a/{{cookiecutter.project_name}}/src/services/redis.py
+++ b/template/{{cookiecutter.project_name}}/src/services/redis.py
@@ -7,6 +7,9 @@ from src.settings import settings
 
 
 class RedisClient:
+    """
+    Super simple redis client.
+    """
     def __init__(self, address: Union[str, Tuple[str, int]], password: str):
         self.address = address
         self.password = password
diff --git a/{{cookiecutter.project_name}}/src/settings.py b/template/{{cookiecutter.project_name}}/src/settings.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/settings.py
rename to template/{{cookiecutter.project_name}}/src/settings.py
diff --git a/{{cookiecutter.project_name}}/src/utils.py b/template/{{cookiecutter.project_name}}/src/utils.py
similarity index 100%
rename from {{cookiecutter.project_name}}/src/utils.py
rename to template/{{cookiecutter.project_name}}/src/utils.py
diff --git a/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_scheduler.service b/template/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_scheduler.service
similarity index 100%
rename from {{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_scheduler.service
rename to template/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_scheduler.service
diff --git a/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_service.service b/template/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_service.service
similarity index 100%
rename from {{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_service.service
rename to template/{{cookiecutter.project_name}}/systemd/{{ cookiecutter.project_name }}_service.service
diff --git a/{{cookiecutter.project_name}}/tests/__init__.py b/template/{{cookiecutter.project_name}}/tests/__init__.py
similarity index 100%
rename from {{cookiecutter.project_name}}/tests/__init__.py
rename to template/{{cookiecutter.project_name}}/tests/__init__.py
diff --git a/{{cookiecutter.project_name}}/tests/conftest.py b/template/{{cookiecutter.project_name}}/tests/conftest.py
similarity index 100%
rename from {{cookiecutter.project_name}}/tests/conftest.py
rename to template/{{cookiecutter.project_name}}/tests/conftest.py
diff --git a/{{cookiecutter.project_name}}/tests/dummy_db_test.py b/template/{{cookiecutter.project_name}}/tests/dummy_db_test.py
similarity index 100%
rename from {{cookiecutter.project_name}}/tests/dummy_db_test.py
rename to template/{{cookiecutter.project_name}}/tests/dummy_db_test.py
diff --git a/{{cookiecutter.project_name}}/envs/.env b/{{cookiecutter.project_name}}/envs/.env
deleted file mode 100644
index 4c2e415347b362d53df3e02c62fbfa76e09f1df7..0000000000000000000000000000000000000000
--- a/{{cookiecutter.project_name}}/envs/.env
+++ /dev/null
@@ -1,17 +0,0 @@
-LOG_LEVEL=Debug
-POSTGRES_HOST=db
-POSTGRES_PORT=5432
-POSTGRES_DB={{cookiecutter.project_name}}_db
-POSTGRES_USER={{cookiecutter.project_name}}
-POSTGRES_PASSWORD={{cookiecutter.postgres_password}}
-{% if cookiecutter.add_redis == "True" -%}
-REDIS_PASSWORD={{cookiecutter.redis_password}}
-REDIS_HOST=redis
-REDIS_PORT=6379
-{% endif %}
-{% if cookiecutter.add_scheduler == "True" -%}
-SCHEDULE_TIMER=20
-{% endif %}
-{% if cookiecutter.add_elastic_search == "True" -%}
-ELASTIC_HOST=http://es:9200
-{% endif %}
\ No newline at end of file
diff --git a/{{cookiecutter.project_name}}/first_run.bat b/{{cookiecutter.project_name}}/first_run.bat
deleted file mode 100644
index f1d87fe797d206d465682b7cef2ade79534c2af8..0000000000000000000000000000000000000000
--- a/{{cookiecutter.project_name}}/first_run.bat
+++ /dev/null
@@ -1,6 +0,0 @@
-python3 -m pip install --user pre-commit
-git init
-git add .
-pre-commit install
-pre-commit run -a
-git add .
\ No newline at end of file
diff --git a/{{cookiecutter.project_name}}/first_run.sh b/{{cookiecutter.project_name}}/first_run.sh
deleted file mode 100644
index f1d87fe797d206d465682b7cef2ade79534c2af8..0000000000000000000000000000000000000000
--- a/{{cookiecutter.project_name}}/first_run.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-python3 -m pip install --user pre-commit
-git init
-git add .
-pre-commit install
-pre-commit run -a
-git add .
\ No newline at end of file