mirror of
https://github.com/autistic-symposium/web3-starter-py.git
synced 2025-05-17 06:02:12 -04:00
add my custom boilerplate (#50)
This commit is contained in:
parent
1cfd785c73
commit
79b56abc7c
14 changed files with 418 additions and 0 deletions
2
boilerplates/project_boilerplate/.env.example
Normal file
2
boilerplates/project_boilerplate/.env.example
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Options are: 'error' < 'info' < 'debug'
|
||||||
|
LOG_LEVEL=info
|
160
boilerplates/project_boilerplate/.gitignore
vendored
Normal file
160
boilerplates/project_boilerplate/.gitignore
vendored
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__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/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
30
boilerplates/project_boilerplate/Makefile
Normal file
30
boilerplates/project_boilerplate/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
@find . -iname '*.py[co]' -delete
|
||||||
|
@find . -iname '__pycache__' -delete
|
||||||
|
@rm -rf '.pytest_cache'
|
||||||
|
@rm -rf dist/
|
||||||
|
@rm -rf build/
|
||||||
|
@rm -rf *.egg-info
|
||||||
|
@rm -rf .tox
|
||||||
|
@rm -rf venv/lib/python*/site-packages/*.egg
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install:
|
||||||
|
@PYTHONPATH=$(pwd) python3 setup.py install
|
||||||
|
|
||||||
|
.PHONY: install_deps
|
||||||
|
install_deps:
|
||||||
|
@PYTHONPATH=$(pwd) pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
.PHONY: install_dev
|
||||||
|
install_deps:
|
||||||
|
@PYTHONPATH=$(pwd) pip3 install -r requirements_dev.txt
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint:
|
||||||
|
@PYTHONPATH=$(pwd) tox -e lint
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
@PYTHONPATH=$(pwd) tox
|
6
boilerplates/project_boilerplate/README.md
Normal file
6
boilerplates/project_boilerplate/README.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
## python boilerplate
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
#### a customized boilerplate to make it quicker starting new projects.
|
||||||
|
|
2
boilerplates/project_boilerplate/requirements.txt
Normal file
2
boilerplates/project_boilerplate/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
python-dotenv==1.0.0
|
||||||
|
|
2
boilerplates/project_boilerplate/requirements_dev.txt
Normal file
2
boilerplates/project_boilerplate/requirements_dev.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pytest==7.4.0
|
||||||
|
tox==4.6.4
|
13
boilerplates/project_boilerplate/setup.py
Normal file
13
boilerplates/project_boilerplate/setup.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="my_package",
|
||||||
|
version='0.1',
|
||||||
|
packages=find_packages(include=['src', \
|
||||||
|
'src.utils']),
|
||||||
|
author="bt3gl",
|
||||||
|
install_requires=['python-dotenv'],
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': ['my_package=src.main:run']
|
||||||
|
},
|
||||||
|
)
|
1
boilerplates/project_boilerplate/src/__init__.py
Normal file
1
boilerplates/project_boilerplate/src/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
33
boilerplates/project_boilerplate/src/main.py
Normal file
33
boilerplates/project_boilerplate/src/main.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
# src/main.py
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
def run_menu() -> argparse.ArgumentParser:
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Run my project')
|
||||||
|
|
||||||
|
parser.add_argument('-t', dest='test', nargs=1,
|
||||||
|
help="Run test method. \
|
||||||
|
Example: <my project> -t <argument>")
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def run() -> None:
|
||||||
|
"""Entry point for this module."""
|
||||||
|
|
||||||
|
parser = run_menu()
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.test:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
parser.print_help()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run()
|
1
boilerplates/project_boilerplate/src/utils/__init__.py
Normal file
1
boilerplates/project_boilerplate/src/utils/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
130
boilerplates/project_boilerplate/src/utils/os.py
Normal file
130
boilerplates/project_boilerplate/src/utils/os.py
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
# utils/os.py
|
||||||
|
# This class implements OS/file system util methods used by the other classes.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import copy
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
|
||||||
|
def set_logging(log_level) -> None:
|
||||||
|
"""Set logging level according to .env config."""
|
||||||
|
|
||||||
|
if log_level == 'info':
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
||||||
|
|
||||||
|
elif log_level == 'error':
|
||||||
|
logging.basicConfig(level=logging.ERROR, format='%(message)s')
|
||||||
|
|
||||||
|
elif log_level == 'debug':
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format='%(message)s')
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f'Logging level {log_level} is not available. Setting to ERROR')
|
||||||
|
logging.basicConfig(level=logging.ERROR, format='%(message)s')
|
||||||
|
|
||||||
|
|
||||||
|
def load_config() -> dict:
|
||||||
|
"""Load and set environment variables."""
|
||||||
|
|
||||||
|
env_file = Path('.') / '.env'
|
||||||
|
if not os.path.isfile(env_file):
|
||||||
|
exit_with_error('Please create an .env file')
|
||||||
|
|
||||||
|
env_vars = {}
|
||||||
|
load_dotenv(env_file)
|
||||||
|
|
||||||
|
try:
|
||||||
|
env_vars['OUTPUT_DIR'] = os.getenv("OUTPUT_DIR")
|
||||||
|
set_logging(os.getenv("LOG_LEVEL"))
|
||||||
|
|
||||||
|
return env_vars
|
||||||
|
|
||||||
|
except KeyError as e:
|
||||||
|
exit_with_error(f'Cannot extract env variables: {e}. Exiting.')
|
||||||
|
|
||||||
|
|
||||||
|
def log_error(string) -> None:
|
||||||
|
"""Print STDOUT error using the logging library."""
|
||||||
|
|
||||||
|
logging.error('🚨 %s', string)
|
||||||
|
|
||||||
|
|
||||||
|
def log_info(string) -> None:
|
||||||
|
"""Print STDOUT info using the logging library."""
|
||||||
|
|
||||||
|
logging.info('🙌🏼 %s', string)
|
||||||
|
|
||||||
|
|
||||||
|
def log_debug(string) -> None:
|
||||||
|
"""Print STDOUT debug using the logging library."""
|
||||||
|
|
||||||
|
logging.debug('🟨 %s', string)
|
||||||
|
|
||||||
|
|
||||||
|
def open_json(filepath) -> dict:
|
||||||
|
"""Load and parse a file."""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as infile:
|
||||||
|
return json.load(infile)
|
||||||
|
|
||||||
|
except (IOError, FileNotFoundError, TypeError) as e:
|
||||||
|
exit_with_error(f'Failed to parse: "{filepath}": {e}')
|
||||||
|
|
||||||
|
|
||||||
|
def format_path(dir_path, filename) -> str:
|
||||||
|
"""Format a OS full filepath."""
|
||||||
|
|
||||||
|
return os.path.join(dir_path, filename)
|
||||||
|
|
||||||
|
|
||||||
|
def format_output_file(name) -> str:
|
||||||
|
"""Format the name for the result file."""
|
||||||
|
|
||||||
|
return f'{name}.json'
|
||||||
|
|
||||||
|
|
||||||
|
def save_output(destination, data) -> None:
|
||||||
|
"""Save data from memory to a destination in disk."""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(destination, 'w', encoding='utf-8') as outfile:
|
||||||
|
json.dump(data, outfile, indent=4)
|
||||||
|
|
||||||
|
except (IOError, TypeError) as e:
|
||||||
|
log_error(f'Could not save {destination}: {e}')
|
||||||
|
|
||||||
|
|
||||||
|
def create_dir(result_dir) -> None:
|
||||||
|
"""Check whether a directory exists and create it if needed."""
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(result_dir):
|
||||||
|
os.mkdir(result_dir)
|
||||||
|
|
||||||
|
except OSError as e:
|
||||||
|
log_error(f'Could not create {result_dir}: {e}')
|
||||||
|
|
||||||
|
|
||||||
|
def deep_copy(dict_to_clone) -> dict:
|
||||||
|
"""Deep copy (not reference copy) to a dict."""
|
||||||
|
|
||||||
|
return copy.deepcopy(dict_to_clone)
|
||||||
|
|
||||||
|
|
||||||
|
def exit_with_error(message) -> None:
|
||||||
|
"""Log an error message and halt the program."""
|
||||||
|
log_error(message)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def print_pid() -> None:
|
||||||
|
"""Print the PID of the current process."""
|
||||||
|
|
||||||
|
log_info(f'Starting process main os.getpid() = {os.getpid()}')
|
||||||
|
|
14
boilerplates/project_boilerplate/src/utils/strings.py
Normal file
14
boilerplates/project_boilerplate/src/utils/strings.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
# utils/strings.py
|
||||||
|
# This class implements string methods used by the other classes.
|
||||||
|
|
||||||
|
from pprint import PrettyPrinter
|
||||||
|
|
||||||
|
def pprint(data, indent=None) -> None:
|
||||||
|
"""Print dicts and data in a suitable format"""
|
||||||
|
|
||||||
|
print()
|
||||||
|
indent = indent or 4
|
||||||
|
pp = PrettyPrinter(indent=indent)
|
||||||
|
pp.pprint(data)
|
||||||
|
print()
|
|
@ -0,0 +1,16 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class TestMyFunction(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_one(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
8
boilerplates/project_boilerplate/tox.ini
Normal file
8
boilerplates/project_boilerplate/tox.ini
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[tox]
|
||||||
|
envlist = py36, py37, py38, py39, py10
|
||||||
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
|
[testenv:lint]
|
||||||
|
skip_install = true
|
||||||
|
deps = flake8
|
||||||
|
commands = flake8 src/
|
Loading…
Add table
Add a link
Reference in a new issue