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.
Files changed (206) hide show
  1. ynab_cli/__init__.py +0 -0
  2. ynab_cli/adapters/__init__.py +0 -0
  3. ynab_cli/adapters/rich/__init__.py +0 -0
  4. ynab_cli/adapters/rich/io.py +38 -0
  5. ynab_cli/adapters/textual/__init__.py +0 -0
  6. ynab_cli/adapters/textual/io.py +62 -0
  7. ynab_cli/adapters/ynab/__init__.py +8 -0
  8. ynab_cli/adapters/ynab/api/__init__.py +1 -0
  9. ynab_cli/adapters/ynab/api/accounts/__init__.py +1 -0
  10. ynab_cli/adapters/ynab/api/accounts/create_account.py +186 -0
  11. ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py +177 -0
  12. ynab_cli/adapters/ynab/api/accounts/get_accounts.py +184 -0
  13. ynab_cli/adapters/ynab/api/budgets/__init__.py +1 -0
  14. ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py +188 -0
  15. ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py +163 -0
  16. ynab_cli/adapters/ynab/api/budgets/get_budgets.py +171 -0
  17. ynab_cli/adapters/ynab/api/categories/__init__.py +1 -0
  18. ynab_cli/adapters/ynab/api/categories/get_categories.py +188 -0
  19. ynab_cli/adapters/ynab/api/categories/get_category_by_id.py +180 -0
  20. ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py +194 -0
  21. ynab_cli/adapters/ynab/api/categories/update_category.py +199 -0
  22. ynab_cli/adapters/ynab/api/categories/update_month_category.py +213 -0
  23. ynab_cli/adapters/ynab/api/months/__init__.py +1 -0
  24. ynab_cli/adapters/ynab/api/months/get_budget_month.py +177 -0
  25. ynab_cli/adapters/ynab/api/months/get_budget_months.py +184 -0
  26. ynab_cli/adapters/ynab/api/payee_locations/__init__.py +1 -0
  27. ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py +176 -0
  28. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py +163 -0
  29. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py +176 -0
  30. ynab_cli/adapters/ynab/api/payees/__init__.py +1 -0
  31. ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py +176 -0
  32. ynab_cli/adapters/ynab/api/payees/get_payees.py +184 -0
  33. ynab_cli/adapters/ynab/api/payees/update_payee.py +199 -0
  34. ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py +1 -0
  35. ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py +186 -0
  36. ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py +176 -0
  37. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py +176 -0
  38. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py +184 -0
  39. ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py +199 -0
  40. ynab_cli/adapters/ynab/api/transactions/__init__.py +1 -0
  41. ynab_cli/adapters/ynab/api/transactions/create_transaction.py +202 -0
  42. ynab_cli/adapters/ynab/api/transactions/delete_transaction.py +176 -0
  43. ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py +176 -0
  44. ynab_cli/adapters/ynab/api/transactions/get_transactions.py +227 -0
  45. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py +236 -0
  46. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py +236 -0
  47. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py +236 -0
  48. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py +236 -0
  49. ynab_cli/adapters/ynab/api/transactions/import_transactions.py +183 -0
  50. ynab_cli/adapters/ynab/api/transactions/update_transaction.py +199 -0
  51. ynab_cli/adapters/ynab/api/transactions/update_transactions.py +177 -0
  52. ynab_cli/adapters/ynab/api/user/__init__.py +1 -0
  53. ynab_cli/adapters/ynab/api/user/get_user.py +130 -0
  54. ynab_cli/adapters/ynab/client.py +268 -0
  55. ynab_cli/adapters/ynab/errors.py +16 -0
  56. ynab_cli/adapters/ynab/models/__init__.py +229 -0
  57. ynab_cli/adapters/ynab/models/account.py +345 -0
  58. ynab_cli/adapters/ynab/models/account_response.py +65 -0
  59. ynab_cli/adapters/ynab/models/account_response_data.py +65 -0
  60. ynab_cli/adapters/ynab/models/account_type.py +23 -0
  61. ynab_cli/adapters/ynab/models/accounts_response.py +65 -0
  62. ynab_cli/adapters/ynab/models/accounts_response_data.py +81 -0
  63. ynab_cli/adapters/ynab/models/budget_detail.py +405 -0
  64. ynab_cli/adapters/ynab/models/budget_detail_response.py +65 -0
  65. ynab_cli/adapters/ynab/models/budget_detail_response_data.py +73 -0
  66. ynab_cli/adapters/ynab/models/budget_settings.py +115 -0
  67. ynab_cli/adapters/ynab/models/budget_settings_response.py +65 -0
  68. ynab_cli/adapters/ynab/models/budget_settings_response_data.py +65 -0
  69. ynab_cli/adapters/ynab/models/budget_summary.py +216 -0
  70. ynab_cli/adapters/ynab/models/budget_summary_response.py +65 -0
  71. ynab_cli/adapters/ynab/models/budget_summary_response_data.py +91 -0
  72. ynab_cli/adapters/ynab/models/bulk_response.py +65 -0
  73. ynab_cli/adapters/ynab/models/bulk_response_data.py +65 -0
  74. ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py +68 -0
  75. ynab_cli/adapters/ynab/models/bulk_transactions.py +75 -0
  76. ynab_cli/adapters/ynab/models/categories_response.py +65 -0
  77. ynab_cli/adapters/ynab/models/categories_response_data.py +81 -0
  78. ynab_cli/adapters/ynab/models/category.py +519 -0
  79. ynab_cli/adapters/ynab/models/category_goal_type_type_1.py +15 -0
  80. ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py +15 -0
  81. ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py +15 -0
  82. ynab_cli/adapters/ynab/models/category_group.py +85 -0
  83. ynab_cli/adapters/ynab/models/category_group_with_categories.py +108 -0
  84. ynab_cli/adapters/ynab/models/category_response.py +65 -0
  85. ynab_cli/adapters/ynab/models/category_response_data.py +65 -0
  86. ynab_cli/adapters/ynab/models/currency_format_type_0.py +117 -0
  87. ynab_cli/adapters/ynab/models/date_format_type_0.py +61 -0
  88. ynab_cli/adapters/ynab/models/error_detail.py +75 -0
  89. ynab_cli/adapters/ynab/models/error_response.py +65 -0
  90. ynab_cli/adapters/ynab/models/existing_transaction.py +322 -0
  91. ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py +12 -0
  92. ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py +12 -0
  93. ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py +12 -0
  94. ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py +12 -0
  95. ynab_cli/adapters/ynab/models/get_transactions_type.py +12 -0
  96. ynab_cli/adapters/ynab/models/hybrid_transaction.py +567 -0
  97. ynab_cli/adapters/ynab/models/hybrid_transaction_type.py +12 -0
  98. ynab_cli/adapters/ynab/models/hybrid_transactions_response.py +65 -0
  99. ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py +84 -0
  100. ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py +44 -0
  101. ynab_cli/adapters/ynab/models/month_detail.py +168 -0
  102. ynab_cli/adapters/ynab/models/month_detail_response.py +65 -0
  103. ynab_cli/adapters/ynab/models/month_detail_response_data.py +65 -0
  104. ynab_cli/adapters/ynab/models/month_summaries_response.py +65 -0
  105. ynab_cli/adapters/ynab/models/month_summaries_response_data.py +81 -0
  106. ynab_cli/adapters/ynab/models/month_summary.py +145 -0
  107. ynab_cli/adapters/ynab/models/new_transaction.py +352 -0
  108. ynab_cli/adapters/ynab/models/patch_category_wrapper.py +65 -0
  109. ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py +65 -0
  110. ynab_cli/adapters/ynab/models/patch_payee_wrapper.py +65 -0
  111. ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py +73 -0
  112. ynab_cli/adapters/ynab/models/payee.py +100 -0
  113. ynab_cli/adapters/ynab/models/payee_location.py +93 -0
  114. ynab_cli/adapters/ynab/models/payee_location_response.py +65 -0
  115. ynab_cli/adapters/ynab/models/payee_location_response_data.py +65 -0
  116. ynab_cli/adapters/ynab/models/payee_locations_response.py +65 -0
  117. ynab_cli/adapters/ynab/models/payee_locations_response_data.py +73 -0
  118. ynab_cli/adapters/ynab/models/payee_response.py +65 -0
  119. ynab_cli/adapters/ynab/models/payee_response_data.py +65 -0
  120. ynab_cli/adapters/ynab/models/payees_response.py +65 -0
  121. ynab_cli/adapters/ynab/models/payees_response_data.py +81 -0
  122. ynab_cli/adapters/ynab/models/post_account_wrapper.py +65 -0
  123. ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py +65 -0
  124. ynab_cli/adapters/ynab/models/post_transactions_wrapper.py +91 -0
  125. ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py +65 -0
  126. ynab_cli/adapters/ynab/models/put_transaction_wrapper.py +65 -0
  127. ynab_cli/adapters/ynab/models/save_account.py +77 -0
  128. ynab_cli/adapters/ynab/models/save_category.py +129 -0
  129. ynab_cli/adapters/ynab/models/save_category_response.py +65 -0
  130. ynab_cli/adapters/ynab/models/save_category_response_data.py +73 -0
  131. ynab_cli/adapters/ynab/models/save_month_category.py +59 -0
  132. ynab_cli/adapters/ynab/models/save_payee.py +59 -0
  133. ynab_cli/adapters/ynab/models/save_payee_response.py +65 -0
  134. ynab_cli/adapters/ynab/models/save_payee_response_data.py +73 -0
  135. ynab_cli/adapters/ynab/models/save_scheduled_transaction.py +269 -0
  136. ynab_cli/adapters/ynab/models/save_sub_transaction.py +166 -0
  137. ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py +366 -0
  138. ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py +322 -0
  139. ynab_cli/adapters/ynab/models/save_transactions_response.py +65 -0
  140. ynab_cli/adapters/ynab/models/save_transactions_response_data.py +123 -0
  141. ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py +238 -0
  142. ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py +381 -0
  143. ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py +23 -0
  144. ynab_cli/adapters/ynab/models/scheduled_transaction_response.py +65 -0
  145. ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py +65 -0
  146. ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py +310 -0
  147. ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py +23 -0
  148. ynab_cli/adapters/ynab/models/scheduled_transactions_response.py +65 -0
  149. ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py +81 -0
  150. ynab_cli/adapters/ynab/models/sub_transaction.py +259 -0
  151. ynab_cli/adapters/ynab/models/transaction_cleared_status.py +13 -0
  152. ynab_cli/adapters/ynab/models/transaction_detail.py +570 -0
  153. ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py +16 -0
  154. ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py +16 -0
  155. ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py +16 -0
  156. ynab_cli/adapters/ynab/models/transaction_response.py +65 -0
  157. ynab_cli/adapters/ynab/models/transaction_response_data.py +65 -0
  158. ynab_cli/adapters/ynab/models/transaction_summary.py +499 -0
  159. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py +18 -0
  160. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py +18 -0
  161. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py +18 -0
  162. ynab_cli/adapters/ynab/models/transactions_import_response.py +65 -0
  163. ynab_cli/adapters/ynab/models/transactions_import_response_data.py +59 -0
  164. ynab_cli/adapters/ynab/models/transactions_response.py +65 -0
  165. ynab_cli/adapters/ynab/models/transactions_response_data.py +81 -0
  166. ynab_cli/adapters/ynab/models/user.py +60 -0
  167. ynab_cli/adapters/ynab/models/user_response.py +65 -0
  168. ynab_cli/adapters/ynab/models/user_response_data.py +65 -0
  169. ynab_cli/adapters/ynab/types.py +46 -0
  170. ynab_cli/adapters/ynab/util.py +78 -0
  171. ynab_cli/domain/__init__.py +0 -0
  172. ynab_cli/domain/constants.py +3 -0
  173. ynab_cli/domain/models/__init__.py +0 -0
  174. ynab_cli/domain/models/rules.py +37 -0
  175. ynab_cli/domain/ports/__init__.py +5 -0
  176. ynab_cli/domain/ports/io.py +63 -0
  177. ynab_cli/domain/settings.py +16 -0
  178. ynab_cli/domain/use_cases/__init__.py +0 -0
  179. ynab_cli/domain/use_cases/categories.py +105 -0
  180. ynab_cli/domain/use_cases/payees.py +232 -0
  181. ynab_cli/domain/use_cases/transactions.py +93 -0
  182. ynab_cli/host/__init__.py +14 -0
  183. ynab_cli/host/cli.py +37 -0
  184. ynab_cli/host/click/__init__.py +0 -0
  185. ynab_cli/host/click/cli.py +44 -0
  186. ynab_cli/host/click/commands/__init__.py +0 -0
  187. ynab_cli/host/click/commands/categories.py +92 -0
  188. ynab_cli/host/click/commands/payees.py +157 -0
  189. ynab_cli/host/click/commands/rich/__init__.py +0 -0
  190. ynab_cli/host/click/commands/rich/progress_table.py +37 -0
  191. ynab_cli/host/click/commands/transactions.py +76 -0
  192. ynab_cli/host/constants.py +3 -0
  193. ynab_cli/host/textual/__init__.py +0 -0
  194. ynab_cli/host/textual/app.py +98 -0
  195. ynab_cli/host/textual/app.tcss +47 -0
  196. ynab_cli/host/textual/cli.py +42 -0
  197. ynab_cli/host/textual/widgets/__init__.py +58 -0
  198. ynab_cli/host/textual/widgets/categories.py +90 -0
  199. ynab_cli/host/textual/widgets/payees.py +154 -0
  200. ynab_cli/host/textual/widgets/transactions.py +89 -0
  201. ynab_cli/py.typed +0 -0
  202. ynab_cli-0.3.0.dist-info/METADATA +102 -0
  203. ynab_cli-0.3.0.dist-info/RECORD +206 -0
  204. ynab_cli-0.3.0.dist-info/WHEEL +4 -0
  205. ynab_cli-0.3.0.dist-info/entry_points.txt +2 -0
  206. 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,8 @@
1
+ """A client library for accessing YNAB API Endpoints"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -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"""