ynab-cli 0.3.0__py3-none-any.whl
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.
- ynab_cli/__init__.py +0 -0
- ynab_cli/adapters/__init__.py +0 -0
- ynab_cli/adapters/rich/__init__.py +0 -0
- ynab_cli/adapters/rich/io.py +38 -0
- ynab_cli/adapters/textual/__init__.py +0 -0
- ynab_cli/adapters/textual/io.py +62 -0
- ynab_cli/adapters/ynab/__init__.py +8 -0
- ynab_cli/adapters/ynab/api/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/accounts/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/accounts/create_account.py +186 -0
- ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py +177 -0
- ynab_cli/adapters/ynab/api/accounts/get_accounts.py +184 -0
- ynab_cli/adapters/ynab/api/budgets/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py +188 -0
- ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py +163 -0
- ynab_cli/adapters/ynab/api/budgets/get_budgets.py +171 -0
- ynab_cli/adapters/ynab/api/categories/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/categories/get_categories.py +188 -0
- ynab_cli/adapters/ynab/api/categories/get_category_by_id.py +180 -0
- ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py +194 -0
- ynab_cli/adapters/ynab/api/categories/update_category.py +199 -0
- ynab_cli/adapters/ynab/api/categories/update_month_category.py +213 -0
- ynab_cli/adapters/ynab/api/months/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/months/get_budget_month.py +177 -0
- ynab_cli/adapters/ynab/api/months/get_budget_months.py +184 -0
- ynab_cli/adapters/ynab/api/payee_locations/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py +176 -0
- ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py +163 -0
- ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py +176 -0
- ynab_cli/adapters/ynab/api/payees/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py +176 -0
- ynab_cli/adapters/ynab/api/payees/get_payees.py +184 -0
- ynab_cli/adapters/ynab/api/payees/update_payee.py +199 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py +186 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py +176 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py +176 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py +184 -0
- ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py +199 -0
- ynab_cli/adapters/ynab/api/transactions/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/transactions/create_transaction.py +202 -0
- ynab_cli/adapters/ynab/api/transactions/delete_transaction.py +176 -0
- ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py +176 -0
- ynab_cli/adapters/ynab/api/transactions/get_transactions.py +227 -0
- ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py +236 -0
- ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py +236 -0
- ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py +236 -0
- ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py +236 -0
- ynab_cli/adapters/ynab/api/transactions/import_transactions.py +183 -0
- ynab_cli/adapters/ynab/api/transactions/update_transaction.py +199 -0
- ynab_cli/adapters/ynab/api/transactions/update_transactions.py +177 -0
- ynab_cli/adapters/ynab/api/user/__init__.py +1 -0
- ynab_cli/adapters/ynab/api/user/get_user.py +130 -0
- ynab_cli/adapters/ynab/client.py +268 -0
- ynab_cli/adapters/ynab/errors.py +16 -0
- ynab_cli/adapters/ynab/models/__init__.py +229 -0
- ynab_cli/adapters/ynab/models/account.py +345 -0
- ynab_cli/adapters/ynab/models/account_response.py +65 -0
- ynab_cli/adapters/ynab/models/account_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/account_type.py +23 -0
- ynab_cli/adapters/ynab/models/accounts_response.py +65 -0
- ynab_cli/adapters/ynab/models/accounts_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/budget_detail.py +405 -0
- ynab_cli/adapters/ynab/models/budget_detail_response.py +65 -0
- ynab_cli/adapters/ynab/models/budget_detail_response_data.py +73 -0
- ynab_cli/adapters/ynab/models/budget_settings.py +115 -0
- ynab_cli/adapters/ynab/models/budget_settings_response.py +65 -0
- ynab_cli/adapters/ynab/models/budget_settings_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/budget_summary.py +216 -0
- ynab_cli/adapters/ynab/models/budget_summary_response.py +65 -0
- ynab_cli/adapters/ynab/models/budget_summary_response_data.py +91 -0
- ynab_cli/adapters/ynab/models/bulk_response.py +65 -0
- ynab_cli/adapters/ynab/models/bulk_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py +68 -0
- ynab_cli/adapters/ynab/models/bulk_transactions.py +75 -0
- ynab_cli/adapters/ynab/models/categories_response.py +65 -0
- ynab_cli/adapters/ynab/models/categories_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/category.py +519 -0
- ynab_cli/adapters/ynab/models/category_goal_type_type_1.py +15 -0
- ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py +15 -0
- ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py +15 -0
- ynab_cli/adapters/ynab/models/category_group.py +85 -0
- ynab_cli/adapters/ynab/models/category_group_with_categories.py +108 -0
- ynab_cli/adapters/ynab/models/category_response.py +65 -0
- ynab_cli/adapters/ynab/models/category_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/currency_format_type_0.py +117 -0
- ynab_cli/adapters/ynab/models/date_format_type_0.py +61 -0
- ynab_cli/adapters/ynab/models/error_detail.py +75 -0
- ynab_cli/adapters/ynab/models/error_response.py +65 -0
- ynab_cli/adapters/ynab/models/existing_transaction.py +322 -0
- ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py +12 -0
- ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py +12 -0
- ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py +12 -0
- ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py +12 -0
- ynab_cli/adapters/ynab/models/get_transactions_type.py +12 -0
- ynab_cli/adapters/ynab/models/hybrid_transaction.py +567 -0
- ynab_cli/adapters/ynab/models/hybrid_transaction_type.py +12 -0
- ynab_cli/adapters/ynab/models/hybrid_transactions_response.py +65 -0
- ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py +84 -0
- ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py +44 -0
- ynab_cli/adapters/ynab/models/month_detail.py +168 -0
- ynab_cli/adapters/ynab/models/month_detail_response.py +65 -0
- ynab_cli/adapters/ynab/models/month_detail_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/month_summaries_response.py +65 -0
- ynab_cli/adapters/ynab/models/month_summaries_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/month_summary.py +145 -0
- ynab_cli/adapters/ynab/models/new_transaction.py +352 -0
- ynab_cli/adapters/ynab/models/patch_category_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/patch_payee_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py +73 -0
- ynab_cli/adapters/ynab/models/payee.py +100 -0
- ynab_cli/adapters/ynab/models/payee_location.py +93 -0
- ynab_cli/adapters/ynab/models/payee_location_response.py +65 -0
- ynab_cli/adapters/ynab/models/payee_location_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/payee_locations_response.py +65 -0
- ynab_cli/adapters/ynab/models/payee_locations_response_data.py +73 -0
- ynab_cli/adapters/ynab/models/payee_response.py +65 -0
- ynab_cli/adapters/ynab/models/payee_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/payees_response.py +65 -0
- ynab_cli/adapters/ynab/models/payees_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/post_account_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/post_transactions_wrapper.py +91 -0
- ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/put_transaction_wrapper.py +65 -0
- ynab_cli/adapters/ynab/models/save_account.py +77 -0
- ynab_cli/adapters/ynab/models/save_category.py +129 -0
- ynab_cli/adapters/ynab/models/save_category_response.py +65 -0
- ynab_cli/adapters/ynab/models/save_category_response_data.py +73 -0
- ynab_cli/adapters/ynab/models/save_month_category.py +59 -0
- ynab_cli/adapters/ynab/models/save_payee.py +59 -0
- ynab_cli/adapters/ynab/models/save_payee_response.py +65 -0
- ynab_cli/adapters/ynab/models/save_payee_response_data.py +73 -0
- ynab_cli/adapters/ynab/models/save_scheduled_transaction.py +269 -0
- ynab_cli/adapters/ynab/models/save_sub_transaction.py +166 -0
- ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py +366 -0
- ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py +322 -0
- ynab_cli/adapters/ynab/models/save_transactions_response.py +65 -0
- ynab_cli/adapters/ynab/models/save_transactions_response_data.py +123 -0
- ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py +238 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py +381 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py +23 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_response.py +65 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py +310 -0
- ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py +23 -0
- ynab_cli/adapters/ynab/models/scheduled_transactions_response.py +65 -0
- ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/sub_transaction.py +259 -0
- ynab_cli/adapters/ynab/models/transaction_cleared_status.py +13 -0
- ynab_cli/adapters/ynab/models/transaction_detail.py +570 -0
- ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py +16 -0
- ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py +16 -0
- ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py +16 -0
- ynab_cli/adapters/ynab/models/transaction_response.py +65 -0
- ynab_cli/adapters/ynab/models/transaction_response_data.py +65 -0
- ynab_cli/adapters/ynab/models/transaction_summary.py +499 -0
- ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py +18 -0
- ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py +18 -0
- ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py +18 -0
- ynab_cli/adapters/ynab/models/transactions_import_response.py +65 -0
- ynab_cli/adapters/ynab/models/transactions_import_response_data.py +59 -0
- ynab_cli/adapters/ynab/models/transactions_response.py +65 -0
- ynab_cli/adapters/ynab/models/transactions_response_data.py +81 -0
- ynab_cli/adapters/ynab/models/user.py +60 -0
- ynab_cli/adapters/ynab/models/user_response.py +65 -0
- ynab_cli/adapters/ynab/models/user_response_data.py +65 -0
- ynab_cli/adapters/ynab/types.py +46 -0
- ynab_cli/adapters/ynab/util.py +78 -0
- ynab_cli/domain/__init__.py +0 -0
- ynab_cli/domain/constants.py +3 -0
- ynab_cli/domain/models/__init__.py +0 -0
- ynab_cli/domain/models/rules.py +37 -0
- ynab_cli/domain/ports/__init__.py +5 -0
- ynab_cli/domain/ports/io.py +63 -0
- ynab_cli/domain/settings.py +16 -0
- ynab_cli/domain/use_cases/__init__.py +0 -0
- ynab_cli/domain/use_cases/categories.py +105 -0
- ynab_cli/domain/use_cases/payees.py +232 -0
- ynab_cli/domain/use_cases/transactions.py +93 -0
- ynab_cli/host/__init__.py +14 -0
- ynab_cli/host/cli.py +37 -0
- ynab_cli/host/click/__init__.py +0 -0
- ynab_cli/host/click/cli.py +44 -0
- ynab_cli/host/click/commands/__init__.py +0 -0
- ynab_cli/host/click/commands/categories.py +92 -0
- ynab_cli/host/click/commands/payees.py +157 -0
- ynab_cli/host/click/commands/rich/__init__.py +0 -0
- ynab_cli/host/click/commands/rich/progress_table.py +37 -0
- ynab_cli/host/click/commands/transactions.py +76 -0
- ynab_cli/host/constants.py +3 -0
- ynab_cli/host/textual/__init__.py +0 -0
- ynab_cli/host/textual/app.py +98 -0
- ynab_cli/host/textual/app.tcss +47 -0
- ynab_cli/host/textual/cli.py +42 -0
- ynab_cli/host/textual/widgets/__init__.py +58 -0
- ynab_cli/host/textual/widgets/categories.py +90 -0
- ynab_cli/host/textual/widgets/payees.py +154 -0
- ynab_cli/host/textual/widgets/transactions.py +89 -0
- ynab_cli/py.typed +0 -0
- ynab_cli-0.3.0.dist-info/METADATA +102 -0
- ynab_cli-0.3.0.dist-info/RECORD +206 -0
- ynab_cli-0.3.0.dist-info/WHEEL +4 -0
- ynab_cli-0.3.0.dist-info/entry_points.txt +2 -0
- ynab_cli-0.3.0.dist-info/licenses/LICENSE.md +21 -0
ynab_cli/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from rich import progress as rich_progress
|
|
2
|
+
from rich import prompt as rich_prompt
|
|
3
|
+
from typing_extensions import override
|
|
4
|
+
|
|
5
|
+
from ynab_cli.domain.ports.io import IO, Progress
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RichProgress(Progress):
|
|
9
|
+
def __init__(self, progress_info: tuple[rich_progress.Progress, rich_progress.TaskID]) -> None:
|
|
10
|
+
self._progress, self._task_id = progress_info
|
|
11
|
+
|
|
12
|
+
@override
|
|
13
|
+
async def update(
|
|
14
|
+
self, *, total: float | None = None, completed: float | None = None, advance: float | None = None
|
|
15
|
+
) -> None:
|
|
16
|
+
task = self._progress.tasks[self._task_id]
|
|
17
|
+
if not task.started:
|
|
18
|
+
self._progress.start_task(self._task_id)
|
|
19
|
+
self._progress.update(self._task_id, total=total, completed=completed, advance=advance)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RichIO(IO):
|
|
23
|
+
def __init__(self, progress_info: tuple[rich_progress.Progress, rich_progress.TaskID]) -> None:
|
|
24
|
+
progress, _ = progress_info
|
|
25
|
+
self._progress = progress
|
|
26
|
+
self.progress = RichProgress(progress_info)
|
|
27
|
+
|
|
28
|
+
@override
|
|
29
|
+
async def prompt(self, prompt: str, password: bool = False) -> str:
|
|
30
|
+
try:
|
|
31
|
+
self._progress.stop()
|
|
32
|
+
return rich_prompt.Prompt.ask(prompt, console=self._progress.console, password=password)
|
|
33
|
+
finally:
|
|
34
|
+
self._progress.start()
|
|
35
|
+
|
|
36
|
+
@override
|
|
37
|
+
async def print(self, message: str) -> None:
|
|
38
|
+
return self._progress.console.print(message)
|
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from textual import on
|
|
4
|
+
from textual.app import App, ComposeResult
|
|
5
|
+
from textual.containers import Vertical
|
|
6
|
+
from textual.screen import ModalScreen
|
|
7
|
+
from textual.widgets import Input, Label, Log, ProgressBar
|
|
8
|
+
from typing_extensions import override
|
|
9
|
+
|
|
10
|
+
from ynab_cli.domain.ports.io import IO, Progress
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TextualProgress(Progress):
|
|
14
|
+
def __init__(self, progress_bar: ProgressBar) -> None:
|
|
15
|
+
self._progress_bar = progress_bar
|
|
16
|
+
|
|
17
|
+
@override
|
|
18
|
+
async def update(
|
|
19
|
+
self, *, total: float | None = None, completed: float | None = None, advance: float | None = None
|
|
20
|
+
) -> None:
|
|
21
|
+
kwargs = {}
|
|
22
|
+
if total is not None:
|
|
23
|
+
kwargs["total"] = total
|
|
24
|
+
if completed is not None:
|
|
25
|
+
kwargs["progress"] = completed
|
|
26
|
+
if advance is not None:
|
|
27
|
+
kwargs["advance"] = advance
|
|
28
|
+
self._progress_bar.update(**kwargs)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class IOScreen(ModalScreen[str]):
|
|
32
|
+
"""A simple modal screen which asks for user input."""
|
|
33
|
+
|
|
34
|
+
def __init__(self, prompt: str, password: bool, *args: Any, **kwargs: Any) -> None:
|
|
35
|
+
super().__init__(*args, **kwargs)
|
|
36
|
+
self._prompt = prompt
|
|
37
|
+
self._password = password
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
def compose(self) -> ComposeResult:
|
|
41
|
+
with Vertical():
|
|
42
|
+
yield Label(self._prompt)
|
|
43
|
+
yield Input(password=self._password)
|
|
44
|
+
|
|
45
|
+
@on(Input.Submitted)
|
|
46
|
+
def return_response(self, event: Input.Submitted) -> None:
|
|
47
|
+
self.dismiss(event.value)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TextualWorkerIO(IO):
|
|
51
|
+
def __init__(self, app: App[Any], log: Log, progress_bar: ProgressBar) -> None:
|
|
52
|
+
self._app = app
|
|
53
|
+
self._log = log
|
|
54
|
+
self.progress = TextualProgress(progress_bar)
|
|
55
|
+
|
|
56
|
+
@override
|
|
57
|
+
async def prompt(self, prompt: str, password: bool = False) -> str:
|
|
58
|
+
return await self._app.push_screen_wait(IOScreen(prompt, password))
|
|
59
|
+
|
|
60
|
+
@override
|
|
61
|
+
async def print(self, message: str) -> None:
|
|
62
|
+
self._log.write_line(message)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains methods for accessing the API"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains endpoint functions for accessing the API"""
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from ynab_cli.adapters.ynab import errors
|
|
7
|
+
from ynab_cli.adapters.ynab.client import AuthenticatedClient, Client
|
|
8
|
+
from ynab_cli.adapters.ynab.models.account_response import AccountResponse
|
|
9
|
+
from ynab_cli.adapters.ynab.models.error_response import ErrorResponse
|
|
10
|
+
from ynab_cli.adapters.ynab.models.post_account_wrapper import PostAccountWrapper
|
|
11
|
+
from ynab_cli.adapters.ynab.types import Response
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_kwargs(
|
|
15
|
+
budget_id: str,
|
|
16
|
+
*,
|
|
17
|
+
body: PostAccountWrapper,
|
|
18
|
+
) -> dict[str, Any]:
|
|
19
|
+
headers: dict[str, Any] = {}
|
|
20
|
+
|
|
21
|
+
_kwargs: dict[str, Any] = {
|
|
22
|
+
"method": "post",
|
|
23
|
+
"url": f"/budgets/{budget_id}/accounts",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_body = body.to_dict()
|
|
27
|
+
|
|
28
|
+
_kwargs["json"] = _body
|
|
29
|
+
headers["Content-Type"] = "application/json"
|
|
30
|
+
|
|
31
|
+
_kwargs["headers"] = headers
|
|
32
|
+
return _kwargs
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _parse_response(
|
|
36
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
37
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
38
|
+
if response.status_code == 201:
|
|
39
|
+
response_201 = AccountResponse.from_dict(response.json())
|
|
40
|
+
|
|
41
|
+
return response_201
|
|
42
|
+
if response.status_code == 400:
|
|
43
|
+
response_400 = ErrorResponse.from_dict(response.json())
|
|
44
|
+
|
|
45
|
+
return response_400
|
|
46
|
+
if client.raise_on_unexpected_status:
|
|
47
|
+
raise errors.UnexpectedStatusError(response.status_code, response.content)
|
|
48
|
+
else:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _build_response(
|
|
53
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
54
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
55
|
+
return Response(
|
|
56
|
+
status_code=HTTPStatus(response.status_code),
|
|
57
|
+
content=response.content,
|
|
58
|
+
headers=response.headers,
|
|
59
|
+
parsed=_parse_response(client=client, response=response),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def sync_detailed(
|
|
64
|
+
budget_id: str,
|
|
65
|
+
*,
|
|
66
|
+
client: AuthenticatedClient | Client,
|
|
67
|
+
body: PostAccountWrapper,
|
|
68
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
69
|
+
"""Create a new account
|
|
70
|
+
|
|
71
|
+
Creates a new account
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
budget_id (str):
|
|
75
|
+
body (PostAccountWrapper):
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
79
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Response[Union[AccountResponse, ErrorResponse]]
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
kwargs = _get_kwargs(
|
|
86
|
+
budget_id=budget_id,
|
|
87
|
+
body=body,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
response = client.get_httpx_client().request(
|
|
91
|
+
**kwargs,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return _build_response(client=client, response=response)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def sync(
|
|
98
|
+
budget_id: str,
|
|
99
|
+
*,
|
|
100
|
+
client: AuthenticatedClient | Client,
|
|
101
|
+
body: PostAccountWrapper,
|
|
102
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
103
|
+
"""Create a new account
|
|
104
|
+
|
|
105
|
+
Creates a new account
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
budget_id (str):
|
|
109
|
+
body (PostAccountWrapper):
|
|
110
|
+
|
|
111
|
+
Raises:
|
|
112
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
113
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Union[AccountResponse, ErrorResponse]
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
return sync_detailed(
|
|
120
|
+
budget_id=budget_id,
|
|
121
|
+
client=client,
|
|
122
|
+
body=body,
|
|
123
|
+
).parsed
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
async def asyncio_detailed(
|
|
127
|
+
budget_id: str,
|
|
128
|
+
*,
|
|
129
|
+
client: AuthenticatedClient | Client,
|
|
130
|
+
body: PostAccountWrapper,
|
|
131
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
132
|
+
"""Create a new account
|
|
133
|
+
|
|
134
|
+
Creates a new account
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
budget_id (str):
|
|
138
|
+
body (PostAccountWrapper):
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
142
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Response[Union[AccountResponse, ErrorResponse]]
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
kwargs = _get_kwargs(
|
|
149
|
+
budget_id=budget_id,
|
|
150
|
+
body=body,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
154
|
+
|
|
155
|
+
return _build_response(client=client, response=response)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
async def asyncio(
|
|
159
|
+
budget_id: str,
|
|
160
|
+
*,
|
|
161
|
+
client: AuthenticatedClient | Client,
|
|
162
|
+
body: PostAccountWrapper,
|
|
163
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
164
|
+
"""Create a new account
|
|
165
|
+
|
|
166
|
+
Creates a new account
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
budget_id (str):
|
|
170
|
+
body (PostAccountWrapper):
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
174
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Union[AccountResponse, ErrorResponse]
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
await asyncio_detailed(
|
|
182
|
+
budget_id=budget_id,
|
|
183
|
+
client=client,
|
|
184
|
+
body=body,
|
|
185
|
+
)
|
|
186
|
+
).parsed
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ynab_cli.adapters.ynab import errors
|
|
8
|
+
from ynab_cli.adapters.ynab.client import AuthenticatedClient, Client
|
|
9
|
+
from ynab_cli.adapters.ynab.models.account_response import AccountResponse
|
|
10
|
+
from ynab_cli.adapters.ynab.models.error_response import ErrorResponse
|
|
11
|
+
from ynab_cli.adapters.ynab.types import Response
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_kwargs(
|
|
15
|
+
budget_id: str,
|
|
16
|
+
account_id: UUID,
|
|
17
|
+
) -> dict[str, Any]:
|
|
18
|
+
_kwargs: dict[str, Any] = {
|
|
19
|
+
"method": "get",
|
|
20
|
+
"url": f"/budgets/{budget_id}/accounts/{account_id}",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return _kwargs
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _parse_response(
|
|
27
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
28
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
29
|
+
if response.status_code == 200:
|
|
30
|
+
response_200 = AccountResponse.from_dict(response.json())
|
|
31
|
+
|
|
32
|
+
return response_200
|
|
33
|
+
if response.status_code == 404:
|
|
34
|
+
response_404 = ErrorResponse.from_dict(response.json())
|
|
35
|
+
|
|
36
|
+
return response_404
|
|
37
|
+
if client.raise_on_unexpected_status:
|
|
38
|
+
raise errors.UnexpectedStatusError(response.status_code, response.content)
|
|
39
|
+
else:
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _build_response(
|
|
44
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
45
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
46
|
+
return Response(
|
|
47
|
+
status_code=HTTPStatus(response.status_code),
|
|
48
|
+
content=response.content,
|
|
49
|
+
headers=response.headers,
|
|
50
|
+
parsed=_parse_response(client=client, response=response),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def sync_detailed(
|
|
55
|
+
budget_id: str,
|
|
56
|
+
account_id: UUID,
|
|
57
|
+
*,
|
|
58
|
+
client: AuthenticatedClient | Client,
|
|
59
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
60
|
+
"""Single account
|
|
61
|
+
|
|
62
|
+
Returns a single account
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
budget_id (str):
|
|
66
|
+
account_id (UUID):
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
70
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Response[Union[AccountResponse, ErrorResponse]]
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
kwargs = _get_kwargs(
|
|
77
|
+
budget_id=budget_id,
|
|
78
|
+
account_id=account_id,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
response = client.get_httpx_client().request(
|
|
82
|
+
**kwargs,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return _build_response(client=client, response=response)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def sync(
|
|
89
|
+
budget_id: str,
|
|
90
|
+
account_id: UUID,
|
|
91
|
+
*,
|
|
92
|
+
client: AuthenticatedClient | Client,
|
|
93
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
94
|
+
"""Single account
|
|
95
|
+
|
|
96
|
+
Returns a single account
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
budget_id (str):
|
|
100
|
+
account_id (UUID):
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
104
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Union[AccountResponse, ErrorResponse]
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
return sync_detailed(
|
|
111
|
+
budget_id=budget_id,
|
|
112
|
+
account_id=account_id,
|
|
113
|
+
client=client,
|
|
114
|
+
).parsed
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
async def asyncio_detailed(
|
|
118
|
+
budget_id: str,
|
|
119
|
+
account_id: UUID,
|
|
120
|
+
*,
|
|
121
|
+
client: AuthenticatedClient | Client,
|
|
122
|
+
) -> Response[AccountResponse | ErrorResponse]:
|
|
123
|
+
"""Single account
|
|
124
|
+
|
|
125
|
+
Returns a single account
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
budget_id (str):
|
|
129
|
+
account_id (UUID):
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
133
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Response[Union[AccountResponse, ErrorResponse]]
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
kwargs = _get_kwargs(
|
|
140
|
+
budget_id=budget_id,
|
|
141
|
+
account_id=account_id,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
145
|
+
|
|
146
|
+
return _build_response(client=client, response=response)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
async def asyncio(
|
|
150
|
+
budget_id: str,
|
|
151
|
+
account_id: UUID,
|
|
152
|
+
*,
|
|
153
|
+
client: AuthenticatedClient | Client,
|
|
154
|
+
) -> AccountResponse | ErrorResponse | None:
|
|
155
|
+
"""Single account
|
|
156
|
+
|
|
157
|
+
Returns a single account
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
budget_id (str):
|
|
161
|
+
account_id (UUID):
|
|
162
|
+
|
|
163
|
+
Raises:
|
|
164
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
165
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Union[AccountResponse, ErrorResponse]
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
await asyncio_detailed(
|
|
173
|
+
budget_id=budget_id,
|
|
174
|
+
account_id=account_id,
|
|
175
|
+
client=client,
|
|
176
|
+
)
|
|
177
|
+
).parsed
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from ynab_cli.adapters.ynab import errors
|
|
7
|
+
from ynab_cli.adapters.ynab.client import AuthenticatedClient, Client
|
|
8
|
+
from ynab_cli.adapters.ynab.models.accounts_response import AccountsResponse
|
|
9
|
+
from ynab_cli.adapters.ynab.models.error_response import ErrorResponse
|
|
10
|
+
from ynab_cli.adapters.ynab.types import UNSET, Response, Unset
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _get_kwargs(
|
|
14
|
+
budget_id: str,
|
|
15
|
+
*,
|
|
16
|
+
last_knowledge_of_server: Unset | int = UNSET,
|
|
17
|
+
) -> dict[str, Any]:
|
|
18
|
+
params: dict[str, Any] = {}
|
|
19
|
+
|
|
20
|
+
params["last_knowledge_of_server"] = last_knowledge_of_server
|
|
21
|
+
|
|
22
|
+
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
|
23
|
+
|
|
24
|
+
_kwargs: dict[str, Any] = {
|
|
25
|
+
"method": "get",
|
|
26
|
+
"url": f"/budgets/{budget_id}/accounts",
|
|
27
|
+
"params": params,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return _kwargs
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse_response(
|
|
34
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
35
|
+
) -> AccountsResponse | ErrorResponse | None:
|
|
36
|
+
if response.status_code == 200:
|
|
37
|
+
response_200 = AccountsResponse.from_dict(response.json())
|
|
38
|
+
|
|
39
|
+
return response_200
|
|
40
|
+
if response.status_code == 404:
|
|
41
|
+
response_404 = ErrorResponse.from_dict(response.json())
|
|
42
|
+
|
|
43
|
+
return response_404
|
|
44
|
+
if client.raise_on_unexpected_status:
|
|
45
|
+
raise errors.UnexpectedStatusError(response.status_code, response.content)
|
|
46
|
+
else:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _build_response(
|
|
51
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
52
|
+
) -> Response[AccountsResponse | ErrorResponse]:
|
|
53
|
+
return Response(
|
|
54
|
+
status_code=HTTPStatus(response.status_code),
|
|
55
|
+
content=response.content,
|
|
56
|
+
headers=response.headers,
|
|
57
|
+
parsed=_parse_response(client=client, response=response),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def sync_detailed(
|
|
62
|
+
budget_id: str,
|
|
63
|
+
*,
|
|
64
|
+
client: AuthenticatedClient | Client,
|
|
65
|
+
last_knowledge_of_server: Unset | int = UNSET,
|
|
66
|
+
) -> Response[AccountsResponse | ErrorResponse]:
|
|
67
|
+
"""Account list
|
|
68
|
+
|
|
69
|
+
Returns all accounts
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
budget_id (str):
|
|
73
|
+
last_knowledge_of_server (Union[Unset, int]):
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
77
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Response[Union[AccountsResponse, ErrorResponse]]
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
kwargs = _get_kwargs(
|
|
84
|
+
budget_id=budget_id,
|
|
85
|
+
last_knowledge_of_server=last_knowledge_of_server,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
response = client.get_httpx_client().request(
|
|
89
|
+
**kwargs,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return _build_response(client=client, response=response)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def sync(
|
|
96
|
+
budget_id: str,
|
|
97
|
+
*,
|
|
98
|
+
client: AuthenticatedClient | Client,
|
|
99
|
+
last_knowledge_of_server: Unset | int = UNSET,
|
|
100
|
+
) -> AccountsResponse | ErrorResponse | None:
|
|
101
|
+
"""Account list
|
|
102
|
+
|
|
103
|
+
Returns all accounts
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
budget_id (str):
|
|
107
|
+
last_knowledge_of_server (Union[Unset, int]):
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
111
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Union[AccountsResponse, ErrorResponse]
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
return sync_detailed(
|
|
118
|
+
budget_id=budget_id,
|
|
119
|
+
client=client,
|
|
120
|
+
last_knowledge_of_server=last_knowledge_of_server,
|
|
121
|
+
).parsed
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async def asyncio_detailed(
|
|
125
|
+
budget_id: str,
|
|
126
|
+
*,
|
|
127
|
+
client: AuthenticatedClient | Client,
|
|
128
|
+
last_knowledge_of_server: Unset | int = UNSET,
|
|
129
|
+
) -> Response[AccountsResponse | ErrorResponse]:
|
|
130
|
+
"""Account list
|
|
131
|
+
|
|
132
|
+
Returns all accounts
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
budget_id (str):
|
|
136
|
+
last_knowledge_of_server (Union[Unset, int]):
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
140
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Response[Union[AccountsResponse, ErrorResponse]]
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
kwargs = _get_kwargs(
|
|
147
|
+
budget_id=budget_id,
|
|
148
|
+
last_knowledge_of_server=last_knowledge_of_server,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
152
|
+
|
|
153
|
+
return _build_response(client=client, response=response)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
async def asyncio(
|
|
157
|
+
budget_id: str,
|
|
158
|
+
*,
|
|
159
|
+
client: AuthenticatedClient | Client,
|
|
160
|
+
last_knowledge_of_server: Unset | int = UNSET,
|
|
161
|
+
) -> AccountsResponse | ErrorResponse | None:
|
|
162
|
+
"""Account list
|
|
163
|
+
|
|
164
|
+
Returns all accounts
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
budget_id (str):
|
|
168
|
+
last_knowledge_of_server (Union[Unset, int]):
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
errors.UnexpectedStatusError: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
172
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Union[AccountsResponse, ErrorResponse]
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
await asyncio_detailed(
|
|
180
|
+
budget_id=budget_id,
|
|
181
|
+
client=client,
|
|
182
|
+
last_knowledge_of_server=last_knowledge_of_server,
|
|
183
|
+
)
|
|
184
|
+
).parsed
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains endpoint functions for accessing the API"""
|