Skip to main content

Roskarl

Is a tiny module for environment variables

Requires

Python 3.11.0+

How to install

uv pip install roskarl

Example usage

from roskarl import (
    env_var,
    env_var_bool,
    env_var_cron,
    env_var_custom,
    env_var_duration,
    env_var_enum,
    env_var_interval_expression,
    env_var_interval_expression_extended,
    env_var_float,
    env_var_int,
    env_var_iso8601_datetime,
    env_var_list,
    env_var_log_level,
    env_var_path,
    env_var_rfc3339_datetime,
    env_var_secret,
    env_var_tz,
    env_var_url,
    env_var_dsn,
    DSN,
    Secret,
)

All functions return None if the variable is not set. An optional default parameter can be provided to return a fallback value instead.

Pass required=True to raise instead of returning None — type checkers will narrow the return type accordingly (e.g. str instead of str | None), so no assert is needed at callsites

str (returns str)

value = env_var(name="STR_VAR", default="fallback")

bool (returns bool — accepts true or false (case insensitive))

value = env_var_bool(name="BOOL_VAR")

tz (returns str if value is a valid IANA timezone (e.g. Europe/Stockholm))

value = env_var_tz(name="TZ_VAR")

list (returns list[str] if value is splittable by separator)

value = env_var_list(name="LIST_VAR", separator="|")

int (returns int if value is numeric)

value = env_var_int(name="INT_VAR")

float (returns float if value is a float)

value = env_var_float(name="FLOAT_VAR")

cron (returns str if value is a valid cron expression)

value = env_var_cron(name="CRON_VAR")

interval expression (returns str if value is a valid offset-free 5-field cron expression)

value = env_var_interval_expression(name="INTERVAL_VAR")

interval expression extended (returns str if value is a valid offset-free 6-field cron expression)

value = env_var_interval_expression_extended(name="INTERVAL_EXTENDED_VAR")

datetime (ISO8601) (returns datetime if value is a valid ISO8601 datetime string — timezone is optional)

value = env_var_iso8601_datetime(name="DATETIME_VAR")

datetime (RFC3339) (returns datetime if value is a valid RFC3339 datetime string — timezone is required)

value = env_var_rfc3339_datetime(name="DATETIME_VAR")

url (returns str if value has a scheme + netloc, e.g. https://example.com)

value = env_var_url(name="API_URL")

secret (returns Secret — wraps the value so it can't accidentally be logged)

repr() and str() return ***. Call .reveal() at the point of use.

key = env_var_secret(name="API_KEY", required=True)
print(key)            # ***
stripe.api_key = key.reveal()

path (returns pathlib.Path)

Pass must_exist=True to fail fast if the path is not present on disk

value = env_var_path(name="CONFIG_PATH", must_exist=True)

enum (returns an instance of your Enum subclass)

Matches against each member's .value. Raises ValueError if no match

from enum import Enum
class Mode(Enum):
    LIVE = "live"
    DRY_RUN = "dry-run"

value = env_var_enum(name="MODE", enum_class=Mode, required=True)

duration (returns timedelta)

Parses compound duration strings using suffixes ms, s, m, h, d. Spaces between parts are tolerated.

value = env_var_duration(name="REQUEST_TIMEOUT", default=timedelta(seconds=30))
# accepts: "30s", "5m", "1h30m", "500ms", "7d", "1h 30m"

log level (returns int matching Python's logging levels)

Accepts DEBUG, INFO, WARNING/WARN, ERROR, CRITICAL/FATAL (case-insensitive).

import logging
level = env_var_log_level(name="LOG_LEVEL", default=logging.INFO)
logging.basicConfig(level=level)

custom (returns whatever your parser returns)

Escape hatch for types without a dedicated helper — pass any Callable[[str], T].

from uuid import UUID
value = env_var_custom(name="UUID_VAR", parser=UUID, required=True)  # type: UUID

DSN

Note: Special characters in passwords must be URL-encoded.

from urllib.parse import quote
password = 'My$ecret!Pass@2024'
encoded = quote(password, safe='')
print(encoded)  # My%24ecret%21Pass%402024 <--- use this
value = env_var_dsn(name="DSN_VAR")

returns DSN object if value is a valid DSN string, formatted as:

postgresql://username:password@hostname:5432/database_name

The DSN object exposes the following attributes:

Attribute Type Example
scheme str postgresql
host str hostname
port int 5432
username str username
password str password
database str database_name

Testing

Tests use pytest. Run the full suite:

pytest tests/

Release

See RELEASE.md for instructions on how to publish a new version.

Metadata

Release files for roskarl 3.1.31

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for roskarl 3.1.31
File Size Uploaded Provenance Actions
roskarl-3.1.31.tar.gz 18.3 kB Without provenance Details for roskarl-3.1.31.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for roskarl 3.1.31
File Interpreter ABI Platform Actions
roskarl-3.1.31-py3-none-any.whl Python 3 none any Details for roskarl-3.1.31-py3-none-any.whl

Total release size: 30.0 kB

Release files / roskarl-3.1.31.tar.gz

Download URL roskarl-3.1.31.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
66bb50cc2ada56e6646d980aab0564fba41ac8eec1786be7131e6622d63821aa
BLAKE2b-256 checksum
How to use checksums
260b7659a8650265559f6207a5650a9eaee20fd6941f7f18cc1ab2584feb4e59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / roskarl-3.1.31-py3-none-any.whl

Download URL roskarl-3.1.31-py3-none-any.whl
Size 11.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3338b99a48fef2ec9a3f50a2082b197d0a16c99e001ed29cd157d9087acf96b1
BLAKE2b-256 checksum
How to use checksums
56627a670472d690fb530dc0c42b2a52f042db52b278cefb511b04119a9bf369
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for roskarl 3.1.31

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

3.1.31 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page