Skip to content

Easy Config

py_simple.easy_config

easy_config aims to simplify creating configuration files.

EasyConfigError

Bases: Exception

Raised when a config file could not be written. This wraps the underlying error (missing template, permission denied, no git repository found) so callers only have to catch one exception type instead of several. Args: message (str): Description of what went wrong.

create_env_file(variables, file_path='.env', overwrite=False)

Creates a .env configuration file with the provided key-value pairs.

Writes variables in 'KEY=VALUE' format. If the file already exists and overwrite is False, the file is left alone. Any missing parent directories are created automatically.

Parameters:

Name Type Description Default
variables dict[str, str]

Dictionary of configuration keys and their string values to store in the file.

required
file_path str

Destination path for the .env file. Defaults to ".env".

'.env'
overwrite bool

Whether to overwrite an existing file. Defaults to False.

False

Returns:

Type Description
None

None

Raises:

Type Description
EasyConfigError

If the file or parent directory cannot be written.

Example
from py_simple import create_env_file

config = {"PORT": "8000", "DEBUG": "True"}
create_env_file(config)
import os

config = {"PORT": "8000", "DEBUG": "True"}
if not os.path.exists(".env"):
    parent_dir = os.path.dirname(".env")
    if parent_dir:
        os.makedirs(parent_dir, exist_ok=True)
    with open(".env", "w", encoding="utf-8") as f:
        for key, value in config.items():
            f.write(f"{key}={value}{os.linesep}")

dockerfile_config(at_root=True)

Creates a starter Dockerfile for a Python project from a template.

The generated Dockerfile is a starting point, not a finished build. The template assumes the project has a requirements.txt and a main.py (COPY requirements.txt ., CMD ["python", "main.py"]), so expect to adjust it for your own entry point, dependency manager, base image and ignore rules before shipping.

The Dockerfile is written to 'Dockerfile'. If the file already exists, it is left alone. Any missing parent directories are created automatically.

Parameters:

Name Type Description Default
at_root bool

When True, the path is relative to the current working directory. When False, the git repository root is looked up and the Dockerfile is placed there. Defaults to True.

True

Returns:

Type Description
None

None

Raises:

Type Description
EasyConfigError

If the template cannot be read, the git repository cannot be found, or the file cannot be written.

Example
from py_simple import dockerfile_config

dockerfile_config()
template = """FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "main.py"]
"""
with open("Dockerfile", "w", encoding="utf-8") as f:
    f.write(template)

gh_workflow_config(filename, at_root=True)

Creates a starter GitHub Actions workflow file from a template.
The workflow is written to '.github/workflows/<filename>.yml', with
the placeholder '[NAME]' in the template replaced by filename. Any
missing folders are created. If the file already exists it is left
alone.
Args:
    filename (str): Name for the workflow, without the '.yml'
        extension (e.g. 'issues' -> '.github/workflows/issues.yml').
    at_root (bool, optional): When True, the path is relative to the
        current working directory. When False, the git repository
        root is looked up and the workflow is placed there.
        Defaults to True.
Returns:
    None
Raises:
    EasyConfigError: If the template cannot be read, the git repository
        cannot be found, or the workflow file cannot be written.
Example:
    === "The Py_simple Way"
        ```python
        from py_simple import gh_workflow_config

        gh_workflow_config("issues")
        ```

    === "The Traditional Way"
        ```python
        import os

        os.makedirs(".github/workflows", exist_ok=True)
        with open(".github/workflows/issues.yml", "w",
                  encoding="utf-8") as f:
            f.write(
                "name: issues

" " " "on: " " " "jobs: " " build: " " runs-on: ubuntu-latest " " " " steps: " " - uses: actions/checkout@v7 " " - name: " " run: " ) ```

gitignore_config(at_root=True)

Creates a starter .gitignore file for Python projects from a template.

The .gitignore is written to '.gitignore'. If the file already exists,
it is left alone. Any missing parent directories are created
automatically.

Args:
    at_root (bool, optional): When True, the path is relative to the
        current working directory. When False, the git repository
        root is looked up and the .gitignore is placed there.
        Defaults to True.

Returns:
    None

Raises:
    EasyConfigError: If the template cannot be read, the git repository
        cannot be found, or the file cannot be written.

Example:
    === "The Py_simple Way"
        ```python
        from py_simple import gitignore_config

        gitignore_config()
        ```

    === "The Traditional Way"
        ```python
        template = """# Byte-compiled / optimized / DLL files

pycache/ *.py[cod]

Virtual environments

venv/ .venv/

Environment variables

.env """ with open(".gitignore", "w", encoding="utf-8") as f: f.write(template) ```

read_env_file(file_path='.env')

Reads a .env configuration file into a dictionary.

Ignores blank lines and comments. Lines are split on the first '=' so values may contain additional '=' characters.

Parameters:

Name Type Description Default
file_path str

Path to the .env file to read. Defaults to ".env".

'.env'

Returns:

Type Description
dict[str, str]

dict[str, str]: Dictionary of configuration keys and values.

Raises:

Type Description
EasyConfigError

If the file cannot be read.

Example
from py_simple import read_env_file

config = read_env_file(".env")
config = {}
with open(".env", encoding="utf-8") as f:
    for line in f:
        if "=" in line and not line.startswith("#"):
            key, value = line.strip().split("=", 1)
            config[key] = value

requirements_config(packages, file_path='requirements.txt', overwrite=False)

Creates a requirements.txt file with the provided package names.

Writes one package name per line. If the file already exists and overwrite is False, the file is left alone. Any missing parent directories are created automatically.

Parameters:

Name Type Description Default
packages list[str]

List of package names to write to the file.

required
file_path str

Destination path for the requirements file. Defaults to "requirements.txt".

'requirements.txt'
overwrite bool

Whether to overwrite an existing file. Defaults to False.

False

Returns:

Type Description
None

None

Raises:

Type Description
EasyConfigError

If the file or parent directory cannot be written.

Example
from py_simple import requirements_config

requirements_config(["numpy", "pandas", "scikit-learn"])
packages = ["numpy", "pandas", "scikit-learn"]

with open("requirements.txt", "w", encoding="utf-8") as f:
    for package in packages:
        f.write(f"{package}\n")