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.
- kpower_forecast-2026.2.0/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- kpower_forecast-2026.2.0/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- kpower_forecast-2026.2.0/.github/pull_request_template.md +28 -0
- kpower_forecast-2026.2.0/.github/workflows/ci.yml +37 -0
- kpower_forecast-2026.2.0/.github/workflows/deploy.yml +55 -0
- kpower_forecast-2026.2.0/.gitignore +207 -0
- kpower_forecast-2026.2.0/.python-version +1 -0
- kpower_forecast-2026.2.0/AGENTS.md +140 -0
- kpower_forecast-2026.2.0/GEMINI.md +138 -0
- kpower_forecast-2026.2.0/LICENSE +661 -0
- kpower_forecast-2026.2.0/PKG-INFO +138 -0
- kpower_forecast-2026.2.0/README.md +108 -0
- kpower_forecast-2026.2.0/pyproject.toml +51 -0
- kpower_forecast-2026.2.0/src/kpower_forecast/__init__.py +4 -0
- kpower_forecast-2026.2.0/src/kpower_forecast/core.py +142 -0
- kpower_forecast-2026.2.0/src/kpower_forecast/storage.py +60 -0
- kpower_forecast-2026.2.0/src/kpower_forecast/utils.py +36 -0
- kpower_forecast-2026.2.0/src/kpower_forecast/weather_client.py +115 -0
- kpower_forecast-2026.2.0/tests/test_core.py +100 -0
- kpower_forecast-2026.2.0/tests/test_utils.py +24 -0
- kpower_forecast-2026.2.0/uv.lock +924 -0
|
@@ -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
|
+
```
|