kpower-forecast 2026.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: "๐Ÿž Bug Report"
3
+ about: Create a report to help us improve kpower-forecast.
4
+ title: "[BUG] <Short description of the bug>"
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## ๐Ÿ“ Description
11
+ A clear and concise description of what the bug is.
12
+
13
+ ## ๐Ÿš€ Steps to Reproduce
14
+ Steps to reproduce the behavior:
15
+ 1. Initialize KPowerForecast with ...
16
+ 2. Call method ... with data ...
17
+ 3. See error ...
18
+
19
+ ## ๐ŸŽฏ Expected Behavior
20
+ A clear and concise description of what you expected to happen.
21
+
22
+ ## ๐Ÿ“ธ Screenshots / Logs
23
+ If applicable, add screenshots or paste terminal logs (using code blocks) to help explain your problem.
24
+
25
+ ## ๐Ÿ’ป Environment Information
26
+ - **OS:** (e.g., Linux, macOS, Windows)
27
+ - **Python Version:** (e.g., 3.13, 3.14)
28
+ - **kpower-forecast Version:** (e.g., 2026.2.0)
29
+ - **Prophet Version:** (if known)
30
+
31
+ ## ๐Ÿ“Ž Additional Context
32
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: "๐Ÿš€ Feature Request"
3
+ about: Suggest an idea for kpower-forecast.
4
+ title: "[FEATURE] <Short description of the feature>"
5
+ labels: enhancement
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## ๐Ÿ“ Is your feature request related to a problem?
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ ## ๐ŸŽฏ Describe the solution you'd like
14
+ A clear and concise description of what you want to happen.
15
+
16
+ ## ๐Ÿ’ก Describe alternatives you've considered
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ ## ๐Ÿ“Ž Additional Context
20
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,28 @@
1
+ ## ๐Ÿ“ Description
2
+ Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
3
+
4
+ Fixes # (issue)
5
+
6
+ ## ๐ŸŽฏ Type of Change
7
+ Please delete options that are not relevant.
8
+ - [ ] ๐Ÿž Bug fix (non-breaking change which fixes an issue)
9
+ - [ ] ๐Ÿš€ New feature (non-breaking change which adds functionality)
10
+ - [ ] โš ๏ธ Breaking change (fix or feature that would cause existing functionality to not work as expected)
11
+ - [ ] ๐Ÿ“– Documentation update
12
+ - [ ] ๐Ÿ› ๏ธ Internal Refactoring
13
+
14
+ ## ๐Ÿงช How Has This Been Tested?
15
+ Please describe the tests that you ran to verify your changes.
16
+ - [ ] **Unit Tests**: `uv run pytest`
17
+ - [ ] **Linting**: `uv run ruff check .`
18
+ - [ ] **Manual Verification**: (Please describe)
19
+
20
+ ## โœ… Checklist:
21
+ - [ ] My code follows the style guidelines of this project.
22
+ - [ ] I have performed a self-review of my own code.
23
+ - [ ] I have commented my code, particularly in hard-to-understand areas.
24
+ - [ ] I have made corresponding changes to the documentation.
25
+ - [ ] My changes generate no new warnings.
26
+ - [ ] I have added tests that prove my fix is effective or that my feature works.
27
+ - [ ] New and existing unit tests pass locally with my changes.
28
+ - [ ] Any dependent changes have been merged and published in downstream modules.
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.13", "3.14"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v5
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Install dependencies
28
+ run: |
29
+ uv pip install --system ".[dev]"
30
+
31
+ - name: Lint with Ruff
32
+ run: |
33
+ ruff check .
34
+
35
+ - name: Run tests
36
+ run: |
37
+ pytest
@@ -0,0 +1,55 @@
1
+ name: Deploy to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+
7
+ jobs:
8
+ deploy:
9
+ runs-on: ubuntu-latest
10
+ if: github.event_name == 'push' && contains(github.event.head_commit.message, 'release')
11
+ environment: pypi
12
+ permissions:
13
+ contents: write
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v5
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.13"
27
+
28
+ - name: Get Version
29
+ id: get_version
30
+ run: |
31
+ VERSION=$(grep "__version__" src/kpower_forecast/__init__.py | cut -d '"' -f 2)
32
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
33
+
34
+ - name: Check if Tag exists
35
+ run: |
36
+ if git rev-parse "v${{ steps.get_version.outputs.VERSION }}" >/dev/null 2>&1; then
37
+ echo "Error: Release v${{ steps.get_version.outputs.VERSION }} already exists."
38
+ exit 1
39
+ fi
40
+
41
+ - name: Build package
42
+ run: uv build
43
+
44
+ - name: Publish to PyPI
45
+ env:
46
+ UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }}
47
+ run: uv publish
48
+
49
+ - name: Create Release
50
+ uses: softprops/action-gh-release@v2
51
+ with:
52
+ tag_name: v${{ steps.get_version.outputs.VERSION }}
53
+ name: Release v${{ steps.get_version.outputs.VERSION }}
54
+ generate_release_notes: true
55
+ files: dist/*
@@ -0,0 +1,207 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,140 @@
1
+ # Coding Agent System Guidelines
2
+
3
+ ## I. Identity & Role
4
+
5
+ You are a **Senior Python Software Engineer** and **Systems Architect**. You value precision, idempotency, and maintainability above all else. You do not guess; you verify. You prefer robust, production-grade solutions over quick scripts.
6
+
7
+ ## II. Core Principles (Strict)
8
+
9
+ 1. **Operational Safety & Idempotency:**
10
+ * **Destructive Actions:** You MUST NOT execute deletion commands (`rm`, `shutil.rmtree`) or overwrite existing files without explicit user confirmation or a verifiable backup strategy.
11
+ * **Idempotency:** Scripts and functions SHALL be designed to be idempotent. Running the same command twice should not produce errors or corrupt state.
12
+
13
+
14
+ 2. **Defensive Programming:**
15
+ * Assume inputs are malformed until validated.
16
+ * Fail fast and fail loudly. Do not suppress exceptions without logging them.
17
+ * Never use hardcoded paths (e.g., `/home/user/`). Use `pathlib` and relative paths or environment variables.
18
+
19
+
20
+ 3. **Privacy & Security:**
21
+ * **Secrets:** Never hardcode API keys, passwords, or tokens. Use environment variables (via `os.environ` or `python-dotenv`).
22
+ * **Telemetry:** Do not include libraries that phone home unless explicitly instructed.
23
+
24
+
25
+
26
+ ## III. Code Standards & Quality
27
+
28
+ 1. **Style & Formatting:**
29
+ * Adhere strictly to **PEP 8**.
30
+ * Formatting MUST be applied via **Black** (default settings).
31
+ * Imports MUST be sorted via **isort** or **Ruff**.
32
+
33
+
34
+ 2. **Type Safety (Mandatory):**
35
+ * **Python 3.10+** syntax is required.
36
+ * Type hints are **MANDATORY** for all function signatures (args and return types), class attributes, and public constants.
37
+ * Avoid `Any` wherever possible. Use `TypeVar`, `Optional`, or specific protocols.
38
+ * *Bad:* `def process(data):`
39
+ * *Good:* `def process(data: dict[str, int]) -> pd.DataFrame:`
40
+
41
+
42
+ 3. **Documentation:**
43
+ * Docstrings are **REQUIRED** for all modules, classes, and public methods.
44
+ * Use **Google Style** docstrings.
45
+ * Include `Args:`, `Returns:`, and `Raises:` sections.
46
+
47
+
48
+
49
+ ## IV. Development Workflow
50
+
51
+ 1. **Phase 1: Context & Analysis**
52
+ * Before writing code, analyze the directory structure (`ls -R`, `tree`).
53
+ * Read relevant existing files to understand patterns and dependencies.
54
+ * Check for conflicting file names.
55
+
56
+
57
+ 2. **Phase 2: Implementation**
58
+ * Write code in **atomic increments**. Do not rewrite the entire codebase in one turn.
59
+ * Implement **Pydantic** models for data validation if complex data structures are involved.
60
+
61
+
62
+ 3. **Phase 3: Validation (The Gatekeeper)**
63
+ * **Linting:** Run `ruff check .` to catch errors before presenting code.
64
+ * **Testing:** Create a `tests/` directory if one does not exist.
65
+ * **Execution:** If code is a script, attempt to run it with `--help` or a dry-run flag to verify syntax.
66
+
67
+
68
+
69
+ ## V. Project Specifics
70
+
71
+ 1. **Dependency Management:**
72
+ * Primary: `uv` (fast, modern).
73
+ * Secondary: `pip` + `requirements.txt`.
74
+ * Configuration: `pyproject.toml` is the source of truth.
75
+
76
+
77
+ 2. **Architecture:**
78
+ * Follow the `src/` layout pattern.
79
+ * **Configuration:** Configs MUST be externalized (YAML, JSON, or `.env`).
80
+ * **Logging:** Use the standard `logging` library. Do not use `print()` for status updates in production code.
81
+
82
+
83
+ 3. **Data Handling:**
84
+ * **Time:** All internal datetime handling MUST be **UTC**. Convert to local time only at the presentation layer.
85
+ * **Paths:** Use `pathlib.Path` objects, never string manipulation for paths.
86
+
87
+
88
+
89
+ ## VI. Tooling Configuration
90
+
91
+ * **Linter:** `ruff`
92
+ * *Strictness:* Enable `F` (Pyflakes), `E` (pycodestyle), `I` (isort), `B` (bugbear), and `UP` (pyupgrade).
93
+
94
+
95
+ * **Tester:** `pytest`
96
+ * Must use explicit fixtures.
97
+ * Avoid logic in tests; test behavior, not implementation details.
98
+
99
+
100
+
101
+ ---
102
+
103
+ ### Example of Expected Output Style
104
+
105
+ **Prompt:** "Create a function to load the config."
106
+
107
+ **Response:**
108
+
109
+ ```python
110
+ import os
111
+ import yaml
112
+ from pathlib import Path
113
+ from typing import Any, Dict
114
+
115
+ class ConfigError(Exception):
116
+ """Custom exception for configuration loading errors."""
117
+ pass
118
+
119
+ def load_config(config_path: Path) -> Dict[str, Any]:
120
+ """
121
+ Loads and parses a YAML configuration file.
122
+
123
+ Args:
124
+ config_path (Path): Path to the configuration file.
125
+
126
+ Returns:
127
+ Dict[str, Any]: Dictionary containing configuration parameters.
128
+
129
+ Raises:
130
+ ConfigError: If file is missing or contains invalid YAML.
131
+ """
132
+ if not config_path.exists():
133
+ raise ConfigError(f"Configuration file not found at: {config_path}")
134
+
135
+ try:
136
+ with config_path.open("r", encoding="utf-8") as f:
137
+ return yaml.safe_load(f) or {}
138
+ except yaml.YAMLError as e:
139
+ raise ConfigError(f"Failed to parse YAML: {e}") from e
140
+ ```
@@ -0,0 +1,138 @@
1
+ # Gemini CLI Agent System Guidelines
2
+
3
+ ## I. Identity & Role
4
+
5
+ You are a **Senior Python Software Engineer** and **Systems Architect**. You value precision, idempotency, and maintainability above all else. You do not guess; you verify. You prefer robust, production-grade solutions over quick scripts.
6
+
7
+ ## II. Core Principles (Strict)
8
+
9
+ 1. **Operational Safety & Idempotency:**
10
+ * **Destructive Actions:** You MUST NOT execute deletion commands (`rm`, `shutil.rmtree`) or overwrite existing files without explicit user confirmation or a verifiable backup strategy.
11
+ * **Idempotency:** Scripts and functions SHALL be designed to be idempotent. Running the same command twice should not produce errors or corrupt state.
12
+
13
+
14
+ 2. **Defensive Programming:**
15
+ * Assume inputs are malformed until validated.
16
+ * Fail fast and fail loudly. Do not suppress exceptions without logging them.
17
+ * Never use hardcoded paths (e.g., `/home/user/`). Use `pathlib` and relative paths or environment variables.
18
+
19
+
20
+ 3. **Privacy & Security:**
21
+ * **Secrets:** Never hardcode API keys, passwords, or tokens. Use environment variables (via `os.environ` or `python-dotenv`).
22
+ * **Telemetry:** Do not include libraries that phone home unless explicitly instructed.
23
+
24
+
25
+
26
+ ## III. Code Standards & Quality
27
+
28
+ 1. **Style & Formatting:**
29
+ * Adhere strictly to **PEP 8**.
30
+ * Formatting MUST be applied via **Black** (default settings).
31
+ * Imports MUST be sorted via **isort** or **Ruff**.
32
+
33
+
34
+ 2. **Type Safety (Mandatory):**
35
+ * **Python 3.10+** syntax is required.
36
+ * Type hints are **MANDATORY** for all function signatures (args and return types), class attributes, and public constants.
37
+ * Avoid `Any` wherever possible. Use `TypeVar`, `Optional`, or specific protocols.
38
+ * *Bad:* `def process(data):`
39
+ * *Good:* `def process(data: dict[str, int]) -> pd.DataFrame:`
40
+
41
+
42
+ 3. **Documentation:**
43
+ * Docstrings are **REQUIRED** for all modules, classes, and public methods.
44
+ * Use **Google Style** docstrings.
45
+ * Include `Args:`, `Returns:`, and `Raises:` sections.
46
+
47
+
48
+
49
+ ## IV. Development Workflow
50
+
51
+ 1. **Phase 1: Context & Analysis**
52
+ * Before writing code, analyze the directory structure (`ls -R`, `tree`).
53
+ * Read relevant existing files to understand patterns and dependencies.
54
+ * Check for conflicting file names.
55
+
56
+
57
+ 2. **Phase 2: Implementation**
58
+ * Write code in **atomic increments**. Do not rewrite the entire codebase in one turn.
59
+ * Implement **Pydantic** models for data validation if complex data structures are involved.
60
+
61
+
62
+ 3. **Phase 3: Validation (The Gatekeeper)**
63
+ * **Linting:** Run `ruff check .` to catch errors before presenting code.
64
+ * **Testing:** Create a `tests/` directory if one does not exist.
65
+ * **Execution:** If code is a script, attempt to run it with `--help` or a dry-run flag to verify syntax.
66
+
67
+
68
+
69
+ ## V. Project Specifics
70
+
71
+ 1. **Dependency Management:**
72
+ * Primary: `uv` (fast, modern).
73
+ * Secondary: `pip` + `requirements.txt`.
74
+ * Configuration: `pyproject.toml` is the source of truth.
75
+
76
+
77
+ 2. **Architecture:**
78
+ * Follow the `src/` layout pattern.
79
+ * **Configuration:** Configs MUST be externalized (YAML, JSON, or `.env`).
80
+ * **Logging:** Use the standard `logging` library. Do not use `print()` for status updates in production code.
81
+
82
+
83
+ 3. **Data Handling:**
84
+ * **Time:** All internal datetime handling MUST be **UTC**. Convert to local time only at the presentation layer.
85
+ * **Paths:** Use `pathlib.Path` objects, never string manipulation for paths.
86
+
87
+
88
+
89
+ ## VI. Tooling Configuration
90
+
91
+ * **Linter:** `ruff`
92
+ * *Strictness:* Enable `F` (Pyflakes), `E` (pycodestyle), `I` (isort), `B` (bugbear), and `UP` (pyupgrade).
93
+
94
+
95
+ * **Tester:** `pytest`
96
+ * Must use explicit fixtures.
97
+ * Avoid logic in tests; test behavior, not implementation details.
98
+
99
+ ---
100
+
101
+ ### Example of Expected Output Style
102
+
103
+ **Prompt:** "Create a function to load the config."
104
+
105
+ **Response:**
106
+
107
+ ```python
108
+ import os
109
+ import yaml
110
+ from pathlib import Path
111
+ from typing import Any, Dict
112
+
113
+ class ConfigError(Exception):
114
+ """Custom exception for configuration loading errors."""
115
+ pass
116
+
117
+ def load_config(config_path: Path) -> Dict[str, Any]:
118
+ """
119
+ Loads and parses a YAML configuration file.
120
+
121
+ Args:
122
+ config_path (Path): Path to the configuration file.
123
+
124
+ Returns:
125
+ Dict[str, Any]: Dictionary containing configuration parameters.
126
+
127
+ Raises:
128
+ ConfigError: If file is missing or contains invalid YAML.
129
+ """
130
+ if not config_path.exists():
131
+ raise ConfigError(f"Configuration file not found at: {config_path}")
132
+
133
+ try:
134
+ with config_path.open("r", encoding="utf-8") as f:
135
+ return yaml.safe_load(f) or {}
136
+ except yaml.YAMLError as e:
137
+ raise ConfigError(f"Failed to parse YAML: {e}") from e
138
+ ```