project-conf


Nameproject-conf JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryDictionary-style configuration with path helpers and automatic environment variable handling
upload_time2025-08-24 20:49:36
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT License Copyright (c) 2024 project-conf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords config configuration dictionary environment path-helpers settings
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # project-conf

[![PyPI version](https://badge.fury.io/py/project-conf.svg)](https://badge.fury.io/py/project-conf)
[![Python Support](https://img.shields.io/pypi/pyversions/project-conf.svg)](https://pypi.org/project/project-conf/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Dictionary-style configuration with path helpers and automatic environment variable handling.**

A simple, powerful configuration system that behaves like a dictionary but provides convenient path helpers and automatic environment variable integration. Perfect for Python projects that need clean, flexible configuration management.

## โœจ Features

- **๐Ÿ—‚๏ธ Dictionary Interface**: Full dict compatibility - use `config['key']`, `config.get()`, `config.update()`, etc.
- **๐Ÿ“ Path Helpers**: Automatic directory creation with `config.data_path()`, `config.logs_path()`, etc.
- **๐ŸŒ Environment Integration**: Automatic override from environment variables and `.env` files
- **๐ŸŽฏ Type-Safe Conversion**: Smart type conversion based on your defaults
- **๐Ÿš€ Auto Project Detection**: Finds your project root automatically
- **๐Ÿ”ง Runtime Modification**: Change configuration at runtime, visible globally
- **๐Ÿ“ฆ Zero Dependencies**: Pure Python, no external dependencies

## ๐Ÿš€ Quick Start

### Installation

```bash
pip install project-conf
```

### Basic Usage

```python
from project_conf import setup, get_config

# 1. Define your configuration schema with defaults
setup({
    'database_url': 'sqlite:///app.db',
    'debug': False,
    'max_workers': 4,
    'api_key': '',
    'features': ['auth', 'cache']
})

# 2. Use anywhere in your application
config = get_config()

# Dictionary-style access
print(config['database_url'])  # sqlite:///app.db
config['debug'] = True         # Runtime modification
config.update({'timeout': 30}) # Bulk updates

# Path helpers (creates directories automatically)
db_path = config.data_path('app.db')      # /project/data/app.db
log_file = config.logs_path('server.log') # /project/logs/server.log
cache_dir = config.cache_path()           # /project/cache/
```

## ๐Ÿ“– Documentation

### Environment Variable Override

Configuration values are automatically overridden by environment variables:

```python
# config.py
setup({
    'database_url': 'sqlite:///dev.db',
    'debug': True,
    'max_workers': 2
})
```

```bash
# Environment variables (case-insensitive, converts types)
export DATABASE_URL="postgresql://localhost/prod"
export DEBUG=false
export MAX_WORKERS=8
```

```python
config = get_config()
print(config['database_url'])  # postgresql://localhost/prod
print(config['debug'])         # False
print(config['max_workers'])   # 8
```

### .env File Support

Create a `.env` file in your project root:

```env
# .env
DATABASE_URL=postgresql://localhost/myapp
DEBUG=false
MAX_WORKERS=8
API_KEY=secret-key-123
FEATURES=["auth", "admin", "analytics"]
```

Values are automatically loaded and type-converted based on your defaults.

### Path Helpers

Any method ending with `_path` becomes a path helper:

```python
config = get_config()

# Directory paths (creates directories)
config.data_path()           # /project/data/
config.logs_path()           # /project/logs/
config.uploads_path()        # /project/uploads/
config.my_custom_path()      # /project/my_custom/

# File paths (creates parent directories)
config.data_path('app.db')           # /project/data/app.db
config.logs_path('server.log')       # /project/logs/server.log
config.uploads_path('image.jpg')     # /project/uploads/image.jpg
config.my_custom_path('file.txt')    # /project/my_custom/file.txt
```

### Type Conversion

Environment variables are automatically converted to match your default types:

```python
setup({
    'debug': False,        # bool: 'true'/'false', '1'/'0', 'yes'/'no'
    'workers': 4,          # int: '8' -> 8
    'timeout': 30.0,       # float: '45.5' -> 45.5
    'name': 'app',         # str: kept as string
    'features': ['auth']   # list: '["auth", "admin"]' -> ['auth', 'admin']
})
```

### Project Root Detection

The project root is automatically detected by looking for:

1. `.git` directory (most reliable)
2. `pyproject.toml`
3. `setup.py`
4. `requirements.txt`
5. `poetry.lock`
6. `Pipfile`
7. `package.json`
8. `.env`

You can also override with `PROJECT_ROOT` environment variable or pass it directly:

```python
setup(defaults, project_root='/custom/path')
```

## ๐ŸŽฏ Real-World Example

**Clean, Simple Pattern - Handle everything in your config module:**

```python
# myproject/config.py - ONLY file that deals with project_conf
from project_conf import setup, get_config

# Single source of truth for configuration
DEFAULTS = {
    'database_url': 'sqlite:///myproject.db',
    'redis_url': 'redis://localhost:6379',
    'debug': False,
    'max_workers': 4,
    'timeout': 30.0,
    'api_key': '',
    'log_level': 'INFO',
    'features': {
        'auth': True,
        'admin': False,
        'analytics': True
    }
}

# Initialize configuration
setup(DEFAULTS)

# Export clean interface - no need for project_conf anywhere else!
config = get_config()
```

```python
# myproject/database.py - Clean imports, no project_conf needed!
from .config import config

def create_connection():
    # Use as dictionary
    db_url = config['database_url']
    timeout = config.get('timeout', 30)

    # Use path helper for file location
    if 'sqlite' in db_url:
        db_file = config.data_path('myproject.db')
        return f"sqlite://{db_file}"

    return db_url
```

```python
# myproject/api.py - Clean imports, no project_conf needed!
from .config import config

def setup_logging():
    # Runtime configuration changes
    if not config.get('api_key'):
        config['api_key'] = 'development-key'

    # Path helpers for log files
    log_file = config.logs_path('api.log')

    return setup_logger(
        level=config['log_level'],
        file=log_file
    )
```

**That's it!** No complex imports, no worrying about initialization order. Your `config.py` handles everything, and the rest of your code just imports from there.

### โœจ Why This Pattern Works

- **๐ŸŽฏ Single Responsibility**: Only `config.py` deals with `project_conf`
- **๐Ÿงน Clean Imports**: Rest of your code just imports from your own config module
- **๐Ÿ”„ No Initialization Worries**: Configuration is ready when you import it
- **๐Ÿ“ฆ Encapsulation**: `project_conf` is an implementation detail, hidden from your app
- **๐Ÿš€ Simple Testing**: Mock `myproject.config.config` in tests, not the underlying library

## ๐Ÿงช Testing

Run the test suite:

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=project_conf --cov-report=html
```

## ๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ”— Links

- [PyPI Package](https://pypi.org/project/project-conf/)
- [Source Code](https://github.com/xychenmsn/project-conf)
- [Issue Tracker](https://github.com/xychenmsn/project-conf/issues)
- [Changelog](CHANGELOG.md)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "project-conf",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "importal <xychen@msn.com>",
    "keywords": "config, configuration, dictionary, environment, path-helpers, settings",
    "author": null,
    "author_email": "importal <xychen@msn.com>",
    "download_url": "https://files.pythonhosted.org/packages/f0/15/952b87fe1f6bb995e463d491f6de6302912556c00ff1a9b85c49449b482d/project_conf-0.1.2.tar.gz",
    "platform": null,
    "description": "# project-conf\n\n[![PyPI version](https://badge.fury.io/py/project-conf.svg)](https://badge.fury.io/py/project-conf)\n[![Python Support](https://img.shields.io/pypi/pyversions/project-conf.svg)](https://pypi.org/project/project-conf/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n**Dictionary-style configuration with path helpers and automatic environment variable handling.**\n\nA simple, powerful configuration system that behaves like a dictionary but provides convenient path helpers and automatic environment variable integration. Perfect for Python projects that need clean, flexible configuration management.\n\n## \u2728 Features\n\n- **\ud83d\uddc2\ufe0f Dictionary Interface**: Full dict compatibility - use `config['key']`, `config.get()`, `config.update()`, etc.\n- **\ud83d\udcc1 Path Helpers**: Automatic directory creation with `config.data_path()`, `config.logs_path()`, etc.\n- **\ud83c\udf10 Environment Integration**: Automatic override from environment variables and `.env` files\n- **\ud83c\udfaf Type-Safe Conversion**: Smart type conversion based on your defaults\n- **\ud83d\ude80 Auto Project Detection**: Finds your project root automatically\n- **\ud83d\udd27 Runtime Modification**: Change configuration at runtime, visible globally\n- **\ud83d\udce6 Zero Dependencies**: Pure Python, no external dependencies\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install project-conf\n```\n\n### Basic Usage\n\n```python\nfrom project_conf import setup, get_config\n\n# 1. Define your configuration schema with defaults\nsetup({\n    'database_url': 'sqlite:///app.db',\n    'debug': False,\n    'max_workers': 4,\n    'api_key': '',\n    'features': ['auth', 'cache']\n})\n\n# 2. Use anywhere in your application\nconfig = get_config()\n\n# Dictionary-style access\nprint(config['database_url'])  # sqlite:///app.db\nconfig['debug'] = True         # Runtime modification\nconfig.update({'timeout': 30}) # Bulk updates\n\n# Path helpers (creates directories automatically)\ndb_path = config.data_path('app.db')      # /project/data/app.db\nlog_file = config.logs_path('server.log') # /project/logs/server.log\ncache_dir = config.cache_path()           # /project/cache/\n```\n\n## \ud83d\udcd6 Documentation\n\n### Environment Variable Override\n\nConfiguration values are automatically overridden by environment variables:\n\n```python\n# config.py\nsetup({\n    'database_url': 'sqlite:///dev.db',\n    'debug': True,\n    'max_workers': 2\n})\n```\n\n```bash\n# Environment variables (case-insensitive, converts types)\nexport DATABASE_URL=\"postgresql://localhost/prod\"\nexport DEBUG=false\nexport MAX_WORKERS=8\n```\n\n```python\nconfig = get_config()\nprint(config['database_url'])  # postgresql://localhost/prod\nprint(config['debug'])         # False\nprint(config['max_workers'])   # 8\n```\n\n### .env File Support\n\nCreate a `.env` file in your project root:\n\n```env\n# .env\nDATABASE_URL=postgresql://localhost/myapp\nDEBUG=false\nMAX_WORKERS=8\nAPI_KEY=secret-key-123\nFEATURES=[\"auth\", \"admin\", \"analytics\"]\n```\n\nValues are automatically loaded and type-converted based on your defaults.\n\n### Path Helpers\n\nAny method ending with `_path` becomes a path helper:\n\n```python\nconfig = get_config()\n\n# Directory paths (creates directories)\nconfig.data_path()           # /project/data/\nconfig.logs_path()           # /project/logs/\nconfig.uploads_path()        # /project/uploads/\nconfig.my_custom_path()      # /project/my_custom/\n\n# File paths (creates parent directories)\nconfig.data_path('app.db')           # /project/data/app.db\nconfig.logs_path('server.log')       # /project/logs/server.log\nconfig.uploads_path('image.jpg')     # /project/uploads/image.jpg\nconfig.my_custom_path('file.txt')    # /project/my_custom/file.txt\n```\n\n### Type Conversion\n\nEnvironment variables are automatically converted to match your default types:\n\n```python\nsetup({\n    'debug': False,        # bool: 'true'/'false', '1'/'0', 'yes'/'no'\n    'workers': 4,          # int: '8' -> 8\n    'timeout': 30.0,       # float: '45.5' -> 45.5\n    'name': 'app',         # str: kept as string\n    'features': ['auth']   # list: '[\"auth\", \"admin\"]' -> ['auth', 'admin']\n})\n```\n\n### Project Root Detection\n\nThe project root is automatically detected by looking for:\n\n1. `.git` directory (most reliable)\n2. `pyproject.toml`\n3. `setup.py`\n4. `requirements.txt`\n5. `poetry.lock`\n6. `Pipfile`\n7. `package.json`\n8. `.env`\n\nYou can also override with `PROJECT_ROOT` environment variable or pass it directly:\n\n```python\nsetup(defaults, project_root='/custom/path')\n```\n\n## \ud83c\udfaf Real-World Example\n\n**Clean, Simple Pattern - Handle everything in your config module:**\n\n```python\n# myproject/config.py - ONLY file that deals with project_conf\nfrom project_conf import setup, get_config\n\n# Single source of truth for configuration\nDEFAULTS = {\n    'database_url': 'sqlite:///myproject.db',\n    'redis_url': 'redis://localhost:6379',\n    'debug': False,\n    'max_workers': 4,\n    'timeout': 30.0,\n    'api_key': '',\n    'log_level': 'INFO',\n    'features': {\n        'auth': True,\n        'admin': False,\n        'analytics': True\n    }\n}\n\n# Initialize configuration\nsetup(DEFAULTS)\n\n# Export clean interface - no need for project_conf anywhere else!\nconfig = get_config()\n```\n\n```python\n# myproject/database.py - Clean imports, no project_conf needed!\nfrom .config import config\n\ndef create_connection():\n    # Use as dictionary\n    db_url = config['database_url']\n    timeout = config.get('timeout', 30)\n\n    # Use path helper for file location\n    if 'sqlite' in db_url:\n        db_file = config.data_path('myproject.db')\n        return f\"sqlite://{db_file}\"\n\n    return db_url\n```\n\n```python\n# myproject/api.py - Clean imports, no project_conf needed!\nfrom .config import config\n\ndef setup_logging():\n    # Runtime configuration changes\n    if not config.get('api_key'):\n        config['api_key'] = 'development-key'\n\n    # Path helpers for log files\n    log_file = config.logs_path('api.log')\n\n    return setup_logger(\n        level=config['log_level'],\n        file=log_file\n    )\n```\n\n**That's it!** No complex imports, no worrying about initialization order. Your `config.py` handles everything, and the rest of your code just imports from there.\n\n### \u2728 Why This Pattern Works\n\n- **\ud83c\udfaf Single Responsibility**: Only `config.py` deals with `project_conf`\n- **\ud83e\uddf9 Clean Imports**: Rest of your code just imports from your own config module\n- **\ud83d\udd04 No Initialization Worries**: Configuration is ready when you import it\n- **\ud83d\udce6 Encapsulation**: `project_conf` is an implementation detail, hidden from your app\n- **\ud83d\ude80 Simple Testing**: Mock `myproject.config.config` in tests, not the underlying library\n\n## \ud83e\uddea Testing\n\nRun the test suite:\n\n```bash\n# Install development dependencies\npip install -e \".[dev]\"\n\n# Run tests\npytest\n\n# Run with coverage\npytest --cov=project_conf --cov-report=html\n```\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udd17 Links\n\n- [PyPI Package](https://pypi.org/project/project-conf/)\n- [Source Code](https://github.com/xychenmsn/project-conf)\n- [Issue Tracker](https://github.com/xychenmsn/project-conf/issues)\n- [Changelog](CHANGELOG.md)\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2024 project-conf\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "Dictionary-style configuration with path helpers and automatic environment variable handling",
    "version": "0.1.2",
    "project_urls": {
        "Changelog": "https://github.com/xychenmsn/project-conf/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/xychenmsn/project-conf#readme",
        "Homepage": "https://github.com/xychenmsn/project-conf",
        "Issues": "https://github.com/xychenmsn/project-conf/issues",
        "Repository": "https://github.com/xychenmsn/project-conf"
    },
    "split_keywords": [
        "config",
        " configuration",
        " dictionary",
        " environment",
        " path-helpers",
        " settings"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1074d363ee8c0d2c36422ad9790ee2d5f020b65b9628ab6bfe6b58ceb4f4ba12",
                "md5": "8f25c47d16734ab372f9531fce99fe7f",
                "sha256": "377dced8947a238c64b3ed4498b43a05c98def18059191906d5b81ed4c39b5c4"
            },
            "downloads": -1,
            "filename": "project_conf-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8f25c47d16734ab372f9531fce99fe7f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 9181,
            "upload_time": "2025-08-24T20:49:34",
            "upload_time_iso_8601": "2025-08-24T20:49:34.881866Z",
            "url": "https://files.pythonhosted.org/packages/10/74/d363ee8c0d2c36422ad9790ee2d5f020b65b9628ab6bfe6b58ceb4f4ba12/project_conf-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f015952b87fe1f6bb995e463d491f6de6302912556c00ff1a9b85c49449b482d",
                "md5": "2cc1e24aa5f3edc3576eb064fcbdc0a6",
                "sha256": "771a4919d0cde6362fa2cd67328c6d1240f34584a4ae5b41fdd0030e061b17d7"
            },
            "downloads": -1,
            "filename": "project_conf-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "2cc1e24aa5f3edc3576eb064fcbdc0a6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 20133,
            "upload_time": "2025-08-24T20:49:36",
            "upload_time_iso_8601": "2025-08-24T20:49:36.083184Z",
            "url": "https://files.pythonhosted.org/packages/f0/15/952b87fe1f6bb995e463d491f6de6302912556c00ff1a9b85c49449b482d/project_conf-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-24 20:49:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "xychenmsn",
    "github_project": "project-conf",
    "github_not_found": true,
    "lcname": "project-conf"
}
        
Elapsed time: 1.06354s