Package: typenv
typenvVersion 0.2.0Typed environment variable parsing for PythonTable of Contentsgenerated withmdformat-tocBackgroundInstallingUsageBasicsSupported typesDefault valuesName prefixesName character setName uppercasingValidationReading from a.envfileDumping parsed valuesAcknowledgmentsBackgroundTypenv does environment variable parsing with an API almost identical to the excellentenvirons.
There are a few reasons why typenv might be preferred:Type annotated typecast functions: type checkers are able to understand types of parsed environment variables.More flexible prefix manipulation of environment variable names.Validation of environment variable names.Optional automatic uppercasing of environment variable names.Ability to generate a .env.example that shows expected types of environment variables.Less dependencies. Nomarshmallowrequired.InstallingInstalling from PyPI repository (https://pypi.org/project/typenv):pipinstalltypenvUsageBasicsSet environment variables:exportNAME='Harry Potter'exportAGE=14exportIS_WIZARD=trueexportPATRONUM_SUCCESS_RATE=0.92exportBANK_BALANCE=134599.01exportLUCKY_NUMBERS=7,3,11exportEXTRA_DETAILS='{"friends": ["Hermione", "Ron"]}'exportFAVORITE_COLOR=0x7f0909Parse the values in Python:fromtypenvimportEnvenv=Env()NAME=env.str("NAME")# => "Harry Potter"AGE=env.int("AGE")# => 14IS_WIZARD=env.bool("IS_WIZARD")# => TruePATRONUM_SUCCESS_RATE=env.float("PATRONUM_SUCCESS_RATE")# => 0.92BANK_BALANCE=env.decimal("BANK_BALANCE")# => decimal.Decimal("134599.01")LUCKY_NUMBERS=env.list("LUCKY_NUMBERS",subcast=int)# => [7, 3, 11]EXTRA_DETAILS=env.json("EXTRA_DETAILS")# => {"friends": ["Hermione", "Ron"]}FAVORITE_COLOR=env.bytes("FAVORITE_COLOR",encoding="hex")# => b"\x7f\t\t"# Optional settings must have a default valueIS_DEATH_EATER=env.bool("IS_DEATH_EATER",default=False)# => FalseSupported typesThe types supported by typenv are:env.strenv.intenv.boolenv.floatenv.decimalenv.listTakes asubcastkeyword argument for casting list items to one ofstr,int,bool,floatordecimal.Decimalenv.jsonenv.bytesTakes anencodingkeyword argument for indicating how the bytes are encoded.
For now onlyhexis supported.Default valuesNormally, if an environment variable is not found, typenv raises an exception.
If a default value is provided, however, that will be returned instead of raising.fromtypenvimportEnvenv=Env()BOOL=env.bool("NON_EXISTING_NAME",default=False)# => FalseLIST=env.list("NON_EXISTING_NAME",default=["a","b"])# => ["a", "b"]OPTIONAL_INT=env.int("NON_EXISTING_NAME",default=None)# => NoneName prefixesexportFLASK_HOST=127.0.0.1exportFLASK_PORT=44144fromtypenvimportEnvenv=Env()# Explicitly prefixing variable names works, but repeats itself# (especially given more environment variables and nested prefixes).HOST=env.str("FLASK_HOST")# => "127.0.0.1"PORT=env.int("FLASK_PORT")# => 44144# This reads the same variables as above, and can be a nice way of# reducing repetition and expressing structure. Note that it is possible# to have nested `with` statements.withenv.prefixed("FLASK_"):HOST=env.str("HOST")# => "127.0.0.1"PORT=env.int("PORT")# => 44144# For more control, one can mutate `env.prefix` (of type list[str])# directly. Note that if an exception occurs reading the environment# variables, then `env.prefix` will not be reset to its initial value,# which is something that the `with` statement would take care of.env.prefix.append("FLASK_")HOST=env.str("HOST")# => "127.0.0.1"PORT=env.int("PORT")# => 44144env.prefix.pop()Name character setTypenv validates environment variable names.
By default, the set of allowed characters includes upper case ASCII letters, digits and the underscore (_).The set of allowed characters can be configured:fromtypenvimportEnvenv=Env(allowed_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ")Name uppercasingexportUPPER_CASE_NAME=truefromtypenvimportEnv# Environment variable names in type cast methods will automatically be upper# cased when `upper=True` is set here.env=Env(upper=True)NAME=env.bool("upper_casE_Name")ValidationexportNAME='Harry Potter'exportAGE=14fromtypenvimportEnvenv=Env()# A single validator functionNAME=env.str("NAME",validate=lambdan:n.startswith("Harry"))# A validator function can signal error by raising an exceptiondefis_positive(num):ifnum<=0:raiseException("Number is not positive")# A validator function can alternatively return `False` to signal an errordefis_less_than_thousand(num):ifnum>=1000:returnFalsereturnTrue# Multiple validator functions can be passed as an iterable of callablesAGE=env.int("AGE",validate=(is_positive,is_less_than_thousand))Reading from a.envfileWhile developing, it is often useful to read environment variables from a file.
Typenv supports this via theEnv.read_end()method.
The method will look for a file (by default) named.envin current working directory
and import environment variables from it.
If a file is not found,
the method will walk up in the directory tree until a file is found or the root directory is reached.
The method returns a boolean that isTrueif a file is found.Given a.envfile in current working directory with the following contentSOME_VAR='some value'The following code will be able to read and parse the valuefromtypenvimportEnvenv=Env()env.read_env()SOME_VAR=env.str("SOME_VAR")# => "some value"Dumping parsed valuesexportSOME_STR=blaablaaexportSOME_INT=99fromtypenvimportEnv,ParsedValueenv=Env()SOME_STR=env.str("SOME_STR")SOME_INT=env.int("SOME_INT")assertenv.dump()=={"SOME_INT":ParsedValue(value=99,type="int",optional=False),"SOME_STR":ParsedValue(value="blaablaa",type="str",optional=False),}AcknowledgmentsThe public API of this library is almost an exact copy ofenvirons,
which is based onenvparseanddjango-environ.
Credit for the interface goes to the authors of those libraries.