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

WIP: Self-documenting environment variables #96

Open
wants to merge 5 commits into
base: develop
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
25 changes: 24 additions & 1 deletion config/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
"""Holds the setings and entrypoints."""
"""Define the configuration scheme using environ-config."""

import logging

import environ

logger = logging.getLogger(__name__)


@environ.config(prefix="SCRAM")
class AppConfig:
"""Top level configuration (i.e. SCRAM_)."""

debugger = environ.var(
default="", help='Will launch the appropriate debugger if set to either "pycharm-pydevd" or "debugpy".'
)

@debugger.validator
def _warn_on_unknown_debugger(self, var, debugger):
samoehlert marked this conversation as resolved.
Show resolved Hide resolved
if debugger and debugger not in {"pycharm-pydevd", "debugpy"}:
logger.warning("Unknown debugger value: %s", debugger)


cfg = environ.to_config(AppConfig)
13 changes: 7 additions & 6 deletions config/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@
# TODO: from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application

from config import cfg

logger = logging.getLogger(__name__)

# Here we setup a debugger if this is desired. This obviously should not be run in production.
debug = os.environ.get("DEBUG")
if debug:
logger.info("Django is set to use a debugger. Provided debug mode: %s", debug)
if debug == "pycharm-pydevd":
if cfg.debugger:
logger.info("Django is set to use a debugger. Provided debug mode: %s", cfg.debugger)
if cfg.debugger == "pycharm-pydevd":
logger.info("Entering debug mode for pycharm, make sure the debug server is running in PyCharm!")

import pydevd_pycharm

pydevd_pycharm.settrace("host.docker.internal", port=56783, stdoutToServer=True, stderrToServer=True)

logger.info("Debugger started.")
elif debug == "debugpy":
elif cfg.debugger == "debugpy":
logger.info("Entering debug mode for debugpy (VSCode)")

import debugpy
Expand All @@ -41,7 +42,7 @@

logger.info("Debugger listening on port 56780.")
else:
logger.warning("Invalid debug mode given: %s. Debugger not started", debug)
logger.warning("Invalid debug mode given: %s. Debugger not started", cfg.debugger)

# This allows easy placement of apps within the interior
# scram directory.
Expand Down
28 changes: 28 additions & 0 deletions docs/document_env_vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Converts environ-config's documentation to Markdown and writes it to the docs folder."""

import sys
from pathlib import Path

sys.path.append(".")

from config import cfg


def formatter(options):
"""Formats the help text to Markdown.

Returns:
str: A simple Markdown table with the env vars
"""
result = "| Name | Description | Required | Default |\n"
result += "|-|-|-|-|\n"
for o in options:
result += f"|{o['var_name']}|{o['help_str']}|{o['required']}|{o['default']!r}|\n"

return result


def on_pre_build(config):
"""Handler from mkdocs hook."""
with Path("docs/environment_variables.md").open("w", encoding="utf-8") as f:
f.write(cfg.generate_help(formatter=formatter))
4 changes: 2 additions & 2 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

The SCRAM ecosystem consists of two parts:

A Django app, [route_manager](/reference/django)
A Django app, [route_manager](django.md)

A translator service, [translator](/reference/translator)
A translator service, [translator](translator.md)
3 changes: 3 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ plugins:
show_submodules: true
- search
- section-index

hooks:
- docs/document_env_vars.py
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data_file = "coverage.coverage"

[tool.coverage.report]
exclude_also = [
"if cfg.debugger:",
"if debug:",
"if self.debug:",
"if settings.DEBUG",
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
django-celery-beat # https://github.com/celery/django-celery-beat
django-netfields # https://pypi.org/project/django-netfields/
environ-config # https://pypi.org/project/environ-config/
flower==1.0.0 # https://github.com/mher/flower
python-slugify==6.1.2 # https://github.com/un33k/python-slugify
uvicorn[standard]==0.17.6 # https://github.com/encode/uvicorn
Expand Down
6 changes: 0 additions & 6 deletions requirements/local.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,3 @@ django-debug-toolbar==3.4.0 # https://github.com/jazzband/django-debug-toolbar
django-extensions==3.1.5 # https://github.com/django-extensions/django-extensions
django-coverage-plugin==3.1.0 # https://github.com/nedbat/django_coverage_plugin
pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django

# Debugging
# ------------------------------------------------------------------------------
debugpy
# Pycharm might force you to be on the same version IDE as library, use caution.
pydevd-pycharm
13 changes: 7 additions & 6 deletions translator/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import websockets
from gobgp import GoBGP

from config import cfg

logger = logging.getLogger(__name__)

KNOWN_MESSAGES = {
Expand All @@ -21,8 +23,7 @@
}

# Here we setup a debugger if this is desired. This obviously should not be run in production.
debug_mode = os.environ.get("DEBUG")
if debug_mode:
if cfg.debugger:

def install_deps():
"""Install necessary dependencies for debuggers.
Expand All @@ -41,10 +42,10 @@ def install_deps():

logger.info("Done installing dependencies for debuggers")

logger.info("Translator is set to use a debugger. Provided debug mode: %s", debug_mode)
logger.info("Translator is set to use a debugger. Provided debug mode: %s", cfg.debugger)
# We have to setup the debugger appropriately for various IDEs. It'd be nice if they all used the same thing but
# sadly, we live in a fallen world.
if debug_mode == "pycharm-pydevd":
if cfg.debugger == "pycharm-pydevd":
logger.info("Entering debug mode for pycharm, make sure the debug server is running in PyCharm!")

install_deps()
Expand All @@ -54,7 +55,7 @@ def install_deps():
pydevd_pycharm.settrace("host.docker.internal", port=56782, stdoutToServer=True, stderrToServer=True)

logger.info("Debugger started.")
elif debug_mode == "debugpy":
elif cfg.debugger == "debugpy":
logger.info("Entering debug mode for debugpy (VSCode)")

install_deps()
Expand All @@ -65,7 +66,7 @@ def install_deps():

logger.info("Debugger listening on port 56781.")
else:
logger.warning("Invalid debug mode given: %s. Debugger not started", debug_mode)
logger.warning("Invalid debug mode given: %s. Debugger not started", cfg.debugger)

# Must match the URL in asgi.py, and needs a trailing slash
hostname = os.environ.get("SCRAM_HOSTNAME", "scram_hostname_not_set")
Expand Down
Loading