sqlite-export-for-ynab 2.9.6__tar.gz → 2.9.7__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.
Files changed (22) hide show
  1. {sqlite_export_for_ynab-2.9.6/sqlite_export_for_ynab.egg-info → sqlite_export_for_ynab-2.9.7}/PKG-INFO +35 -18
  2. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/README.md +32 -16
  3. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/pyproject.toml +4 -3
  4. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/_main.py +27 -7
  5. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7/sqlite_export_for_ynab.egg-info}/PKG-INFO +35 -18
  6. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab.egg-info/requires.txt +3 -0
  7. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/LICENSE +0 -0
  8. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/setup.cfg +0 -0
  9. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/__init__.py +0 -0
  10. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/__main__.py +0 -0
  11. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/ddl/__init__.py +0 -0
  12. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/ddl/create-relations.sql +0 -0
  13. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/ddl/drop-relations.sql +0 -0
  14. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab/py.typed +0 -0
  15. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab.egg-info/SOURCES.txt +0 -0
  16. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab.egg-info/dependency_links.txt +0 -0
  17. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab.egg-info/entry_points.txt +0 -0
  18. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/sqlite_export_for_ynab.egg-info/top_level.txt +0 -0
  19. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/testing/__init__.py +0 -0
  20. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/testing/fixtures.py +0 -0
  21. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/tests/__init__.py +0 -0
  22. {sqlite_export_for_ynab-2.9.6 → sqlite_export_for_ynab-2.9.7}/tests/_main_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlite_export_for_ynab
3
- Version: 2.9.6
3
+ Version: 2.9.7
4
4
  Summary: SQLite Export for YNAB - Export YNAB Data to SQLite
5
5
  Author-email: Max R <mxr@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3 :: Only
11
11
  Classifier: Programming Language :: Python :: Implementation :: CPython
12
12
  Classifier: Programming Language :: Python :: Implementation :: PyPy
13
- Requires-Python: >=3.12
13
+ Requires-Python: >=3.11
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: aiohttp>=3
@@ -20,17 +20,20 @@ Requires-Dist: asyncio-for-ynab~=1.86.0
20
20
  Requires-Dist: fasteners
21
21
  Requires-Dist: rich>=10
22
22
  Requires-Dist: tenacity
23
+ Requires-Dist: typing-extensions; python_version < "3.12"
23
24
  Dynamic: license-file
24
25
 
25
26
  # sqlite-export-for-ynab
26
27
 
27
- [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main) [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
28
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main)
29
+ [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
28
30
 
29
31
  SQLite Export for YNAB - Export YNAB Budget Data to SQLite
30
32
 
31
33
  ## What This Does
32
34
 
33
- Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your data with any tools compatible with SQLite.
35
+ Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your
36
+ data with any tools compatible with SQLite.
34
37
 
35
38
  ## Installation
36
39
 
@@ -42,7 +45,8 @@ $ pip install sqlite-export-for-ynab
42
45
 
43
46
  ### CLI
44
47
 
45
- Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment variable.
48
+ Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment
49
+ variable.
46
50
 
47
51
  ```console
48
52
  $ export YNAB_PERSONAL_ACCESS_TOKEN="..."
@@ -54,17 +58,22 @@ Run the tool from the terminal to download your plans:
54
58
  $ sqlite-export-for-ynab
55
59
  ```
56
60
 
57
- Running it again will pull only data that changed since the last pull (this is done with [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the `--full-refresh` flag.
58
- Pass `--quiet` to suppress all CLI output, including progress bars.
61
+ Running it again will pull only data that changed since the last pull (this is done with
62
+ [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the
63
+ `--full-refresh` flag. Pass `--quiet` to suppress all CLI output, including progress bars.
59
64
 
60
65
  <a id="db-path"></a>You can specify the DB path with the following options
66
+
61
67
  1. The `--db` flag.
62
- 1. The `XDG_DATA_HOME` variable (see the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
63
- 1. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
68
+ 2. The `XDG_DATA_HOME` variable (see the
69
+ [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that
70
+ case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
71
+ 3. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
64
72
 
65
73
  ### Library
66
74
 
67
- The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use them as follows:
75
+ The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use
76
+ them as follows:
68
77
 
69
78
  ```python
70
79
  import asyncio
@@ -82,11 +91,17 @@ asyncio.run(sync(token, db, full_refresh))
82
91
 
83
92
  ## Relations
84
93
 
85
- The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some additions:
94
+ The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with
95
+ [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some
96
+ additions:
86
97
 
87
- 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
88
- 1. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
89
- 1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields to make querying more ergonomic.
98
+ 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions,
99
+ loan account periodic values).
100
+ 2. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
101
+ 3. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and
102
+ non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions`
103
+ respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields
104
+ to make querying more ergonomic.
90
105
 
91
106
  ## Querying
92
107
 
@@ -96,10 +111,10 @@ You can issue queries with typical SQLite tools. *`sqlite-export-for-ynab` delib
96
111
 
97
112
  You can run the queries from this README using a tool like [`mdq`](https://github.com/yshavit/mdq). For example:
98
113
 
99
- ```console
114
+ ````console
100
115
  $ mdq '```sql dupes' path/to/sqlite-export-for-ynab/README.md -o plain \
101
116
  | sqlite3 path/to/sqlite-export-for-ynab/db.sqlite
102
- ```
117
+ ````
103
118
 
104
119
  The DB path is documented [above](#db-path).
105
120
 
@@ -233,7 +248,7 @@ FROM (
233
248
  ;
234
249
  ```
235
250
 
236
- To estimate taxable interest for a given year[^1]:
251
+ To estimate taxable interest for a given year\[^1\]:
237
252
 
238
253
  ```sql
239
254
  -- Parameters expected by this query:
@@ -591,4 +606,6 @@ WHERE
591
606
  ;
592
607
  ```
593
608
 
594
- [^1]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified professional.
609
+ \[^1\]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax
610
+ advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified
611
+ professional.
@@ -1,12 +1,14 @@
1
1
  # sqlite-export-for-ynab
2
2
 
3
- [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main) [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
3
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main)
4
+ [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
4
5
 
5
6
  SQLite Export for YNAB - Export YNAB Budget Data to SQLite
6
7
 
7
8
  ## What This Does
8
9
 
9
- Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your data with any tools compatible with SQLite.
10
+ Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your
11
+ data with any tools compatible with SQLite.
10
12
 
11
13
  ## Installation
12
14
 
@@ -18,7 +20,8 @@ $ pip install sqlite-export-for-ynab
18
20
 
19
21
  ### CLI
20
22
 
21
- Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment variable.
23
+ Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment
24
+ variable.
22
25
 
23
26
  ```console
24
27
  $ export YNAB_PERSONAL_ACCESS_TOKEN="..."
@@ -30,17 +33,22 @@ Run the tool from the terminal to download your plans:
30
33
  $ sqlite-export-for-ynab
31
34
  ```
32
35
 
33
- Running it again will pull only data that changed since the last pull (this is done with [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the `--full-refresh` flag.
34
- Pass `--quiet` to suppress all CLI output, including progress bars.
36
+ Running it again will pull only data that changed since the last pull (this is done with
37
+ [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the
38
+ `--full-refresh` flag. Pass `--quiet` to suppress all CLI output, including progress bars.
35
39
 
36
40
  <a id="db-path"></a>You can specify the DB path with the following options
41
+
37
42
  1. The `--db` flag.
38
- 1. The `XDG_DATA_HOME` variable (see the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
39
- 1. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
43
+ 2. The `XDG_DATA_HOME` variable (see the
44
+ [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that
45
+ case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
46
+ 3. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
40
47
 
41
48
  ### Library
42
49
 
43
- The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use them as follows:
50
+ The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use
51
+ them as follows:
44
52
 
45
53
  ```python
46
54
  import asyncio
@@ -58,11 +66,17 @@ asyncio.run(sync(token, db, full_refresh))
58
66
 
59
67
  ## Relations
60
68
 
61
- The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some additions:
69
+ The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with
70
+ [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some
71
+ additions:
62
72
 
63
- 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
64
- 1. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
65
- 1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields to make querying more ergonomic.
73
+ 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions,
74
+ loan account periodic values).
75
+ 2. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
76
+ 3. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and
77
+ non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions`
78
+ respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields
79
+ to make querying more ergonomic.
66
80
 
67
81
  ## Querying
68
82
 
@@ -72,10 +86,10 @@ You can issue queries with typical SQLite tools. *`sqlite-export-for-ynab` delib
72
86
 
73
87
  You can run the queries from this README using a tool like [`mdq`](https://github.com/yshavit/mdq). For example:
74
88
 
75
- ```console
89
+ ````console
76
90
  $ mdq '```sql dupes' path/to/sqlite-export-for-ynab/README.md -o plain \
77
91
  | sqlite3 path/to/sqlite-export-for-ynab/db.sqlite
78
- ```
92
+ ````
79
93
 
80
94
  The DB path is documented [above](#db-path).
81
95
 
@@ -209,7 +223,7 @@ FROM (
209
223
  ;
210
224
  ```
211
225
 
212
- To estimate taxable interest for a given year[^1]:
226
+ To estimate taxable interest for a given year\[^1\]:
213
227
 
214
228
  ```sql
215
229
  -- Parameters expected by this query:
@@ -567,4 +581,6 @@ WHERE
567
581
  ;
568
582
  ```
569
583
 
570
- [^1]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified professional.
584
+ \[^1\]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax
585
+ advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified
586
+ professional.
@@ -26,6 +26,7 @@ dependencies = [
26
26
  "fasteners",
27
27
  "rich>=10",
28
28
  "tenacity",
29
+ "typing-extensions; python_version<'3.12'",
29
30
  ]
30
31
  description = "SQLite Export for YNAB - Export YNAB Data to SQLite"
31
32
  keywords = ["ynab", "sqlite", "sql", "budget", "plan", "cli"]
@@ -33,8 +34,8 @@ license = "MIT"
33
34
  license-files = ["LICENSE"]
34
35
  name = "sqlite_export_for_ynab"
35
36
  readme = "README.md"
36
- requires-python = ">=3.12"
37
- version = "2.9.6"
37
+ requires-python = ">=3.11"
38
+ version = "2.9.7"
38
39
 
39
40
  [project.scripts]
40
41
  sqlite-export-for-ynab = "sqlite_export_for_ynab._main:main"
@@ -65,7 +66,7 @@ module = "tests.*"
65
66
  asyncio_default_fixture_loop_scope = "function"
66
67
 
67
68
  [tool.ruff]
68
- target-version = "py312"
69
+ target-version = "py311"
69
70
 
70
71
  [tool.ruff.lint]
71
72
  extend-select = [
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import argparse
4
4
  import asyncio
5
5
  import os
6
+ import sys
6
7
  from contextlib import asynccontextmanager
7
8
  from contextlib import contextmanager
8
9
  from dataclasses import dataclass
@@ -12,14 +13,14 @@ from datetime import datetime
12
13
  from datetime import timedelta
13
14
  from importlib import resources
14
15
  from importlib.metadata import version
15
- from itertools import batched
16
16
  from pathlib import Path
17
17
  from typing import TYPE_CHECKING
18
18
  from typing import Any
19
19
  from typing import Literal
20
+ from typing import TypeVar
21
+ from typing import cast
20
22
  from typing import get_args
21
23
  from typing import overload
22
- from typing import override
23
24
 
24
25
  import aiosqlite
25
26
  import asyncio_for_ynab # noqa: F401
@@ -55,11 +56,30 @@ if TYPE_CHECKING:
55
56
  from collections.abc import AsyncIterator
56
57
  from collections.abc import Awaitable
57
58
  from collections.abc import Callable
59
+ from collections.abc import Iterable
58
60
  from collections.abc import Iterator
59
61
  from collections.abc import Sequence
60
62
 
63
+ _T = TypeVar("_T")
64
+
65
+ if sys.version_info >= (3, 12): # pragma: >=3.12 cover
66
+ from itertools import batched
67
+ from typing import override
68
+ else: # pragma: <3.12 cover
69
+ from itertools import islice
70
+
71
+ from typing_extensions import override
72
+
73
+ def batched(iterable: Iterable[_T], n: int) -> Iterator[tuple[_T, ...]]:
74
+ it = iter(iterable)
75
+ while batch := tuple(islice(it, n)):
76
+ yield batch
77
+
78
+
61
79
  try:
62
- from rich.progress import MofNCompleteColumn
80
+ from rich.progress import (
81
+ MofNCompleteColumn, # pyright: ignore[reportAssignmentType]
82
+ )
63
83
  # https://github.com/benleb/surepy/issues/240
64
84
  except ImportError: # pragma: no cover
65
85
  from rich.progress import ProgressColumn
@@ -157,9 +177,9 @@ async def async_main(
157
177
  )
158
178
 
159
179
  args = parser.parse_args(argv)
160
- db: Path = args.db
161
- full_refresh: bool = args.full_refresh
162
- quiet: bool = args.quiet
180
+ db = cast("Path", args.db)
181
+ full_refresh = cast("bool", args.full_refresh)
182
+ quiet = cast("bool", args.quiet)
163
183
 
164
184
  token = resolve_token(token_override)
165
185
 
@@ -674,7 +694,7 @@ class _ProgressYnab:
674
694
  task_id: TaskID
675
695
 
676
696
  @retry(stop=stop_after_attempt(3))
677
- async def get[T](self, endpoint: Callable[..., Awaitable[T]]) -> T:
697
+ async def get(self, endpoint: Callable[..., Awaitable[_T]]) -> _T:
678
698
  try:
679
699
  return await endpoint(
680
700
  plan_id=self.plan_id,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlite_export_for_ynab
3
- Version: 2.9.6
3
+ Version: 2.9.7
4
4
  Summary: SQLite Export for YNAB - Export YNAB Data to SQLite
5
5
  Author-email: Max R <mxr@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3 :: Only
11
11
  Classifier: Programming Language :: Python :: Implementation :: CPython
12
12
  Classifier: Programming Language :: Python :: Implementation :: PyPy
13
- Requires-Python: >=3.12
13
+ Requires-Python: >=3.11
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: aiohttp>=3
@@ -20,17 +20,20 @@ Requires-Dist: asyncio-for-ynab~=1.86.0
20
20
  Requires-Dist: fasteners
21
21
  Requires-Dist: rich>=10
22
22
  Requires-Dist: tenacity
23
+ Requires-Dist: typing-extensions; python_version < "3.12"
23
24
  Dynamic: license-file
24
25
 
25
26
  # sqlite-export-for-ynab
26
27
 
27
- [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main) [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
28
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/mxr/sqlite-export-for-ynab/main.svg)](https://results.pre-commit.ci/latest/github/mxr/sqlite-export-for-ynab/main)
29
+ [![codecov](https://codecov.io/github/mxr/sqlite-export-for-ynab/graph/badge.svg?token=NVCP6RDKSH)](https://codecov.io/github/mxr/sqlite-export-for-ynab)
28
30
 
29
31
  SQLite Export for YNAB - Export YNAB Budget Data to SQLite
30
32
 
31
33
  ## What This Does
32
34
 
33
- Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your data with any tools compatible with SQLite.
35
+ Export all your [YNAB](https://ynab.com/) plans to a local [SQLite](https://www.sqlite.org/) DB. Then you can query your
36
+ data with any tools compatible with SQLite.
34
37
 
35
38
  ## Installation
36
39
 
@@ -42,7 +45,8 @@ $ pip install sqlite-export-for-ynab
42
45
 
43
46
  ### CLI
44
47
 
45
- Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment variable.
48
+ Provision a [YNAB Personal Access Token](https://api.ynab.com/#personal-access-tokens) and save it as an environment
49
+ variable.
46
50
 
47
51
  ```console
48
52
  $ export YNAB_PERSONAL_ACCESS_TOKEN="..."
@@ -54,17 +58,22 @@ Run the tool from the terminal to download your plans:
54
58
  $ sqlite-export-for-ynab
55
59
  ```
56
60
 
57
- Running it again will pull only data that changed since the last pull (this is done with [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the `--full-refresh` flag.
58
- Pass `--quiet` to suppress all CLI output, including progress bars.
61
+ Running it again will pull only data that changed since the last pull (this is done with
62
+ [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the
63
+ `--full-refresh` flag. Pass `--quiet` to suppress all CLI output, including progress bars.
59
64
 
60
65
  <a id="db-path"></a>You can specify the DB path with the following options
66
+
61
67
  1. The `--db` flag.
62
- 1. The `XDG_DATA_HOME` variable (see the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
63
- 1. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
68
+ 2. The `XDG_DATA_HOME` variable (see the
69
+ [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/index.html)). In that
70
+ case the DB is saved in `"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite`.
71
+ 3. If neither is set, the DB is saved in `~/.local/share/sqlite-export-for-ynab/db.sqlite`.
64
72
 
65
73
  ### Library
66
74
 
67
- The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use them as follows:
75
+ The library exposes the package `sqlite_export_for_ynab` and two functions - `default_db_path` and `sync`. You can use
76
+ them as follows:
68
77
 
69
78
  ```python
70
79
  import asyncio
@@ -82,11 +91,17 @@ asyncio.run(sync(token, db, full_refresh))
82
91
 
83
92
  ## Relations
84
93
 
85
- The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some additions:
94
+ The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/create-relations.sql). They are 1:1 with
95
+ [YNAB's OpenAPI Spec](https://api.ynab.com/papi/open_api_spec.yaml) (ex: transactions, accounts, etc) with some
96
+ additions:
86
97
 
87
- 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
88
- 1. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
89
- 1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields to make querying more ergonomic.
98
+ 1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions,
99
+ loan account periodic values).
100
+ 2. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
101
+ 3. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and
102
+ non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions`
103
+ respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields
104
+ to make querying more ergonomic.
90
105
 
91
106
  ## Querying
92
107
 
@@ -96,10 +111,10 @@ You can issue queries with typical SQLite tools. *`sqlite-export-for-ynab` delib
96
111
 
97
112
  You can run the queries from this README using a tool like [`mdq`](https://github.com/yshavit/mdq). For example:
98
113
 
99
- ```console
114
+ ````console
100
115
  $ mdq '```sql dupes' path/to/sqlite-export-for-ynab/README.md -o plain \
101
116
  | sqlite3 path/to/sqlite-export-for-ynab/db.sqlite
102
- ```
117
+ ````
103
118
 
104
119
  The DB path is documented [above](#db-path).
105
120
 
@@ -233,7 +248,7 @@ FROM (
233
248
  ;
234
249
  ```
235
250
 
236
- To estimate taxable interest for a given year[^1]:
251
+ To estimate taxable interest for a given year\[^1\]:
237
252
 
238
253
  ```sql
239
254
  -- Parameters expected by this query:
@@ -591,4 +606,6 @@ WHERE
591
606
  ;
592
607
  ```
593
608
 
594
- [^1]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified professional.
609
+ \[^1\]: This query is a rough estimate based on YNAB data and optional user inputs. It is not financial advice, tax
610
+ advice, or a substitute for Forms 1099-INT, brokerage statements, bank records, or guidance from a qualified
611
+ professional.
@@ -5,3 +5,6 @@ asyncio-for-ynab~=1.86.0
5
5
  fasteners
6
6
  rich>=10
7
7
  tenacity
8
+
9
+ [:python_version < "3.12"]
10
+ typing-extensions