Skip to main content

Type safe environment variables

Project description

pysafe-config

pysafe-config is a lightweight Python package designed to simplify and secure the process of reading environment variables. It provides a set of functions for each of the common types used for environment variables to reduce boilerplate code, enforce type safety, and handle missing variables gracefully, making application config more robust and easier to manage.

The Problem: Boilerplate and Error-Prone Environment Variable Handling

Without pysafe-config, handling environment variables often involves repetitive and error-prone code, especially when dealing with type conversions and mandatory checks. Consider the common scenario of retrieving a SAMPLING_RATIO as a float:

import os
SAMPLING_RATIO = os.getenv("SAMPLING_RATIO", None)

if SAMPLING_RATIO is None:
    raise RuntimeError("SAMPLING_RATIO is unset")
else:
    SAMPLING_RATIO = float(SAMPLING_RATIO)

This approach is verbose, susceptible to ValueError if the conversion fails, and requires explicit checks for None.

The Solution: pysafe-config

pysafe-config streamlines this process, allowing you to retrieve and validate environment variables with minimal code. The previous example can be reduced to a single, clear line:

from pysafe_config import getenv_float_strict

SAMPLING_RATIO: float = getenv_float_strict("SAMPLING_RATIO")

Features and Benefits

  • Reduced Boilerplate: Significantly cuts down the amount of code needed to read and validate environment variables.
  • Type Safety: Automatically converts environment variable strings to the desired Python types (bool, int, float, str) and raises TypeError if conversion fails. If using the strict version of a getenv function, the return type is guaranteed and will allow mypy to recognise the variable as the correct type.
  • Strict Mode: Functions like getenv_float_strict ensure that a RuntimeError is raised if a mandatory environment variable is not set, preventing silent failures.
  • Flexible Handling: Provides both strict and non-strict versions of functions. Non-strict versions (getenv_bool, getenv_float, etc.) allow you to specify a default value and control whether a variable is required.
  • Clear Error Messages: Provides descriptive error messages for missing or invalid environment variables, aiding in quicker debugging.
  • Consistent Validation: Enforces strict validation rules for different types (e.g., specific formats for floats and integers, a predefined set of true/false strings for booleans).

Installation

poetry

poetry add pysafe-config

pip

pip install pysafe-config

Usage

Getting Started

Import the required function from pysafe_config. Public functions can be imported like so:

from pysafe_config import (
    getenv_bool,
    getenv_float,
    getenv_int,
    getenv_str,
    getenv_bool_strict,
    getenv_float_strict,
    getenv_int_strict,
    getenv_str_strict,
)

Strict Retrieval (Recommended for Mandatory Variables)

Use the _strict functions when an environment variable must be present and correctly typed. These functions will raise a RuntimeError if the variable is missing or a ValueError if the type conversion fails.

# Mandatory float environment variable
DATABASE_TIMEOUT: float = getenv_float_strict("DATABASE_TIMEOUT")

# Mandatory boolean environment variable
FEATURE_FLAG_ENABLED: bool = getenv_bool_strict("FEATURE_FLAG_ENABLED")

# Mandatory integer environment variable
WORKER_COUNT: int = getenv_int_strict("WORKER_COUNT")

# Mandatory string environment variable
API_KEY: str = getenv_str_strict("API_KEY")

Flexible Retrieval (with Defaults and Optionality)

Use the non-strict functions when an environment variable is optional or has a sensible default value. You can specify required=False and provide a default value if the variable cannot be found in the environment.

# Optional string with a default value
LOG_LEVEL: str | None = getenv_str("LOG_LEVEL", default="INFO")

# Optional integer, defaults to None if not set
MAX_RETRIES: int | None = getenv_int("MAX_RETRIES")

# Required boolean with no default (will raise RuntimeError if variable is unset in environment)
DEBUG_MODE: bool | None = getenv_bool("DEBUG_MODE", required=True)

# Required boolean with default value specified (will raise RuntimeError if variable is unset in environment)
RETURN_UPSTREAM_ERRORS: bool | None = getenv_bool("DEBUG_MODE", default=True, required=True)

Supported Boolean Values

pysafe-config provides robust parsing for boolean environment variables. The following case-insensitive values are recognised:

True values False values
"true" "false"
"1" "0"
"yes" "no"
"y" "n"
"on" "off"
"enable" "disable"
"enabled" "disabled"
"t" "f"

Supported Float Values

Float values must adhere to a strict format:

  • Contain only digits (0-9), optionally preceded by a single + or - sign.
  • Include exactly one decimal point to separate the whole and fractional parts.
  • Not contain any whitespace, commas, or alphabetic characters.
Valid strings Invalid strings
"50.2" "50"
"-0.0" "5.5.5"
"+1000.5" " 12.3"
"-99.0" "12,3"
"0.0001" "ten"
"+.5" "5."
"-1.23" "" (empty)

Supported Integer Values

Integer values must adhere to a strict format:

  • Contain only digits (0-9), optionally preceded by a single + or - sign.
  • Not contain any whitespace.
  • Not include decimal points, letters, or special symbols.
Valid strings Invalid strings
"100" " 100"
"1" "10.5"
"-50" "1,000"
"+1000" "12a"
"0" "++5"
"-0" "5-"
"123456" "ten"
"-123456" "" (empty)

Contributing

Contributions are welcome! Please refer to the CONTRIBUTING.md for guidelines.

License

This project is licensed under the MIT License.

Release docs

TODO: add steps on how to release here

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysafe_config-0.0.0.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysafe_config-0.0.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file pysafe_config-0.0.0.tar.gz.

File metadata

  • Download URL: pysafe_config-0.0.0.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pysafe_config-0.0.0.tar.gz
Algorithm Hash digest
SHA256 aa1283a055f0f92a5481c184c3d398737833cfdabd28121d7caeceda35c43d0c
MD5 de302838e14a24ec3e60dfea8e4ef623
BLAKE2b-256 3e7044220f4652059789b5aa4778b7b80c41cd94667bb204a8414b7076a5dda4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysafe_config-0.0.0.tar.gz:

Publisher: python-publish.yml on Lancasterg/pysafe-config

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pysafe_config-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: pysafe_config-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pysafe_config-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 01351871cc922af87f21c5bb2211880b6ad2d2c721c6ee362c6ed50cc4518ac9
MD5 6acce75e50d100e0a58f8d814ef75894
BLAKE2b-256 18e1813c68317da7a5550a2f2dd0fec1b43e0879c28357c16c03fbd0c85d450a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysafe_config-0.0.0-py3-none-any.whl:

Publisher: python-publish.yml on Lancasterg/pysafe-config

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page