fava-nl2bql 0.1.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.
- fava_nl2bql-0.1.0/.gitattributes +1 -0
- fava_nl2bql-0.1.0/.github/dependabot.yml +31 -0
- fava_nl2bql-0.1.0/.github/pr-labeler.yml +3 -0
- fava_nl2bql-0.1.0/.github/workflows/build-publish.yml +133 -0
- fava_nl2bql-0.1.0/.github/workflows/pr-labeler.yml +18 -0
- fava_nl2bql-0.1.0/.github/workflows/release-drafter.yml +20 -0
- fava_nl2bql-0.1.0/.gitignore +37 -0
- fava_nl2bql-0.1.0/.pre-commit-config.yaml +50 -0
- fava_nl2bql-0.1.0/.readthedocs.yaml +22 -0
- fava_nl2bql-0.1.0/CLAUDE.md +16 -0
- fava_nl2bql-0.1.0/CONTRIBUTING.md +86 -0
- fava_nl2bql-0.1.0/LICENSE.txt +21 -0
- fava_nl2bql-0.1.0/MANIFEST.in +2 -0
- fava_nl2bql-0.1.0/PKG-INFO +37 -0
- fava_nl2bql-0.1.0/README.rst +15 -0
- fava_nl2bql-0.1.0/docs/_static/.gitkeep +0 -0
- fava_nl2bql-0.1.0/docs/conf.py +106 -0
- fava_nl2bql-0.1.0/docs/index.rst +25 -0
- fava_nl2bql-0.1.0/docs/installation.rst +17 -0
- fava_nl2bql-0.1.0/docs/license.rst +7 -0
- fava_nl2bql-0.1.0/docs/usage.rst +36 -0
- fava_nl2bql-0.1.0/pyproject.toml +80 -0
- fava_nl2bql-0.1.0/src/fava_nl2bql/FavaNl2Bql.js +11 -0
- fava_nl2bql-0.1.0/src/fava_nl2bql/__init__.py +10 -0
- fava_nl2bql-0.1.0/src/fava_nl2bql/extension.py +41 -0
- fava_nl2bql-0.1.0/src/fava_nl2bql/templates/FavaNl2Bql.html +26 -0
- fava_nl2bql-0.1.0/src/fava_nl2bql/translator.py +75 -0
- fava_nl2bql-0.1.0/tests/fava_nl2bql/test_extension.py +70 -0
- fava_nl2bql-0.1.0/tests/fava_nl2bql/test_translator.py +96 -0
- fava_nl2bql-0.1.0/uv.lock +1994 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: uv
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
cooldown:
|
|
8
|
+
default-days: 7
|
|
9
|
+
labels:
|
|
10
|
+
- dependencies
|
|
11
|
+
- python:uv
|
|
12
|
+
- chore
|
|
13
|
+
groups:
|
|
14
|
+
python-dependencies:
|
|
15
|
+
update-types:
|
|
16
|
+
- minor
|
|
17
|
+
- patch
|
|
18
|
+
|
|
19
|
+
- package-ecosystem: github-actions
|
|
20
|
+
directory: /
|
|
21
|
+
schedule:
|
|
22
|
+
interval: monthly
|
|
23
|
+
cooldown:
|
|
24
|
+
default-days: 7
|
|
25
|
+
labels:
|
|
26
|
+
- dependencies
|
|
27
|
+
- chore
|
|
28
|
+
groups:
|
|
29
|
+
github-actions:
|
|
30
|
+
patterns:
|
|
31
|
+
- "*"
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [master]
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
# a newer push to a pull request replaces the running checks, publishing is never interrupted
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
12
|
+
|
|
13
|
+
permissions: {}
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint:
|
|
17
|
+
name: Lint
|
|
18
|
+
runs-on: ubuntu-24.04
|
|
19
|
+
timeout-minutes: 15
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.14"
|
|
30
|
+
|
|
31
|
+
- name: Install the project
|
|
32
|
+
run: uv sync --locked --dev
|
|
33
|
+
|
|
34
|
+
- name: Pre Commit
|
|
35
|
+
run: uv run pre-commit run --all-files
|
|
36
|
+
|
|
37
|
+
- name: Check dependencies
|
|
38
|
+
run: uv run deptry src
|
|
39
|
+
|
|
40
|
+
- name: Build documentation
|
|
41
|
+
run: uv run --locked --group docs sphinx-build -W --keep-going -b html docs "$RUNNER_TEMP/docs"
|
|
42
|
+
|
|
43
|
+
test:
|
|
44
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
45
|
+
runs-on: ubuntu-24.04
|
|
46
|
+
timeout-minutes: 15
|
|
47
|
+
permissions:
|
|
48
|
+
contents: read
|
|
49
|
+
strategy:
|
|
50
|
+
fail-fast: false
|
|
51
|
+
matrix:
|
|
52
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
55
|
+
with:
|
|
56
|
+
fetch-depth: 0
|
|
57
|
+
persist-credentials: false
|
|
58
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
59
|
+
with:
|
|
60
|
+
python-version: ${{ matrix.python-version }}
|
|
61
|
+
|
|
62
|
+
- name: Install the project
|
|
63
|
+
run: uv sync --locked --dev
|
|
64
|
+
|
|
65
|
+
- name: Test
|
|
66
|
+
run: uv run pytest
|
|
67
|
+
|
|
68
|
+
build:
|
|
69
|
+
name: Build
|
|
70
|
+
runs-on: ubuntu-24.04
|
|
71
|
+
timeout-minutes: 15
|
|
72
|
+
permissions:
|
|
73
|
+
contents: read
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
76
|
+
with:
|
|
77
|
+
fetch-depth: 0
|
|
78
|
+
persist-credentials: false
|
|
79
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
80
|
+
with:
|
|
81
|
+
python-version: "3.14"
|
|
82
|
+
|
|
83
|
+
- name: Build
|
|
84
|
+
run: uv build
|
|
85
|
+
|
|
86
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
87
|
+
with:
|
|
88
|
+
name: dist
|
|
89
|
+
path: dist/
|
|
90
|
+
if-no-files-found: error
|
|
91
|
+
|
|
92
|
+
# the publish jobs only get an OIDC token (trusted publishing), no repository content and no stored secrets
|
|
93
|
+
publish-testpypi:
|
|
94
|
+
name: Publish 📦 to TestPyPI
|
|
95
|
+
needs: [lint, test, build]
|
|
96
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
|
97
|
+
runs-on: ubuntu-24.04
|
|
98
|
+
timeout-minutes: 15
|
|
99
|
+
environment:
|
|
100
|
+
name: testpypi
|
|
101
|
+
url: https://test.pypi.org/p/fava-nl2bql
|
|
102
|
+
permissions:
|
|
103
|
+
id-token: write
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
106
|
+
with:
|
|
107
|
+
name: dist
|
|
108
|
+
path: dist/
|
|
109
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
110
|
+
|
|
111
|
+
- name: Publish distribution 📦 to Test PyPI
|
|
112
|
+
run: uv publish --trusted-publishing always --publish-url https://test.pypi.org/legacy/
|
|
113
|
+
|
|
114
|
+
publish-pypi:
|
|
115
|
+
name: Publish 📦 to PyPI
|
|
116
|
+
needs: [lint, test, build]
|
|
117
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
|
118
|
+
runs-on: ubuntu-24.04
|
|
119
|
+
timeout-minutes: 15
|
|
120
|
+
environment:
|
|
121
|
+
name: pypi
|
|
122
|
+
url: https://pypi.org/p/fava-nl2bql
|
|
123
|
+
permissions:
|
|
124
|
+
id-token: write
|
|
125
|
+
steps:
|
|
126
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
127
|
+
with:
|
|
128
|
+
name: dist
|
|
129
|
+
path: dist/
|
|
130
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
131
|
+
|
|
132
|
+
- name: Publish distribution 📦 to PyPI
|
|
133
|
+
run: uv publish --trusted-publishing always
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: PR Labeler
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
types: [opened]
|
|
5
|
+
|
|
6
|
+
permissions: {}
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
pr-labeler:
|
|
10
|
+
runs-on: ubuntu-24.04
|
|
11
|
+
timeout-minutes: 5
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
pull-requests: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: TimonVS/pr-labeler-action@f9c084306ce8b3f488a8f3ee1ccedc6da131d1af # v5.0.0
|
|
17
|
+
env:
|
|
18
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Release Drafter
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
permissions: {}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
update_release_draft:
|
|
12
|
+
runs-on: ubuntu-24.04
|
|
13
|
+
timeout-minutes: 5
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: read
|
|
17
|
+
steps:
|
|
18
|
+
- uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
|
|
19
|
+
env:
|
|
20
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Temporary and binary files
|
|
2
|
+
*~
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.so
|
|
5
|
+
*.orig
|
|
6
|
+
*.log
|
|
7
|
+
__pycache__/
|
|
8
|
+
.cache/
|
|
9
|
+
.*.swp
|
|
10
|
+
.DS_Store
|
|
11
|
+
|
|
12
|
+
# Project files
|
|
13
|
+
.idea
|
|
14
|
+
.vscode
|
|
15
|
+
|
|
16
|
+
# Package files
|
|
17
|
+
*.egg
|
|
18
|
+
*.eggs/
|
|
19
|
+
.installed.cfg
|
|
20
|
+
*.egg-info/
|
|
21
|
+
|
|
22
|
+
# Unittest, coverage and type checking
|
|
23
|
+
htmlcov/
|
|
24
|
+
.coverage
|
|
25
|
+
.tox
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.mypy_cache/
|
|
28
|
+
.ruff_cache/
|
|
29
|
+
|
|
30
|
+
# Build and docs folder/files
|
|
31
|
+
build/
|
|
32
|
+
dist/
|
|
33
|
+
docs/api/
|
|
34
|
+
docs/_build/
|
|
35
|
+
|
|
36
|
+
# Per-project virtualenvs
|
|
37
|
+
.venv*/
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
exclude: '^docs/conf.py'
|
|
2
|
+
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v6.0.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
- id: check-ast
|
|
10
|
+
- id: check-json
|
|
11
|
+
- id: check-merge-conflict
|
|
12
|
+
- id: check-xml
|
|
13
|
+
- id: check-yaml
|
|
14
|
+
- id: debug-statements
|
|
15
|
+
- id: end-of-file-fixer
|
|
16
|
+
- id: requirements-txt-fixer
|
|
17
|
+
- id: mixed-line-ending
|
|
18
|
+
args: ['--fix=auto'] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows
|
|
19
|
+
|
|
20
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
21
|
+
rev: v0.16.8
|
|
22
|
+
hooks:
|
|
23
|
+
- id: ruff-check
|
|
24
|
+
- id: ruff-format
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
|
|
27
|
+
rev: v1.0.1
|
|
28
|
+
hooks:
|
|
29
|
+
- id: rst-linter
|
|
30
|
+
files: README.rst
|
|
31
|
+
|
|
32
|
+
- repo: local
|
|
33
|
+
hooks:
|
|
34
|
+
- id: mypy
|
|
35
|
+
name: mypy
|
|
36
|
+
# runs in the project environment to see the types of the installed packages, mypy and its stubs are dev dependencies
|
|
37
|
+
entry: uv run --locked mypy src tests
|
|
38
|
+
language: system
|
|
39
|
+
types: [python]
|
|
40
|
+
pass_filenames: false
|
|
41
|
+
|
|
42
|
+
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
43
|
+
rev: 0.12.16
|
|
44
|
+
hooks:
|
|
45
|
+
- id: uv-lock
|
|
46
|
+
|
|
47
|
+
- repo: https://github.com/zizmorcore/zizmor-pre-commit
|
|
48
|
+
rev: v1.30.1
|
|
49
|
+
hooks:
|
|
50
|
+
- id: zizmor
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Read the Docs configuration file for Sphinx projects
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
# Required
|
|
5
|
+
version: 2
|
|
6
|
+
|
|
7
|
+
sphinx:
|
|
8
|
+
configuration: docs/conf.py
|
|
9
|
+
|
|
10
|
+
build:
|
|
11
|
+
os: ubuntu-24.04
|
|
12
|
+
tools:
|
|
13
|
+
python: "3.14"
|
|
14
|
+
jobs:
|
|
15
|
+
pre_create_environment:
|
|
16
|
+
- asdf plugin add uv
|
|
17
|
+
- asdf install uv latest
|
|
18
|
+
- asdf global uv latest
|
|
19
|
+
create_environment:
|
|
20
|
+
- uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
|
|
21
|
+
install:
|
|
22
|
+
- UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
@CONTRIBUTING.md
|
|
4
|
+
|
|
5
|
+
## Notes for Claude
|
|
6
|
+
|
|
7
|
+
- Open pull requests and stop there, the maintainer reviews and merges them. Do not merge unless explicitly asked.
|
|
8
|
+
- Run the checks from CONTRIBUTING.md before pushing, and `git add` new files first, `pre-commit --all-files` skips
|
|
9
|
+
untracked files.
|
|
10
|
+
- Never put real financial data, credentials or personal details into the repository, commits, pull requests or
|
|
11
|
+
issues. Tests, fixtures and examples are synthetic.
|
|
12
|
+
- Show that a test can fail: when fixing a bug, check that the new test fails without the fix.
|
|
13
|
+
- When dependencies change, regenerate `uv.lock` with the uv version of the pre-commit hook and check that the lock
|
|
14
|
+
diff only contains what you intended.
|
|
15
|
+
- Keep pull request descriptions factual: the problem, the change, how it was verified (including what could not be
|
|
16
|
+
verified before merging).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
`fava-nl2bql` is a [Fava](https://beancount.github.io/fava/) extension that translates natural-language
|
|
4
|
+
questions about a ledger into [BQL](https://beancount.github.io/docs/beancount_query_language.html) queries
|
|
5
|
+
and runs them, published to PyPI. User documentation is in `docs/` (built with Sphinx, hosted on Read the Docs).
|
|
6
|
+
|
|
7
|
+
## Layout
|
|
8
|
+
|
|
9
|
+
| Path | Content |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `src/fava_nl2bql/extension.py` | the `FavaExtensionBase` subclass Fava loads (report page, endpoints) |
|
|
12
|
+
| `src/fava_nl2bql/translator.py` | natural language → BQL translation (the tuned model lives behind this) |
|
|
13
|
+
| `src/fava_nl2bql/templates/` | Jinja template for the extension's report page |
|
|
14
|
+
| `src/fava_nl2bql/FavaNl2Bql.js` | the extension's JS module (Fava loads `<ClassName>.js` next to the class) |
|
|
15
|
+
| `tests/fava_nl2bql/` | tests, mirroring the layout of `src` |
|
|
16
|
+
| `docs/` | user documentation, `docs/api` is generated at build time and git-ignored |
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv sync --locked --dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Python 3.11 to 3.14 are supported and tested.
|
|
25
|
+
|
|
26
|
+
## Checks
|
|
27
|
+
|
|
28
|
+
CI runs the same commands, all of them have to pass:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv run pre-commit run --all-files # ruff, ruff format, mypy, uv-lock, zizmor, rst lint
|
|
32
|
+
uv run deptry src # imports vs declared dependencies
|
|
33
|
+
uv run pytest
|
|
34
|
+
uv run --group docs sphinx-build -W --keep-going -b html docs docs/_build # documentation without warnings
|
|
35
|
+
uv build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Things that catch people out:
|
|
39
|
+
|
|
40
|
+
- `pre-commit run --all-files` only looks at files tracked by git. `git add` new files before running it, otherwise
|
|
41
|
+
they are not checked (and CI then fails on them).
|
|
42
|
+
- mypy runs in the project environment (a local pre-commit hook calling `uv run mypy`), so it checks against the types
|
|
43
|
+
of the installed packages. Stub packages (`types-*`) belong into the `dev` dependency group.
|
|
44
|
+
- deptry fails for an import that is only available transitively and for a declared dependency that is not used.
|
|
45
|
+
Declare what you import in `pyproject.toml`, remove what you stop using.
|
|
46
|
+
|
|
47
|
+
## Code
|
|
48
|
+
|
|
49
|
+
- Type hints are required in `src` (mypy `disallow_untyped_defs`, tests are exempt).
|
|
50
|
+
- ruff selects `E4, E7, E9, F, B, I, S113, T20, UP` (see `pyproject.toml`), `ruff format` decides the formatting.
|
|
51
|
+
- Tests use synthetic ledgers and fixtures only: no real account numbers, balances or personal financial data,
|
|
52
|
+
not even anonymized ones.
|
|
53
|
+
|
|
54
|
+
## Dependencies
|
|
55
|
+
|
|
56
|
+
- `uv.lock` is committed. Regenerate it with the uv version of the `uv-lock` pre-commit hook (`rev` in
|
|
57
|
+
`.pre-commit-config.yaml`), a different uv version rewrites unrelated parts of the file:
|
|
58
|
+
`uvx --from uv==<rev> uv lock`.
|
|
59
|
+
- Dependabot (`.github/dependabot.yml`) opens grouped PRs for minor and patch updates of Python packages weekly and
|
|
60
|
+
for GitHub Actions monthly. Major updates come as separate PRs.
|
|
61
|
+
|
|
62
|
+
## Network
|
|
63
|
+
|
|
64
|
+
- The only network call is `translator.py`'s call to a local Ollama server via the `ollama` package.
|
|
65
|
+
Always pass `timeout=` to `Client(...)` — a stalled server must not block the request forever.
|
|
66
|
+
- Tests must not make real network calls: mock `fava_nl2bql.translator.Client` (see
|
|
67
|
+
`tests/fava_nl2bql/test_translator.py`).
|
|
68
|
+
|
|
69
|
+
## Git and pull requests
|
|
70
|
+
|
|
71
|
+
- Branch off `master`, named `feature/…`, `bugfix/…` or `chore/…` (snake_case after the prefix). The prefix labels
|
|
72
|
+
the PR (`.github/pr-labeler.yml`), and the label decides the category in the release notes (the shared
|
|
73
|
+
`release-drafter.yml` of [tarioch/.github](https://github.com/tarioch/.github)).
|
|
74
|
+
- Commit subjects are imperative and start with a capital letter, the body explains why.
|
|
75
|
+
- Changes go through pull requests into `master` and are merged with a merge commit.
|
|
76
|
+
|
|
77
|
+
## CI and releases
|
|
78
|
+
|
|
79
|
+
`.github/workflows/build-publish.yml` runs `lint`, `test` (matrix), `build`, and on pushes to `master` and version tags
|
|
80
|
+
the publish jobs. Workflows use the least permissions they need, and every action is pinned to a commit SHA.
|
|
81
|
+
|
|
82
|
+
- Every push to `master` publishes a development version to TestPyPI.
|
|
83
|
+
- Release notes are drafted by release-drafter. Publishing the draft creates the tag `vX.Y.Z`, which publishes to PyPI.
|
|
84
|
+
- Publishing uses PyPI trusted publishing (OIDC) from the GitHub environments `testpypi` and `pypi`, there are no
|
|
85
|
+
stored tokens.
|
|
86
|
+
- The version is derived from the git tags (uv-dynamic-versioning), so CI checks out the full history (`fetch-depth: 0`).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Patrick Ruckstuhl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: fava-nl2bql
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Fava extension: ask questions about your ledger in plain English, get BQL results
|
|
5
|
+
Project-URL: Homepage, https://github.com/tarioch/fava-nl2bql
|
|
6
|
+
Project-URL: Documentation, https://fava-nl2bql.rtfd.io
|
|
7
|
+
Project-URL: Repository, https://github.com/tarioch/fava-nl2bql/
|
|
8
|
+
Project-URL: Issues, https://github.com/tarioch/fava-nl2bql/issues
|
|
9
|
+
Author-email: Patrick Ruckstuhl <patrick@ch.tario.org>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE.txt
|
|
12
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
13
|
+
Classifier: Framework :: Flask
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
17
|
+
Classifier: Topic :: Office/Business :: Financial :: Accounting
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: fava>=1.30
|
|
20
|
+
Requires-Dist: ollama>=0.6
|
|
21
|
+
Description-Content-Type: text/x-rst
|
|
22
|
+
|
|
23
|
+
.. image:: https://img.shields.io/pypi/l/fava-nl2bql.svg
|
|
24
|
+
:target: https://pypi.python.org/pypi/fava-nl2bql
|
|
25
|
+
.. image:: https://img.shields.io/pypi/v/fava-nl2bql.svg
|
|
26
|
+
:target: https://pypi.python.org/pypi/fava-nl2bql
|
|
27
|
+
.. image:: https://readthedocs.org/projects/fava-nl2bql/badge
|
|
28
|
+
:target: https://fava-nl2bql.rtfd.io
|
|
29
|
+
|
|
30
|
+
fava-nl2bql
|
|
31
|
+
===========
|
|
32
|
+
|
|
33
|
+
A `Fava <https://beancount.github.io/fava/>`__ extension that translates plain-English questions about
|
|
34
|
+
your ledger into `BQL <https://beancount.github.io/docs/beancount_query_language.html>`__ queries and runs
|
|
35
|
+
them, using a small tuned model instead of hand-written heuristics.
|
|
36
|
+
|
|
37
|
+
This project is a work in progress. See the detailed `Documentation <https://fava-nl2bql.rtfd.io/>`__.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.. image:: https://img.shields.io/pypi/l/fava-nl2bql.svg
|
|
2
|
+
:target: https://pypi.python.org/pypi/fava-nl2bql
|
|
3
|
+
.. image:: https://img.shields.io/pypi/v/fava-nl2bql.svg
|
|
4
|
+
:target: https://pypi.python.org/pypi/fava-nl2bql
|
|
5
|
+
.. image:: https://readthedocs.org/projects/fava-nl2bql/badge
|
|
6
|
+
:target: https://fava-nl2bql.rtfd.io
|
|
7
|
+
|
|
8
|
+
fava-nl2bql
|
|
9
|
+
===========
|
|
10
|
+
|
|
11
|
+
A `Fava <https://beancount.github.io/fava/>`__ extension that translates plain-English questions about
|
|
12
|
+
your ledger into `BQL <https://beancount.github.io/docs/beancount_query_language.html>`__ queries and runs
|
|
13
|
+
them, using a small tuned model instead of hand-written heuristics.
|
|
14
|
+
|
|
15
|
+
This project is a work in progress. See the detailed `Documentation <https://fava-nl2bql.rtfd.io/>`__.
|
|
File without changes
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# This file is execfile()d with the current directory set to its containing dir.
|
|
2
|
+
#
|
|
3
|
+
# This file only contains a selection of the most common options. For a full
|
|
4
|
+
# list see the documentation:
|
|
5
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
import inspect
|
|
10
|
+
import shutil
|
|
11
|
+
|
|
12
|
+
# -- Path setup --------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
__location__ = os.path.join(
|
|
15
|
+
os.getcwd(), os.path.dirname(inspect.getfile(inspect.currentframe()))
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
sys.path.insert(0, os.path.join(__location__, "../src"))
|
|
19
|
+
|
|
20
|
+
# -- Run sphinx-apidoc -------------------------------------------------------
|
|
21
|
+
# This hack is necessary since RTD does not issue `sphinx-apidoc` before running
|
|
22
|
+
# `sphinx-build -b html . _build/html`.
|
|
23
|
+
|
|
24
|
+
from sphinx.ext import apidoc
|
|
25
|
+
|
|
26
|
+
output_dir = os.path.join(__location__, "api")
|
|
27
|
+
module_dir = os.path.join(__location__, "../src/fava_nl2bql")
|
|
28
|
+
try:
|
|
29
|
+
shutil.rmtree(output_dir)
|
|
30
|
+
except FileNotFoundError:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
import sphinx
|
|
35
|
+
|
|
36
|
+
cmd_line = f"sphinx-apidoc --implicit-namespaces -f -o {output_dir} {module_dir}"
|
|
37
|
+
args = cmd_line.split(" ")[1:]
|
|
38
|
+
apidoc.main(args)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
print(f"Running `sphinx-apidoc` failed!\n{e}")
|
|
41
|
+
|
|
42
|
+
# -- General configuration ---------------------------------------------------
|
|
43
|
+
|
|
44
|
+
extensions = [
|
|
45
|
+
"sphinx.ext.autodoc",
|
|
46
|
+
"sphinx.ext.intersphinx",
|
|
47
|
+
"sphinx.ext.todo",
|
|
48
|
+
"sphinx.ext.autosummary",
|
|
49
|
+
"sphinx.ext.viewcode",
|
|
50
|
+
"sphinx.ext.coverage",
|
|
51
|
+
"sphinx.ext.doctest",
|
|
52
|
+
"sphinx.ext.ifconfig",
|
|
53
|
+
"sphinx.ext.mathjax",
|
|
54
|
+
"sphinx.ext.napoleon",
|
|
55
|
+
"sphinx_rtd_theme",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
templates_path = ["_templates"]
|
|
59
|
+
source_suffix = ".rst"
|
|
60
|
+
master_doc = "index"
|
|
61
|
+
|
|
62
|
+
project = "fava-nl2bql"
|
|
63
|
+
copyright = "2026, Patrick Ruckstuhl"
|
|
64
|
+
|
|
65
|
+
version = ""
|
|
66
|
+
release = ""
|
|
67
|
+
|
|
68
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".venv"]
|
|
69
|
+
|
|
70
|
+
pygments_style = "sphinx"
|
|
71
|
+
|
|
72
|
+
# -- Options for HTML output -------------------------------------------------
|
|
73
|
+
|
|
74
|
+
html_theme = "sphinx_rtd_theme"
|
|
75
|
+
html_theme_options = {}
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
from fava_nl2bql import __version__ as version
|
|
79
|
+
except ImportError:
|
|
80
|
+
pass
|
|
81
|
+
else:
|
|
82
|
+
release = version
|
|
83
|
+
|
|
84
|
+
html_static_path = ["_static"]
|
|
85
|
+
html_show_sphinx = False
|
|
86
|
+
htmlhelp_basename = "fava-nl2bql-doc"
|
|
87
|
+
|
|
88
|
+
# -- Options for LaTeX output ------------------------------------------------
|
|
89
|
+
|
|
90
|
+
latex_elements = {}
|
|
91
|
+
|
|
92
|
+
latex_documents = [
|
|
93
|
+
(
|
|
94
|
+
"index",
|
|
95
|
+
"user_guide.tex",
|
|
96
|
+
"fava-nl2bql Documentation",
|
|
97
|
+
"Patrick Ruckstuhl",
|
|
98
|
+
"manual",
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
# -- External mapping --------------------------------------------------------
|
|
103
|
+
python_version = ".".join(map(str, sys.version_info[0:2]))
|
|
104
|
+
intersphinx_mapping = {
|
|
105
|
+
"python": ("https://docs.python.org/" + python_version, None),
|
|
106
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
===========
|
|
2
|
+
fava-nl2bql
|
|
3
|
+
===========
|
|
4
|
+
|
|
5
|
+
A `Fava <https://beancount.github.io/fava/>`__ extension that translates plain-English questions about your
|
|
6
|
+
ledger into `BQL <https://beancount.github.io/docs/beancount_query_language.html>`__ queries and runs them.
|
|
7
|
+
|
|
8
|
+
Contents
|
|
9
|
+
========
|
|
10
|
+
|
|
11
|
+
.. toctree::
|
|
12
|
+
:maxdepth: 3
|
|
13
|
+
|
|
14
|
+
Installation <installation>
|
|
15
|
+
Usage <usage>
|
|
16
|
+
License <license>
|
|
17
|
+
Module Reference <api/modules>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Indices and tables
|
|
21
|
+
==================
|
|
22
|
+
|
|
23
|
+
* :ref:`genindex`
|
|
24
|
+
* :ref:`modindex`
|
|
25
|
+
* :ref:`search`
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Installation
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
As this is released on `PyPI <https://pypi.python.org/pypi/fava-nl2bql/>`__ you can install it with
|
|
5
|
+
|
|
6
|
+
.. code-block:: console
|
|
7
|
+
|
|
8
|
+
pip install fava-nl2bql
|
|
9
|
+
|
|
10
|
+
Then enable it in your beancount file:
|
|
11
|
+
|
|
12
|
+
.. code-block:: text
|
|
13
|
+
|
|
14
|
+
2026-01-01 custom "fava-extension" "fava_nl2bql.extension"
|
|
15
|
+
|
|
16
|
+
See :doc:`usage` for the prerequisites (a local Ollama instance with the translation model pulled)
|
|
17
|
+
and the ``ollama_host``/``model`` config keys.
|