mirror of
https://github.com/thegeeklab/ansible-doctor.git
synced 2024-11-21 20:30:43 +00:00
feat: migrate to dynaconf to handle multi-source configuration (#708)
This commit is contained in:
parent
9b20c11660
commit
8e042c739e
@ -12,7 +12,7 @@ ENV TZ=UTC
|
||||
|
||||
ADD dist/ansible_doctor-*.whl /
|
||||
|
||||
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
|
||||
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev git && \
|
||||
pip install --upgrade --no-cache-dir pip && \
|
||||
pip install --no-cache-dir $(find / -name "ansible_doctor-*.whl")[ansible-core] && \
|
||||
rm -f ansible_doctor-*.whl && \
|
||||
|
@ -18,11 +18,17 @@ class AnsibleDoctor:
|
||||
def __init__(self):
|
||||
self.log = SingleLog()
|
||||
self.logger = self.log.logger
|
||||
self.args = self._cli_args()
|
||||
self.config = self._get_config()
|
||||
|
||||
try:
|
||||
self.config = SingleConfig()
|
||||
self.config.load(args=self._parse_args())
|
||||
self.log.register_hanlers(json=self.config.config.logging.json)
|
||||
except ansibledoctor.exception.ConfigError as e:
|
||||
self.log.sysexit_with_message(e)
|
||||
|
||||
self._execute()
|
||||
|
||||
def _cli_args(self):
|
||||
def _parse_args(self):
|
||||
"""
|
||||
Use argparse for parsing CLI arguments.
|
||||
|
||||
@ -33,28 +39,40 @@ class AnsibleDoctor:
|
||||
description="Generate documentation from annotated Ansible roles using templates"
|
||||
)
|
||||
parser.add_argument(
|
||||
"base_dir", nargs="?", help="base directory (default: current working directory)"
|
||||
"base_dir",
|
||||
nargs="?",
|
||||
default=self.config.config.base_dir,
|
||||
help="base directory (default: current working directory)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", "--config", dest="config_file", help="path to configuration file"
|
||||
"-c",
|
||||
"--config",
|
||||
dest="config_file",
|
||||
help="path to configuration file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o", "--output", dest="output_dir", action="store", help="output directory"
|
||||
"-o",
|
||||
"--output",
|
||||
dest="renderer__dest",
|
||||
action="store",
|
||||
default=self.config.config.renderer.dest,
|
||||
help="output directory",
|
||||
metavar="OUTPUT_DIR",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--recursive",
|
||||
dest="recursive",
|
||||
action="store_true",
|
||||
default=None,
|
||||
default=self.config.config.recursive,
|
||||
help="run recursively over the base directory subfolders",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
dest="force_overwrite",
|
||||
dest="renderer.force_overwrite",
|
||||
action="store_true",
|
||||
default=None,
|
||||
default=self.config.config.renderer.force_overwrite,
|
||||
help="force overwrite output file",
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -62,7 +80,7 @@ class AnsibleDoctor:
|
||||
"--dry-run",
|
||||
dest="dry_run",
|
||||
action="store_true",
|
||||
default=None,
|
||||
default=self.config.config.dry_run,
|
||||
help="dry run without writing",
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -70,49 +88,58 @@ class AnsibleDoctor:
|
||||
"--no-role-detection",
|
||||
dest="role_detection",
|
||||
action="store_false",
|
||||
default=None,
|
||||
default=self.config.config.role.autodetect,
|
||||
help="disable automatic role detection",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", dest="logging.level", action="append_const", const=-1, help="increase log level"
|
||||
"-v",
|
||||
dest="logging.level",
|
||||
action="append_const",
|
||||
const=-1,
|
||||
help="increase log level",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", dest="logging.level", action="append_const", const=1, help="decrease log level"
|
||||
"-q",
|
||||
dest="logging.level",
|
||||
action="append_const",
|
||||
const=1,
|
||||
help="decrease log level",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
action="version",
|
||||
version=f"%(prog)s {__version__}",
|
||||
)
|
||||
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||
|
||||
return parser.parse_args().__dict__
|
||||
|
||||
def _get_config(self):
|
||||
try:
|
||||
config = SingleConfig(args=self.args)
|
||||
except ansibledoctor.exception.ConfigError as e:
|
||||
self.log.sysexit_with_message(e)
|
||||
|
||||
return config
|
||||
|
||||
def _execute(self):
|
||||
cwd = self.config.base_dir
|
||||
cwd = os.path.abspath(self.config.config.base_dir)
|
||||
walkdirs = [cwd]
|
||||
|
||||
if self.config.recursive:
|
||||
if self.config.config.recursive:
|
||||
walkdirs = [f.path for f in os.scandir(cwd) if f.is_dir()]
|
||||
|
||||
for item in walkdirs:
|
||||
os.chdir(item)
|
||||
|
||||
self.config.set_config(base_dir=os.getcwd())
|
||||
try:
|
||||
self.log.set_level(self.config.config["logging"]["level"])
|
||||
self.config.load(root_path=os.getcwd())
|
||||
self.log.register_hanlers(json=self.config.config.logging.json)
|
||||
except ansibledoctor.exception.ConfigError as e:
|
||||
self.log.sysexit_with_message(e)
|
||||
|
||||
try:
|
||||
self.log.set_level(self.config.config.logging.level)
|
||||
except ValueError as e:
|
||||
self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
|
||||
self.logger.info(f"Using config file: {self.config.config_file}")
|
||||
self.logger.info(f"Using config file: {self.config.config_files}")
|
||||
|
||||
self.logger.debug(f"Using working dir: {item}")
|
||||
self.logger.debug(f"Using working directory: {os.path.relpath(item, self.log.ctx)}")
|
||||
|
||||
if self.config.config["role_detection"]:
|
||||
if self.config.is_role:
|
||||
self.logger.info(f"Ansible role detected: {self.config.config['role_name']}")
|
||||
if self.config.config.role.autodetect:
|
||||
if self.config.is_role():
|
||||
self.logger.info(f"Ansible role detected: {self.config.config.role_name}")
|
||||
else:
|
||||
self.log.sysexit_with_message("No Ansible role detected")
|
||||
else:
|
||||
|
@ -3,133 +3,15 @@
|
||||
|
||||
import os
|
||||
|
||||
import anyconfig
|
||||
import environs
|
||||
import jsonschema.exceptions
|
||||
import ruamel.yaml
|
||||
from appdirs import AppDirs
|
||||
from jsonschema._utils import format_as_index
|
||||
from dynaconf import Dynaconf, ValidationError, Validator
|
||||
|
||||
import ansibledoctor.exception
|
||||
from ansibledoctor.utils import Singleton
|
||||
|
||||
config_dir = AppDirs("ansible-doctor").user_config_dir
|
||||
default_config_file = os.path.join(config_dir, "config.yml")
|
||||
default_envs_prefix = "ANSIBLE_DOCTOR_"
|
||||
|
||||
|
||||
class Config:
|
||||
"""
|
||||
Create an object with all necessary settings.
|
||||
|
||||
Settings are loade from multiple locations in defined order (last wins):
|
||||
- default settings defined by `self._get_defaults()`
|
||||
- yaml config file, defaults to OS specific user config dir (https://pypi.org/project/appdirs/)
|
||||
- provides cli parameters
|
||||
"""
|
||||
|
||||
SETTINGS = {
|
||||
"config_file": {
|
||||
"default": default_config_file,
|
||||
"env": "CONFIG_FILE",
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"base_dir": {
|
||||
"default": os.getcwd(),
|
||||
"refresh": os.getcwd,
|
||||
"env": "BASE_DIR",
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"role_name": {
|
||||
"default": "",
|
||||
"env": "ROLE_NAME",
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"dry_run": {
|
||||
"default": False,
|
||||
"env": "DRY_RUN",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"logging.level": {
|
||||
"default": "WARNING",
|
||||
"env": "LOG_LEVEL",
|
||||
"file": True,
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"logging.json": {
|
||||
"default": False,
|
||||
"env": "LOG_JSON",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"output_dir": {
|
||||
"default": os.getcwd(),
|
||||
"refresh": os.getcwd,
|
||||
"env": "OUTPUT_DIR",
|
||||
"file": True,
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"recursive": {
|
||||
"default": False,
|
||||
"env": "RECURSIVE",
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"template_dir": {
|
||||
"default": os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates"),
|
||||
"env": "TEMPLATE_DIR",
|
||||
"file": True,
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"template": {
|
||||
"default": "readme",
|
||||
"env": "TEMPLATE",
|
||||
"file": True,
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"template_autotrim": {
|
||||
"default": True,
|
||||
"env": "TEMPLATE_AUTOTRIM",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"force_overwrite": {
|
||||
"default": False,
|
||||
"env": "FORCE_OVERWRITE",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"custom_header": {
|
||||
"default": "",
|
||||
"env": "CUSTOM_HEADER",
|
||||
"file": True,
|
||||
"type": environs.Env().str,
|
||||
},
|
||||
"exclude_files": {
|
||||
"default": [],
|
||||
"env": "EXCLUDE_FILES",
|
||||
"file": True,
|
||||
"type": environs.Env().list,
|
||||
},
|
||||
"exclude_tags": {
|
||||
"default": [],
|
||||
"env": "EXCLUDE_TAGS",
|
||||
"file": True,
|
||||
"type": environs.Env().list,
|
||||
},
|
||||
"role_detection": {
|
||||
"default": True,
|
||||
"env": "ROLE_DETECTION",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
"tabulate_variables": {
|
||||
"default": False,
|
||||
"env": "TABULATE_VARIABLES",
|
||||
"file": True,
|
||||
"type": environs.Env().bool,
|
||||
},
|
||||
}
|
||||
"""Create configuration object."""
|
||||
|
||||
ANNOTATIONS = {
|
||||
"meta": {
|
||||
@ -164,174 +46,161 @@ class Config:
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, args=None):
|
||||
"""
|
||||
Initialize a new settings class.
|
||||
def __init__(self):
|
||||
self.config_files = [
|
||||
os.path.join(AppDirs("ansible-doctor").user_config_dir, "config.yml"),
|
||||
".ansibledoctor",
|
||||
".ansibledoctor.yml",
|
||||
".ansibledoctor.yaml",
|
||||
]
|
||||
self.config_merge = True
|
||||
self.args = {}
|
||||
self.load()
|
||||
|
||||
:param args: An optional dict of options, arguments and commands from the CLI.
|
||||
:param config_file: An optional path to a yaml config file.
|
||||
:returns: None
|
||||
def load(self, root_path=None, args=None):
|
||||
if args:
|
||||
if args.get("config_file"):
|
||||
self.config_merge = False
|
||||
self.config_files = [os.path.abspath(args.get("config_file"))]
|
||||
args.pop("config_file")
|
||||
|
||||
"""
|
||||
if args is None:
|
||||
self._args = {}
|
||||
else:
|
||||
self._args = args
|
||||
self._schema = None
|
||||
self.config = None
|
||||
self.is_role = False
|
||||
self.set_config()
|
||||
self.args = args
|
||||
|
||||
def _get_args(self, args):
|
||||
cleaned = dict(filter(lambda item: item[1] is not None, args.items()))
|
||||
self.config = Dynaconf(
|
||||
envvar_prefix="ANSIBLE_DOCTOR",
|
||||
merge_enabled=self.config_merge,
|
||||
core_loaders=["YAML"],
|
||||
root_path=root_path,
|
||||
settings_files=self.config_files,
|
||||
fresh_vars=["base_dir", "output_dir"],
|
||||
validators=[
|
||||
Validator(
|
||||
"base_dir",
|
||||
default=os.getcwd(),
|
||||
apply_default_on_none=True,
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"dry_run",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"recursive",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"exclude_files",
|
||||
default=[],
|
||||
is_type_of=list,
|
||||
),
|
||||
Validator(
|
||||
"exclude_tags",
|
||||
default=[],
|
||||
is_type_of=list,
|
||||
),
|
||||
Validator(
|
||||
"role.name",
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"role.autodetect",
|
||||
default=True,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"logging.level",
|
||||
default="WARNING",
|
||||
is_in=[
|
||||
"DEBUG",
|
||||
"INFO",
|
||||
"WARNING",
|
||||
"ERROR",
|
||||
"CRITICAL",
|
||||
"debug",
|
||||
"info",
|
||||
"warning",
|
||||
"error",
|
||||
"critical",
|
||||
],
|
||||
),
|
||||
Validator(
|
||||
"logging.json",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"recursive",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"template.src",
|
||||
default=os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates"),
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"template.name",
|
||||
default="readme",
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"template.options.tabulate_variables",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"renderer.autotrim",
|
||||
default=True,
|
||||
is_type_of=bool,
|
||||
),
|
||||
Validator(
|
||||
"renderer.include_header",
|
||||
default="",
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"renderer.dest",
|
||||
default=os.path.relpath(os.getcwd()),
|
||||
is_type_of=str,
|
||||
),
|
||||
Validator(
|
||||
"renderer.force_overwrite",
|
||||
default=False,
|
||||
is_type_of=bool,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
normalized = {}
|
||||
for key, value in cleaned.items():
|
||||
normalized = self._add_dict_branch(normalized, key.split("."), value)
|
||||
self.validate()
|
||||
|
||||
# Override correct log level from argparse
|
||||
levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||
log_level = levels.index(self.SETTINGS["logging.level"]["default"])
|
||||
if normalized.get("logging"):
|
||||
for adjustment in normalized["logging"]["level"]:
|
||||
log_level = min(len(levels) - 1, max(log_level + adjustment, 0))
|
||||
normalized["logging"]["level"] = levels[log_level]
|
||||
log_level = levels.index(self.config.logging.level.upper())
|
||||
if self.args.get("logging.level") and isinstance(self.args["logging.level"], list):
|
||||
for lvl in self.args["logging.level"]:
|
||||
log_level = min(len(levels) - 1, max(log_level + lvl, 0))
|
||||
|
||||
return normalized
|
||||
self.args["logging__level"] = levels[log_level]
|
||||
|
||||
def _get_defaults(self):
|
||||
normalized = {}
|
||||
for key, item in self.SETTINGS.items():
|
||||
if item.get("refresh"):
|
||||
item["default"] = item["refresh"]()
|
||||
normalized = self._add_dict_branch(normalized, key.split("."), item["default"])
|
||||
if root_path:
|
||||
self.args["base_dir"] = root_path
|
||||
|
||||
self.schema = anyconfig.gen_schema(normalized)
|
||||
return normalized
|
||||
self.config.update(self.args)
|
||||
self.validate()
|
||||
|
||||
def _get_envs(self):
|
||||
normalized = {}
|
||||
for key, item in self.SETTINGS.items():
|
||||
if item.get("env"):
|
||||
envname = f"{default_envs_prefix}{item['env']}"
|
||||
def validate(self):
|
||||
try:
|
||||
value = item["type"](envname)
|
||||
normalized = self._add_dict_branch(normalized, key.split("."), value)
|
||||
except environs.EnvError as e:
|
||||
if f'"{envname}" not set' in str(e):
|
||||
pass
|
||||
else:
|
||||
raise ansibledoctor.exception.ConfigError(
|
||||
"Unable to read environment variable", str(e)
|
||||
) from e
|
||||
self.config.validators.validate_all()
|
||||
except ValidationError as e:
|
||||
raise ansibledoctor.exception.ConfigError("Configuration error", e.message) from e
|
||||
|
||||
return normalized
|
||||
|
||||
def set_config(self, base_dir=None):
|
||||
args = self._get_args(self._args)
|
||||
envs = self._get_envs()
|
||||
defaults = self._get_defaults()
|
||||
|
||||
self.recursive = defaults.get("recursive")
|
||||
if envs.get("recursive"):
|
||||
self.recursive = envs.get("recursive")
|
||||
if args.get("recursive"):
|
||||
self.recursive = args.get("recursive")
|
||||
if "recursive" in defaults:
|
||||
defaults.pop("recursive")
|
||||
|
||||
self.config_file = defaults.get("config_file")
|
||||
if envs.get("config_file"):
|
||||
self.config_file = self._normalize_path(envs.get("config_file"))
|
||||
if args.get("config_file"):
|
||||
self.config_file = self._normalize_path(args.get("config_file"))
|
||||
if "config_file" in defaults:
|
||||
defaults.pop("config_file")
|
||||
|
||||
self.base_dir = defaults.get("base_dir")
|
||||
if envs.get("base_dir"):
|
||||
self.base_dir = self._normalize_path(envs.get("base_dir"))
|
||||
if args.get("base_dir"):
|
||||
self.base_dir = self._normalize_path(args.get("base_dir"))
|
||||
if base_dir:
|
||||
self.base_dir = base_dir
|
||||
if "base_dir" in defaults:
|
||||
defaults.pop("base_dir")
|
||||
|
||||
self.is_role = os.path.isdir(os.path.join(self.base_dir, "tasks"))
|
||||
|
||||
# compute role_name default
|
||||
defaults["role_name"] = os.path.basename(self.base_dir)
|
||||
|
||||
source_files = []
|
||||
source_files.append((self.config_file, False))
|
||||
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor"), True))
|
||||
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor.yml"), True))
|
||||
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor.yaml"), True))
|
||||
|
||||
for config, first_found in source_files:
|
||||
if config and os.path.exists(config):
|
||||
with open(config, encoding="utf8") as stream:
|
||||
s = stream.read()
|
||||
try:
|
||||
file_dict = ruamel.yaml.YAML(typ="safe", pure=True).load(s)
|
||||
except (
|
||||
ruamel.yaml.composer.ComposerError,
|
||||
ruamel.yaml.scanner.ScannerError,
|
||||
) as e:
|
||||
message = f"{e.context} {e.problem}"
|
||||
raise ansibledoctor.exception.ConfigError(
|
||||
f"Unable to read config file: {config}", message
|
||||
) from e
|
||||
|
||||
if self._validate(file_dict):
|
||||
anyconfig.merge(defaults, file_dict, ac_merge=anyconfig.MS_DICTS)
|
||||
defaults["logging"]["level"] = defaults["logging"]["level"].upper()
|
||||
|
||||
self.config_file = config
|
||||
if first_found:
|
||||
break
|
||||
|
||||
if self._validate(envs):
|
||||
anyconfig.merge(defaults, envs, ac_merge=anyconfig.MS_DICTS)
|
||||
|
||||
if self._validate(args):
|
||||
anyconfig.merge(defaults, args, ac_merge=anyconfig.MS_DICTS)
|
||||
|
||||
fix_files = ["output_dir", "template_dir", "custom_header"]
|
||||
for filename in fix_files:
|
||||
if defaults[filename] and defaults[filename] != "":
|
||||
defaults[filename] = self._normalize_path(defaults[filename])
|
||||
|
||||
defaults["logging"]["level"] = defaults["logging"]["level"].upper()
|
||||
|
||||
self.config = defaults
|
||||
|
||||
def _normalize_path(self, path):
|
||||
if not os.path.isabs(path):
|
||||
base = os.path.join(os.getcwd(), path)
|
||||
return os.path.abspath(os.path.expanduser(os.path.expandvars(base)))
|
||||
|
||||
return path
|
||||
|
||||
def _validate(self, config):
|
||||
try:
|
||||
anyconfig.validate(config, self.schema, ac_schema_safe=False)
|
||||
except jsonschema.exceptions.ValidationError as e:
|
||||
schema = format_as_index(list(e.relative_schema_path)[:-1])
|
||||
schema_error = f"Failed validating '{e.validator}' in schema {schema}\n{e.message}"
|
||||
raise ansibledoctor.exception.ConfigError("Configuration error", schema_error) from e
|
||||
|
||||
return True
|
||||
|
||||
def _add_dict_branch(self, tree, vector, value):
|
||||
key = vector[0]
|
||||
tree[key] = (
|
||||
value
|
||||
if len(vector) == 1
|
||||
else self._add_dict_branch(tree.get(key, {}), vector[1:], value)
|
||||
def is_role(self):
|
||||
self.config.role_name = self.config.get(
|
||||
"role_name", os.path.basename(self.config.base_dir)
|
||||
)
|
||||
return tree
|
||||
return os.path.isdir(os.path.join(self.config.base_dir, "tasks"))
|
||||
|
||||
def get_annotations_definition(self, automatic=True):
|
||||
annotations = {}
|
||||
@ -355,9 +224,9 @@ class Config:
|
||||
|
||||
:return: str abs path
|
||||
"""
|
||||
template_dir = self.config.get("template_dir")
|
||||
template = self.config.get("template")
|
||||
return os.path.realpath(os.path.join(template_dir, template))
|
||||
template_base = self.config.get("template.src")
|
||||
template_name = self.config.get("template.name")
|
||||
return os.path.realpath(os.path.join(template_base, template_name))
|
||||
|
||||
|
||||
class SingleConfig(Config, metaclass=Singleton):
|
||||
|
@ -36,14 +36,14 @@ class Generator:
|
||||
|
||||
:return: None
|
||||
"""
|
||||
template_dir = self.config.get_template()
|
||||
if os.path.isdir(template_dir):
|
||||
self.logger.info(f"Using template dir: {template_dir}")
|
||||
template = self.config.get_template()
|
||||
if os.path.isdir(template):
|
||||
self.logger.info(f"Using template: {os.path.relpath(template, self.log.ctx)}")
|
||||
else:
|
||||
self.log.sysexit_with_message(f"Can not open template dir {template_dir}")
|
||||
self.log.sysexit_with_message(f"Can not open template directory {template}")
|
||||
|
||||
for file in glob.iglob(template_dir + "/**/*." + self.extension, recursive=True):
|
||||
relative_file = file[len(template_dir) + 1 :]
|
||||
for file in glob.iglob(template + "/**/*." + self.extension, recursive=True):
|
||||
relative_file = file[len(template) + 1 :]
|
||||
if ntpath.basename(file)[:1] != "_":
|
||||
self.logger.debug(f"Found template file: {relative_file}")
|
||||
self.template_files.append(relative_file)
|
||||
@ -63,12 +63,12 @@ class Generator:
|
||||
|
||||
for file in self.template_files:
|
||||
doc_file = os.path.join(
|
||||
self.config.config.get("output_dir"), os.path.splitext(file)[0]
|
||||
self.config.config.get("renderer.dest"), os.path.splitext(file)[0]
|
||||
)
|
||||
if os.path.isfile(doc_file):
|
||||
files_to_overwite.append(doc_file)
|
||||
|
||||
header_file = self.config.config.get("custom_header")
|
||||
header_file = self.config.config.get("renderer.include_header")
|
||||
role_data = self._parser.get_data()
|
||||
header_content = ""
|
||||
if bool(header_file):
|
||||
@ -81,7 +81,7 @@ class Generator:
|
||||
|
||||
if (
|
||||
len(files_to_overwite) > 0
|
||||
and self.config.config.get("force_overwrite") is False
|
||||
and self.config.config.get("renderer.force_overwrite") is False
|
||||
and not self.config.config["dry_run"]
|
||||
):
|
||||
files_to_overwite_string = "\n".join(files_to_overwite)
|
||||
@ -98,11 +98,14 @@ class Generator:
|
||||
|
||||
for file in self.template_files:
|
||||
doc_file = os.path.join(
|
||||
self.config.config.get("output_dir"), os.path.splitext(file)[0]
|
||||
self.config.config.get("renderer.dest"), os.path.splitext(file)[0]
|
||||
)
|
||||
source_file = self.config.get_template() + "/" + file
|
||||
|
||||
self.logger.debug(f"Writing doc output to: {doc_file} from: {source_file}")
|
||||
self.logger.debug(
|
||||
f"Writing renderer output to: {os.path.relpath(doc_file, self.log.ctx)} "
|
||||
f"from: {os.path.dirname(os.path.relpath(source_file, self.log.ctx))}"
|
||||
)
|
||||
|
||||
# make sure the directory exists
|
||||
self._create_dir(os.path.dirname(doc_file))
|
||||
@ -123,9 +126,9 @@ class Generator:
|
||||
jenv.filters["safe_join"] = self._safe_join
|
||||
# keep the old name of the function to not break custom templates.
|
||||
jenv.filters["save_join"] = self._safe_join
|
||||
tabulate_vars = self.config.config.get("tabulate_variables")
|
||||
template_options = self.config.config.get("template.options")
|
||||
data = jenv.from_string(data).render(
|
||||
role_data, role=role_data, tabulate_vars=tabulate_vars
|
||||
role_data, role=role_data, options=template_options
|
||||
)
|
||||
if not self.config.config["dry_run"]:
|
||||
with open(doc_file, "wb") as outfile:
|
||||
@ -170,12 +173,12 @@ class Generator:
|
||||
|
||||
normalized = jinja2.filters.do_join(eval_ctx, value, d, attribute=None)
|
||||
|
||||
if self.config.config["template_autotrim"]:
|
||||
if self.config.config.renderer.autotrim:
|
||||
for s in [r" +(\n|\t| )", r"(\n|\t) +"]:
|
||||
normalized = re.sub(s, "\\1", normalized)
|
||||
|
||||
return jinja2.filters.do_mark_safe(normalized)
|
||||
|
||||
def render(self):
|
||||
self.logger.info(f"Using output dir: {self.config.config.get('output_dir')}")
|
||||
self.logger.info(f"Using renderer destination: {self.config.config.get('renderer.dest')}")
|
||||
self._write_doc()
|
||||
|
@ -21,7 +21,8 @@ class Registry:
|
||||
def __init__(self):
|
||||
self._doc = []
|
||||
self.config = SingleConfig()
|
||||
self.log = SingleLog().logger
|
||||
self.log = SingleLog()
|
||||
self.logger = self.log.logger
|
||||
self._scan_for_yamls()
|
||||
|
||||
def get_files(self):
|
||||
@ -35,19 +36,19 @@ class Registry:
|
||||
:return: None
|
||||
"""
|
||||
extensions = YAML_EXTENSIONS
|
||||
base_dir = self.config.base_dir
|
||||
role_name = os.path.basename(base_dir)
|
||||
base_dir = self.config.config.base_dir
|
||||
role_name = self.config.config.role_name
|
||||
excludes = self.config.config.get("exclude_files")
|
||||
excludespec = pathspec.PathSpec.from_lines("gitwildmatch", excludes)
|
||||
|
||||
self.log.debug(f"Scan for files: {base_dir}")
|
||||
self.logger.debug(f"Scan for files: {os.path.relpath(base_dir,self.log.ctx)}")
|
||||
|
||||
for extension in extensions:
|
||||
pattern = os.path.join(base_dir, "**/*." + extension)
|
||||
for filename in glob.iglob(pattern, recursive=True):
|
||||
if not excludespec.match_file(filename):
|
||||
self.log.debug(
|
||||
f"Adding file to '{role_name}': {os.path.relpath(filename, base_dir)}"
|
||||
f"Adding file to role '{role_name}': {os.path.relpath(filename, base_dir)}"
|
||||
)
|
||||
self._doc.append(filename)
|
||||
else:
|
||||
|
@ -2,7 +2,7 @@
|
||||
{% set var = role.var | default({}) %}
|
||||
{% if var %}
|
||||
- [Default Variables](#default-variables)
|
||||
{% if not tabulate_vars %}
|
||||
{% if not options.tabulate_vars %}
|
||||
{% for key, item in var | dictsort %}
|
||||
- [{{ key }}](#{{ key }})
|
||||
{% endfor %}
|
||||
|
@ -23,7 +23,7 @@ summary: {{ meta.summary.value | safe_join(" ") }}
|
||||
{% include '_requirements.j2' %}
|
||||
|
||||
{# Vars #}
|
||||
{% if tabulate_vars %}
|
||||
{% if options.tabulate_vars %}
|
||||
{% include '_vars_tabulated.j2' %}
|
||||
{% else %}
|
||||
{% include '_vars.j2' %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
{% include '_requirements.j2' %}
|
||||
|
||||
{# Vars #}
|
||||
{% if tabulate_vars %}
|
||||
{% if options.tabulate_vars %}
|
||||
{% include '_vars_tabulated.j2' %}
|
||||
{% else %}
|
||||
{% include '_vars.j2' %}
|
||||
|
@ -4,7 +4,7 @@
|
||||
{% set var = role.var | default({}) %}
|
||||
{% if var %}
|
||||
- [Default Variables](#default-variables)
|
||||
{% if not tabulate_vars %}
|
||||
{% if not options.tabulate_vars %}
|
||||
{% for key, item in var | dictsort %}
|
||||
- [{{ key }}](#{{ key }})
|
||||
{% endfor %}
|
||||
|
@ -145,13 +145,10 @@ class Log:
|
||||
"""Handle logging."""
|
||||
|
||||
def __init__(self, level=logging.WARNING, name="ansibledoctor", json=False):
|
||||
self.ctx = os.getcwd()
|
||||
self.logger = logging.getLogger(name)
|
||||
self.logger.setLevel(level)
|
||||
self.logger.addHandler(self._get_error_handler(json=json))
|
||||
self.logger.addHandler(self._get_warning_handler(json=json))
|
||||
self.logger.addHandler(self._get_info_handler(json=json))
|
||||
self.logger.addHandler(self._get_critical_handler(json=json))
|
||||
self.logger.addHandler(self._get_debug_handler(json=json))
|
||||
self.register_hanlers(json=json)
|
||||
self.logger.propagate = False
|
||||
|
||||
def _get_error_handler(self, json=False):
|
||||
@ -249,8 +246,24 @@ class Log:
|
||||
|
||||
return handler
|
||||
|
||||
def register_hanlers(self, json=False):
|
||||
"""
|
||||
Enable or disable JSON logging.
|
||||
|
||||
:param enable: True to enable JSON logging, False to disable
|
||||
"""
|
||||
# Remove all existing handlers
|
||||
for handler in self.logger.handlers[:]:
|
||||
self.logger.removeHandler(handler)
|
||||
|
||||
self.logger.addHandler(self._get_error_handler(json=json))
|
||||
self.logger.addHandler(self._get_warning_handler(json=json))
|
||||
self.logger.addHandler(self._get_info_handler(json=json))
|
||||
self.logger.addHandler(self._get_critical_handler(json=json))
|
||||
self.logger.addHandler(self._get_debug_handler(json=json))
|
||||
|
||||
def set_level(self, s):
|
||||
self.logger.setLevel(s)
|
||||
self.logger.setLevel(s.upper())
|
||||
|
||||
def debug(self, msg):
|
||||
"""Format info messages and return string."""
|
||||
|
@ -20,40 +20,17 @@ Configuration options can be set in different places, which are processed in the
|
||||
---
|
||||
# Default is the current working directory.
|
||||
base_dir:
|
||||
|
||||
role:
|
||||
# Default is the basename of 'role_name'.
|
||||
role_name:
|
||||
name:
|
||||
# Auto-detect if the given directory is a role, can be disabled
|
||||
# to parse loose files instead.
|
||||
role_detection: True
|
||||
# Don't write anything to file system
|
||||
autodetect: True
|
||||
|
||||
# Don't write anything to file system.
|
||||
dry_run: False
|
||||
|
||||
logging:
|
||||
# Possible options debug | info | warning | error | critical
|
||||
level: "warning"
|
||||
# Json logging can be enabled if a parsable output is required
|
||||
json: False
|
||||
|
||||
# Path to write rendered template file. Default is the current working directory.
|
||||
output_dir:
|
||||
# Default is built-in templates directory.
|
||||
template_dir:
|
||||
template: readme
|
||||
# By default, double spaces, spaces before and after line breaks or tab characters, etc.
|
||||
# are automatically removed before the template is rendered. As a result, indenting
|
||||
# with spaces does not work. If you want to use spaces to indent text, you must disable
|
||||
# this option.
|
||||
template_autotrim: True
|
||||
# Configures whether to tabulate variables in the output. When set to `True`,
|
||||
# variables will be displayed in a tabular format intsead of plain marktdown sections.
|
||||
# NOTE: This option does not support rendering multiline code blocks.
|
||||
tabulate_variables: False
|
||||
|
||||
# Don't ask to overwrite if output file exists.
|
||||
force_overwrite: False
|
||||
# Load custom header from given file and append template output to it before write.
|
||||
custom_header: ""
|
||||
|
||||
exclude_files: []
|
||||
# Examples
|
||||
# exclude_files:
|
||||
@ -63,6 +40,36 @@ exclude_files: []
|
||||
# Exclude tags from automatic detection. Configured tags are only skipped
|
||||
# if the tag is not used in an annotation.
|
||||
exclude_tags: []
|
||||
|
||||
logging:
|
||||
# Possible options: debug|info|warning| error|critical
|
||||
level: "warning"
|
||||
# JSON logging can be enabled if a parsable output is required.
|
||||
json: False
|
||||
|
||||
template:
|
||||
name: readme
|
||||
# Default is built-in templates directory.
|
||||
src:
|
||||
|
||||
options:
|
||||
# Configures whether to tabulate variables in the output. When set to `True`,
|
||||
# variables will be displayed in a tabular format intsead of plain marktdown sections.
|
||||
# NOTE: This option does not support rendering multiline code blocks.
|
||||
tabulate_vars: False
|
||||
|
||||
renderer:
|
||||
# By default, double spaces, spaces before and after line breaks or tab characters, etc.
|
||||
# are automatically removed before the template is rendered. As a result, indenting
|
||||
# with spaces does not work. If you want to use spaces to indent text, you must disable
|
||||
# this option.
|
||||
autotrim: True
|
||||
# Load custom header from given file and append template output to it before write.
|
||||
include_header: ""
|
||||
# Path to write rendered template file. Default is the current working directory.
|
||||
dest:
|
||||
# Don't ask to overwrite if output file exists.
|
||||
force_overwrite: False
|
||||
```
|
||||
|
||||
## CLI
|
||||
@ -95,23 +102,25 @@ options:
|
||||
## Environment Variables
|
||||
|
||||
```Shell
|
||||
ANSIBLE_DOCTOR_CONFIG_FILE=
|
||||
ANSIBLE_DOCTOR_ROLE_DETECTION=true
|
||||
ANSIBLE_DOCTOR_BASE_DIR=
|
||||
ANSIBLE_DOCTOR_RECURSIVE=false
|
||||
ANSIBLE_DOCTOR_ROLE_NAME=
|
||||
ANSIBLE_DOCTOR_DRY_RUN=false
|
||||
ANSIBLE_DOCTOR_LOG_LEVEL=warning
|
||||
ANSIBLE_DOCTOR_LOG_JSON=false
|
||||
ANSIBLE_DOCTOR_OUTPUT_DIR=
|
||||
ANSIBLE_DOCTOR_TEMPLATE_DIR=
|
||||
ANSIBLE_DOCTOR_TEMPLATE=readme
|
||||
ANSIBLE_DOCTOR_TEMPLATE_AUTOTRIM=true
|
||||
ANSIBLE_DOCTOR_TABULATE_VARIABLES=false
|
||||
ANSIBLE_DOCTOR_FORCE_OVERWRITE=false
|
||||
ANSIBLE_DOCTOR_CUSTOM_HEADER=
|
||||
ANSIBLE_DOCTOR_DRY_RUN=False
|
||||
ANSIBLE_DOCTOR_EXCLUDE_FILES=
|
||||
ANSIBLE_DOCTOR_EXCLUDE_FILES=molecule/,files/**/*.py
|
||||
ANSIBLE_DOCTOR_EXCLUDE_TAGS=
|
||||
|
||||
ANSIBLE_DOCTOR_ROLE__NAME=
|
||||
ANSIBLE_DOCTOR_ROLE__AUTODETECT=True
|
||||
|
||||
ANSIBLE_DOCTOR_LOGGING__LEVEL="warning"
|
||||
ANSIBLE_DOCTOR_LOGGING__JSON=False
|
||||
|
||||
ANSIBLE_DOCTOR_TEMPLATE__NAME=readme
|
||||
ANSIBLE_DOCTOR_TEMPLATE__SRC=
|
||||
ANSIBLE_DOCTOR_TEMPLATE__OPTIONS__TABULATE_VARS=False
|
||||
|
||||
ANSIBLE_DOCTOR_RENDERER__AUTOTRIM=True
|
||||
ANSIBLE_DOCTOR_RENDERER__INCLUDE_HEADER=
|
||||
ANSIBLE_DOCTOR_RENDERER__DEST=
|
||||
ANSIBLE_DOCTOR_RENDERER__FORCE_OVERWRITE=False
|
||||
```
|
||||
|
||||
## Pre-Commit setup
|
||||
|
@ -1,5 +1,9 @@
|
||||
---
|
||||
custom_header: HEADER.md
|
||||
logging:
|
||||
level: debug
|
||||
template: readme
|
||||
|
||||
template:
|
||||
name: readme
|
||||
|
||||
renderer:
|
||||
include_header: HEADER.md
|
||||
|
@ -1,5 +1,9 @@
|
||||
---
|
||||
custom_header: HEADER.md
|
||||
logging:
|
||||
level: debug
|
||||
template: readme
|
||||
|
||||
template:
|
||||
name: readme
|
||||
|
||||
renderer:
|
||||
include_header: HEADER.md
|
||||
|
161
poetry.lock
generated
161
poetry.lock
generated
@ -209,43 +209,43 @@ toml = ["tomli"]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "42.0.7"
|
||||
version = "42.0.8"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"},
|
||||
{file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"},
|
||||
{file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"},
|
||||
{file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"},
|
||||
{file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"},
|
||||
{file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"},
|
||||
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -261,6 +261,27 @@ ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "dynaconf"
|
||||
version = "3.2.5"
|
||||
description = "The dynamic configurator for your Python Project"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "dynaconf-3.2.5-py2.py3-none-any.whl", hash = "sha256:12202fc26546851c05d4194c80bee00197e7c2febcb026e502b0863be9cbbdd8"},
|
||||
{file = "dynaconf-3.2.5.tar.gz", hash = "sha256:42c8d936b32332c4b84e4d4df6dd1626b6ef59c5a94eb60c10cd3c59d6b882f2"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
all = ["configobj", "hvac", "redis", "ruamel.yaml"]
|
||||
configobj = ["configobj"]
|
||||
ini = ["configobj"]
|
||||
redis = ["redis"]
|
||||
test = ["configobj", "django", "flask (>=0.12)", "hvac (>=1.1.0)", "pytest", "pytest-cov", "pytest-mock", "pytest-xdist", "python-dotenv", "radon", "redis", "toml"]
|
||||
toml = ["toml"]
|
||||
vault = ["hvac"]
|
||||
yaml = ["ruamel.yaml"]
|
||||
|
||||
[[package]]
|
||||
name = "environs"
|
||||
version = "11.0.0"
|
||||
@ -637,14 +658,24 @@ cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-json-logger"
|
||||
version = "2.0.7"
|
||||
description = "A python library adding a json log formatter"
|
||||
version = "3.1.0"
|
||||
description = "JSON Log Formatter for the Python Logging Package"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"},
|
||||
{file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"},
|
||||
]
|
||||
python-versions = ">=3.8"
|
||||
files = []
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = "*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["backports.zoneinfo", "black", "build", "freezegun", "mdx-truly-sane-lists", "mike", "mkdocs", "mkdocs-awesome-pages-plugin", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-material (>=8.5)", "mkdocstrings[python]", "msgspec", "mypy", "orjson", "pylint", "pytest", "tzdata", "validate-pyproject[all]"]
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "https://github.com/nhairs/python-json-logger.git"
|
||||
reference = "v3.1.0"
|
||||
resolved_reference = "e2b40e420f4181fd921b01a2fd0b23ca82b5fc9b"
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
@ -658,7 +689,6 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
||||
@ -666,16 +696,8 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
||||
@ -692,7 +714,6 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
||||
@ -700,7 +721,6 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
@ -891,51 +911,37 @@ python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"},
|
||||
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"},
|
||||
{file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"},
|
||||
@ -989,10 +995,21 @@ files = [
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.12.1"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"},
|
||||
{file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"},
|
||||
]
|
||||
|
||||
[extras]
|
||||
ansible-core = ["ansible-core"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9.0"
|
||||
content-hash = "fe371a30a9ad68f7aea83715fa476b69156254aa79658db529990a692f4df89d"
|
||||
content-hash = "7836ddcc834dcd41e84f8f4fbf583495bad4c72e8e831d68af607f5e4df79f0e"
|
||||
|
@ -39,8 +39,9 @@ environs = "11.0.0"
|
||||
jsonschema = "4.22.0"
|
||||
pathspec = "0.12.1"
|
||||
python = "^3.9.0"
|
||||
python-json-logger = "2.0.7"
|
||||
python-json-logger = { git = "https://github.com/nhairs/python-json-logger.git", tag = "v3.1.0" }
|
||||
"ruamel.yaml" = "0.18.6"
|
||||
dynaconf = "3.2.5"
|
||||
ansible-core = { version = "2.14.17", optional = true }
|
||||
|
||||
[tool.poetry.extras]
|
||||
|
Loading…
Reference in New Issue
Block a user