Python File as Property File. Configuration in Python Itself.
Project description
ProperPy - Declarative Configuration Using Python Itself
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.
componentdecorator. Wraps the function used to validate parameters into a component function that can support input of various dictionaries and subcomponents.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 importmodule_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 codesupported_modules:list[str]: List of supported modulessupported_builtin_modules:list[ModuleTag]: List of supported Python built-in module typesModuleTag.MONITOR: Built-in modules that require behavior monitoringModuleTag.NORMAL: Regular built-in modulesModuleTag.RISK: Built-in modules containing risky behaviorsModuleTag.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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file properpy-0.1.0.tar.gz.
File metadata
- Download URL: properpy-0.1.0.tar.gz
- Upload date:
- Size: 15.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2980aef9383e9b2c012387114edfb7d97a173ee54bf5b4b578c2c602648dc4d7
|
|
| MD5 |
8c4bbede7cf04763d692398edf7314b8
|
|
| BLAKE2b-256 |
8b9bc1eff47db69d21661885f488523cf2075c3bb73412bc20feb323f4c54b27
|
File details
Details for the file properpy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: properpy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aa429a5d6db8adc31018ff42080a64030195043175cfc69dc70eb76831a70c2
|
|
| MD5 |
671185c26bdd3e4ddb3c4f376fc9696c
|
|
| BLAKE2b-256 |
2b8d9d1948e19dd85b14e990e096bb5d6979528c42b1598edf8e81acd7d88fdd
|