Skip to main content

ProperPy - Declarative Configuration Using Python Itself

Python Version License

👉中文

ProperPy is a Python-based declarative configuration parsing tool and structured data generation tool, integrating component-based development ideas with Python's native syntax, offering:

  • Definition file (schema.py) — like JSON Schema
    • 🧩 React/Compose style component-based configuration building
    • 🔒 Pydantic constraint support
  • Configuration file (.proper.py) — like JSON/TOML/YAML
    • 🐍 Pure Python syntax to implement DSL
    • ⚙️ Declarative configuration syntax
    • ✍ IDE type hints based on Python when writing
  • Parsing configuration — like GSON
    • 🛡️ Dynamic dependency resolution and type safety

Quick Start

Installation

pip install properpy

Basic Usage

Writing Definition File (config_schema.py)

The definition file refers to the file that defines the number of configuration items and the types of configuration items. It is usually used to verify the legality of configuration items and provide type hints when writing. ProperPy provides two decorators to help build definition files.

  1. component decorator. Wraps the function used to validate parameters into a component function that can support input of various dictionaries and subcomponents.
  2. config_wraper(RECEIVER) decorator factory. Same as above.

Functions wrapped by these two decorators are called components, which are a series of functions for parameter validation. Components will return a dictionary representing the component structure. For config_wraper, if RECEIVER is a dictionary, the result will be updated into RECEIVER; if it is a function, the result will be passed as a parameter to call this function.

According to the parameters passed to the component, the content of the result dictionary is as follows. If the positional parameters passed to the component are dictionaries and contain the tag key, they are treated as subcomponents; if they do not contain the tag key, they are merged into the result dictionary; if the parameters are keyword arguments, they are merged into the result dictionary.

  • 'tag': tag name (function name of the component)
  • 'children': subcomponents
  • ...attribute: keyword arguments parsed as dictionary attributes

The following example defines two components and a result receiving component.

from properpy import component, config_wrapper

@component
def html(title: str, class_: str = ""):
    pass

@component
def div(content: str, style: dict = None):
    pass

RESULT = {}
@config_wrapper(RESULT)
def define_config(html_component, title: str):
    pass

Writing Configuration File (config.proper.py)

The configuration file refers to the file that users need to configure based on the configuration item information provided by the definition file. Please use .proper.py as the suffix for ProperPy configuration files.

ProperPy provides the attrs function to help write configuration items.

The attrs function accepts any positional parameters (dictionary type) and keyword arguments, and merges them into a dictionary. It is mainly used to help convert keyword writing forms into dictionary writing forms.

The following example demonstrates how to call the result wrapper component and build the configuration file through component construction.

from config_schema import html, div, define_config
from properpy import attrs

other = "wrong"
define_config(
    html(
        div(
            attrs(style={"color": "red"}),
            "Dynamic content"
        ),
        class_="container"
    ),
    title="My App"
)

Parsing Configuration

ProperPy provides two ways to parse configurations and corresponding functions.

Parsing by Import

When using this method, you need to provide a receiving function or receiving dictionary in the definition file, and use config_wrapper to wrap the component. As in the RESULT in the above code.

Global variables in the configuration file need to be referenced through the imported module.

import_config: Dynamically import the module under a certain path and name it module_name

  • Parameters:
    • file_path:str: Path of the configuration file to import
    • module_name:str: Module naming, can be left blank (because the configuration file name contains illegal .proper, it will automatically be replaced with _)
  • Return value:ModuleType

Example code:

from properpy import import_config
from config_schema import RESULT

module = import_config("path/to/config.proper.py")
print(json.dumps(RESULT, indent=2))
# module.other is used to reference the global variable other

Output:

{
  "tag": "define_config",
  "children": [
    {
      "tag": "html",
      "children": [
        {
          "tag": "div",
          "children": [
            "Dynamic content"
          ],
          "style": {
            "color": "red"
          }
        }
      ],
      "class_": "container"
    }
  ],
  "title": "My App"
}
Parsing by Parser

This method performs static analysis on the entire file, and then dynamically executes the code in a sandbox after analysis, so a list of modules supported by the sandbox needs to be provided.

In this method, global variables will be added to the parsing result dictionary.

parse_config:

  • Parameters:
    • file_path_or_code:str|PathLike[str]|PathLike[bytes]: Configuration file path or configuration file code
    • supported_modules:list[str]: List of supported modules
    • supported_builtin_modules:list[ModuleTag]: List of supported Python built-in module types
      • ModuleTag.MONITOR: Built-in modules that require behavior monitoring
      • ModuleTag.NORMAL: Regular built-in modules
      • ModuleTag.RISK: Built-in modules containing risky behaviors
      • ModuleTag.BLOCKED: Built-in modules that should be blocked from parsing
    • module_paths:list[str]: Module search paths, default is empty
  • Return value:dict: Parsing result

Example code:

from properpy import parse_config, ModuleTag

result = parse_config("path/to/config.proper.py", ["config_schema"], [ModuleTag.NORMAL])
print(json.dumps(result, indent=2))

Output:

{
  "children": [
    {
      "tag": "define_config",
      "children": [
        {
          "tag": "html",
          "children": [
            {
              "tag": "div",
              "children": [
                "Dynamic content"
              ],
              "style": {
                "color": "red"
              }
            }
          ],
          "class_": "container"
        }
      ],
      "title": "My App"
    }
  ],
  "other": "wrong"
}

Contribution Guide

Package management tool uses uv

# Development environment setup
git clone https://github.com/yourusername/properpy.git
cd properpy
uv install

Metadata

Release files for properpy 0.1.0

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

Source distribution (sdist)

Source distribution for properpy 0.1.0
File Size Uploaded
properpy-0.1.0.tar.gz 15.1 kB Details

Built distribution (wheel)

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

Total release size: 27.7 kB

Release files / properpy-0.1.0.tar.gz

Download URL properpy-0.1.0.tar.gz
Size 15.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2980aef9383e9b2c012387114edfb7d97a173ee54bf5b4b578c2c602648dc4d7
BLAKE2b-256 checksum
How to use checksums
8b9bc1eff47db69d21661885f488523cf2075c3bb73412bc20feb323f4c54b27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.25

Release files / properpy-0.1.0-py3-none-any.whl

Download URL properpy-0.1.0-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1aa429a5d6db8adc31018ff42080a64030195043175cfc69dc70eb76831a70c2
BLAKE2b-256 checksum
How to use checksums
2b8d9d1948e19dd85b14e990e096bb5d6979528c42b1598edf8e81acd7d88fdd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.25

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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