All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- A new expression for injecting values imported from/via Python like so
${__PY__:alviss.__version__}
- This uses the
ccptools.tpu.strimp.get_any(...)
to import whatever the expression key points to and inject into the parsed config - The use case here is mainly to inject dynamic Python values into Alviss
files "on-demand" like when using ccp-stencil
templates in a CI/CD pipe so you can have the ever-changing version of the
package you're working on injected automatically into the Alviss config file
used as Context for rendering Docker files, Kube manifests and so on
(similar to how it can be done in
pyproject.toml
) - This expression also adheres to the normal format of "defaults" (e.g.
${__PY__:alviss.__version__=Unknown}
) and "required" (e.g.${__PY__:alviss.__version__!=}
)
- This uses the
- Stubber CLI was ignoring the class name when using the
-o
output flag
- Stubber now has an option to only "export" the resulting "Final" stub class and keeping all the other stubs "private" and this option is True by default (they don't really need to be public)
- You can now give the resulting "Final" config stub a custom name
- You can also give the "Final" config stub an empty string for a name which will simply omit generating it (for custom/complex composition of stubs later on if people want)
- All stubs now also inherit from
dict
because any attribute inBaseConfig
that's a Map (and thus has a stub class) will also behave as adict
(even ifEmpty
)
- Stubber now appends an underscore to stubs with Python reserved keywords
like
class
anddef
etc. - The
BaseConfig
object now also spots attribute fetching of those keywords with an appended underscore and fetches the correct attribute nevertheless.
- Stub generators from descriptor config files where you structure out your config file and give each value the Python type you expect the config to yield in order to generate type-hinting stub-classes that match the structure of your config file(s).
- CLI commands for running the stub generation:
alviss-stubber
- CLI commands for running the config rendering:
alviss-render
- A bunch of Alviss specific Error Exceptions that are raised e.g. when files aren't found or when Fidelius is required but isn't installed
- The rendering of static single file configs from Alviss config files and expressions has now been moved into its own sub-module with a standard API
- A way to make evaluating environment variables require a value to be found by
appending
!=
to the end of the expression like so${__ENV__:API_KEY!=}
. Missing values will trigger aValueError
raised when loading config files.
- Fidelius mode - Alviss now reads the
ALVISS_FIDELIUS_MODE
environment variable to determine one of these Fidelius modes available:ON_DEMAND
(default): Fidelius is only ever loaded (i.e. an import is attempted) if fidelius expressions (__FID__
) are encountered when reading a configENABLED
: Alviss tries to import fidelius on startup and raises anImportError
if it failsDISABLED
: All fidelius expressions (__FID__
) are simply ignored and left unparsedSUBSTITUTE_ENV
: All fidelius expressions (__FID__
) are treated as if they are environment variable expressions (__ENV__
)MOCK
: Fidelius will be initialised using its mock implementation, which uses a singleton in-memory datastore, making this useful for testing
- Error reporting on the keys that have Fidelius tags in them in case of a Fidelius related error (like access problems or if fidelius is not installed)
- Fidelius can now grab config values from the config files Alviss is
reading via the
__fidelius__
special key (e.g.ALVISS_FIDELIUS_MODE
and anykwargs
thatAwsParamStoreRepo
takes.
- Migrated the project from our internal repos to Github and Pypi
- Alviss now ships by default without fidelius
support and runs in
ALVISS_FIDELIUS_MODE=ON_DEMAND
and this only tries to import fidelius if a__FID__
expression is encountered- Installing Alviss with built in fidelius support can still be done via
pip install alviss[fidelius]
plus all theboto3
stuff and such
- Installing Alviss with built in fidelius support can still be done via
- Bumped the
fidelius
version to 1.0.0 so now all the new environment variables available in that version can be used to configure fidelius in Alviss, e.g. by settingFIDELIUS_AWS_ENDPOINT_URL
to point to a LocalStack container for testing and/or development.
- An issue where the default values of environment variables could not contain any whitespaces (like a simple space)
- Issue where Fidelius expressions were being evaluated by default when calling
render_load
- Automatic parsing of Fidelius expressions
{$__FID__:...}
- Environment variable injection tags can now have a default value that they
get assigned if the environment variable in question was not found
- E.g.
app_version: ${__ENV__:APP_VERSION=0.0.0}
whereapp_version
will be0.0.0
ifAPP_VERSION
is not found on the system as an environment variable)
- E.g.
- A rare but serious error where nested internal referencing with multiple variables would break prematurely in files that extend others with the same keys
- The
raw_load
method that loads a config file and returns the rawdict
result- This is mainly intended to be used for debugging large and complex sets of config files with multiple inclusions and extensions and internal references and such, so that reading in the files and seeing the resulting structure after everything has been included and evaluated can help.
- The
render_load
method that loads a config file and returns the renderedstr
result (JSON or YAML depending on the input file)- This is mainly intended to be used for debugging large and complex sets of config files with multiple inclusions and extensions and internal references and such, so that reading in the files and seeing the resulting JSON or YAML after everything has been included and evaluated can help, as if this was just one large file with static values.
- The
unmaksed
param (default=False
) to theas_json
,as_yaml
andas_dict
methods in order to usealviss
to load and render config and export as a single "compiled" file e.g. for deployment manifests and such
- Issue with resolution order of extended keys with variables
- Issue with resolving variables in entries with nested keys collapsed into one string
- Support for multiple files in
__extends__
keys - Support for nested
__extends__
keys - Support for using
__extends__
and__include__
in collapsed keys - Aliases:
__extend__
=>__extends__
__includes__
=>__include__
- YAML support (YAY! Now we can properly document/comment in config files!)
- New
quickloader
module - Support for extending base files via
__extends__
key - Support for including additional files via
__include__
key - Better config representation (e.g. for logs) via
as_json()
andas_yaml()
methods - Internal reference variable resolving via
${keys}
- Support for collapsing multiple nested keys into a single key with dots
like so:
database.connection.host
- Support for documentation keys in JSON files via the "comment-like"
__doc__
key - Way to "comment-out" any keys in JSON by ignoring any keys starting with a double underscore.
- Support for including environment variables into any value string, wherever in that string
- The format for environment variable inclusion to
${__ENV__:SOME_ENV_VAR}
- Refactored structure (just
from alviss.quickloader import *
and go)
- The singleton functionality of
BaseConfig
by default and moved it over toSingletonConfig
- The CI/CD pipelines
- If something in config starts with "_", it's no longer printed
- Requirements and version bump due to bug in dependency
- A bug from
typeutils.iters.nested_dict_update
that didn't update the nested parts of nestedEmptyDict
- The
update
to usenested_dict_update
fromtypeutils
2.5+ so config value updates can be updated safely in a nested way e.g. in order to have a base config file and then a much smaller override config file - The
__str__
and__repr__
and calls so they now mask out secrets and passwords (any keys with the following words in them: 'pass', 'key', 'secret', 'token')
Initial release
- Everything!