ynab-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. ynab_cli-0.1.0/.env-sample +7 -0
  2. ynab_cli-0.1.0/.github/FUNDING.yml +1 -0
  3. ynab_cli-0.1.0/.github/workflows/pr.yml +24 -0
  4. ynab_cli-0.1.0/.github/workflows/publish-to-pypi.yml +43 -0
  5. ynab_cli-0.1.0/.gitignore +12 -0
  6. ynab_cli-0.1.0/.python-version +1 -0
  7. ynab_cli-0.1.0/CHANGELOG.md +25 -0
  8. ynab_cli-0.1.0/LICENSE.md +21 -0
  9. ynab_cli-0.1.0/Makefile +45 -0
  10. ynab_cli-0.1.0/PKG-INFO +106 -0
  11. ynab_cli-0.1.0/README.md +82 -0
  12. ynab_cli-0.1.0/docs/index.md +42 -0
  13. ynab_cli-0.1.0/docs/transaction_rules.md +42 -0
  14. ynab_cli-0.1.0/mkdocs.yml +28 -0
  15. ynab_cli-0.1.0/pyproject.toml +133 -0
  16. ynab_cli-0.1.0/src/ynab_cli/__init__.py +0 -0
  17. ynab_cli-0.1.0/src/ynab_cli/adapters/__init__.py +0 -0
  18. ynab_cli-0.1.0/src/ynab_cli/adapters/rich/__init__.py +0 -0
  19. ynab_cli-0.1.0/src/ynab_cli/adapters/rich/io.py +38 -0
  20. ynab_cli-0.1.0/src/ynab_cli/adapters/textual/__init__.py +0 -0
  21. ynab_cli-0.1.0/src/ynab_cli/adapters/textual/io.py +62 -0
  22. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/__init__.py +8 -0
  23. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/__init__.py +1 -0
  24. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/accounts/__init__.py +1 -0
  25. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/accounts/create_account.py +186 -0
  26. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py +177 -0
  27. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/accounts/get_accounts.py +184 -0
  28. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/budgets/__init__.py +1 -0
  29. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py +188 -0
  30. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py +163 -0
  31. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/budgets/get_budgets.py +171 -0
  32. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/__init__.py +1 -0
  33. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/get_categories.py +188 -0
  34. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/get_category_by_id.py +180 -0
  35. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py +194 -0
  36. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/update_category.py +199 -0
  37. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/categories/update_month_category.py +213 -0
  38. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/months/__init__.py +1 -0
  39. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/months/get_budget_month.py +177 -0
  40. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/months/get_budget_months.py +184 -0
  41. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payee_locations/__init__.py +1 -0
  42. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py +176 -0
  43. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py +163 -0
  44. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py +176 -0
  45. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payees/__init__.py +1 -0
  46. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py +176 -0
  47. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payees/get_payees.py +184 -0
  48. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/payees/update_payee.py +199 -0
  49. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py +1 -0
  50. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py +186 -0
  51. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py +176 -0
  52. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py +176 -0
  53. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py +184 -0
  54. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py +199 -0
  55. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/__init__.py +1 -0
  56. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/create_transaction.py +202 -0
  57. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/delete_transaction.py +176 -0
  58. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py +176 -0
  59. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transactions.py +227 -0
  60. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py +236 -0
  61. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py +236 -0
  62. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py +236 -0
  63. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py +236 -0
  64. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/import_transactions.py +183 -0
  65. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/update_transaction.py +199 -0
  66. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/transactions/update_transactions.py +177 -0
  67. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/user/__init__.py +1 -0
  68. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/api/user/get_user.py +130 -0
  69. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/client.py +268 -0
  70. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/errors.py +16 -0
  71. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/__init__.py +229 -0
  72. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/account.py +345 -0
  73. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/account_response.py +65 -0
  74. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/account_response_data.py +65 -0
  75. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/account_type.py +23 -0
  76. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/accounts_response.py +65 -0
  77. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/accounts_response_data.py +81 -0
  78. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_detail.py +405 -0
  79. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_detail_response.py +65 -0
  80. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_detail_response_data.py +73 -0
  81. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_settings.py +115 -0
  82. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_settings_response.py +65 -0
  83. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_settings_response_data.py +65 -0
  84. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_summary.py +216 -0
  85. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_summary_response.py +65 -0
  86. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/budget_summary_response_data.py +91 -0
  87. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/bulk_response.py +65 -0
  88. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/bulk_response_data.py +65 -0
  89. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py +68 -0
  90. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/bulk_transactions.py +75 -0
  91. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/categories_response.py +65 -0
  92. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/categories_response_data.py +81 -0
  93. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category.py +519 -0
  94. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_goal_type_type_1.py +15 -0
  95. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py +15 -0
  96. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py +15 -0
  97. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_group.py +85 -0
  98. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_group_with_categories.py +108 -0
  99. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_response.py +65 -0
  100. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/category_response_data.py +65 -0
  101. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/currency_format_type_0.py +117 -0
  102. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/date_format_type_0.py +61 -0
  103. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/error_detail.py +75 -0
  104. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/error_response.py +65 -0
  105. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/existing_transaction.py +322 -0
  106. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py +12 -0
  107. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py +12 -0
  108. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py +12 -0
  109. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py +12 -0
  110. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/get_transactions_type.py +12 -0
  111. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/hybrid_transaction.py +567 -0
  112. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/hybrid_transaction_type.py +12 -0
  113. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/hybrid_transactions_response.py +65 -0
  114. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py +84 -0
  115. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py +44 -0
  116. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_detail.py +168 -0
  117. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_detail_response.py +65 -0
  118. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_detail_response_data.py +65 -0
  119. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_summaries_response.py +65 -0
  120. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_summaries_response_data.py +81 -0
  121. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/month_summary.py +145 -0
  122. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/new_transaction.py +352 -0
  123. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/patch_category_wrapper.py +65 -0
  124. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py +65 -0
  125. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/patch_payee_wrapper.py +65 -0
  126. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py +73 -0
  127. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee.py +100 -0
  128. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_location.py +93 -0
  129. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_location_response.py +65 -0
  130. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_location_response_data.py +65 -0
  131. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_locations_response.py +65 -0
  132. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_locations_response_data.py +73 -0
  133. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_response.py +65 -0
  134. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payee_response_data.py +65 -0
  135. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payees_response.py +65 -0
  136. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/payees_response_data.py +81 -0
  137. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/post_account_wrapper.py +65 -0
  138. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py +65 -0
  139. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/post_transactions_wrapper.py +91 -0
  140. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py +65 -0
  141. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/put_transaction_wrapper.py +65 -0
  142. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_account.py +77 -0
  143. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_category.py +129 -0
  144. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_category_response.py +65 -0
  145. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_category_response_data.py +73 -0
  146. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_month_category.py +59 -0
  147. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_payee.py +59 -0
  148. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_payee_response.py +65 -0
  149. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_payee_response_data.py +73 -0
  150. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_scheduled_transaction.py +269 -0
  151. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_sub_transaction.py +166 -0
  152. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py +366 -0
  153. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py +322 -0
  154. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_transactions_response.py +65 -0
  155. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/save_transactions_response_data.py +123 -0
  156. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py +238 -0
  157. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py +381 -0
  158. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py +23 -0
  159. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_response.py +65 -0
  160. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py +65 -0
  161. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py +310 -0
  162. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py +23 -0
  163. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transactions_response.py +65 -0
  164. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py +81 -0
  165. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/sub_transaction.py +259 -0
  166. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_cleared_status.py +13 -0
  167. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_detail.py +570 -0
  168. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py +16 -0
  169. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py +16 -0
  170. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py +16 -0
  171. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_response.py +65 -0
  172. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_response_data.py +65 -0
  173. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_summary.py +499 -0
  174. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py +18 -0
  175. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py +18 -0
  176. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py +18 -0
  177. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transactions_import_response.py +65 -0
  178. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transactions_import_response_data.py +59 -0
  179. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transactions_response.py +65 -0
  180. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/transactions_response_data.py +81 -0
  181. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/user.py +60 -0
  182. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/user_response.py +65 -0
  183. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/models/user_response_data.py +65 -0
  184. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/types.py +46 -0
  185. ynab_cli-0.1.0/src/ynab_cli/adapters/ynab/util.py +78 -0
  186. ynab_cli-0.1.0/src/ynab_cli/domain/__init__.py +0 -0
  187. ynab_cli-0.1.0/src/ynab_cli/domain/constants.py +3 -0
  188. ynab_cli-0.1.0/src/ynab_cli/domain/models/__init__.py +0 -0
  189. ynab_cli-0.1.0/src/ynab_cli/domain/models/rules.py +37 -0
  190. ynab_cli-0.1.0/src/ynab_cli/domain/ports/__init__.py +5 -0
  191. ynab_cli-0.1.0/src/ynab_cli/domain/ports/io.py +63 -0
  192. ynab_cli-0.1.0/src/ynab_cli/domain/settings.py +16 -0
  193. ynab_cli-0.1.0/src/ynab_cli/domain/use_cases/__init__.py +0 -0
  194. ynab_cli-0.1.0/src/ynab_cli/domain/use_cases/budgets.py +33 -0
  195. ynab_cli-0.1.0/src/ynab_cli/domain/use_cases/categories.py +105 -0
  196. ynab_cli-0.1.0/src/ynab_cli/domain/use_cases/payees.py +232 -0
  197. ynab_cli-0.1.0/src/ynab_cli/domain/use_cases/transactions.py +93 -0
  198. ynab_cli-0.1.0/src/ynab_cli/host/__init__.py +14 -0
  199. ynab_cli-0.1.0/src/ynab_cli/host/cli.py +38 -0
  200. ynab_cli-0.1.0/src/ynab_cli/host/click/__init__.py +0 -0
  201. ynab_cli-0.1.0/src/ynab_cli/host/click/cli.py +43 -0
  202. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/__init__.py +0 -0
  203. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/budgets.py +54 -0
  204. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/categories.py +96 -0
  205. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/payees.py +161 -0
  206. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/rich/__init__.py +0 -0
  207. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/rich/progress_table.py +37 -0
  208. ynab_cli-0.1.0/src/ynab_cli/host/click/commands/transactions.py +80 -0
  209. ynab_cli-0.1.0/src/ynab_cli/host/constants.py +3 -0
  210. ynab_cli-0.1.0/src/ynab_cli/host/textual/__init__.py +0 -0
  211. ynab_cli-0.1.0/src/ynab_cli/host/textual/app.py +98 -0
  212. ynab_cli-0.1.0/src/ynab_cli/host/textual/app.tcss +47 -0
  213. ynab_cli-0.1.0/src/ynab_cli/host/textual/cli.py +42 -0
  214. ynab_cli-0.1.0/src/ynab_cli/host/textual/widgets/__init__.py +58 -0
  215. ynab_cli-0.1.0/src/ynab_cli/host/textual/widgets/categories.py +90 -0
  216. ynab_cli-0.1.0/src/ynab_cli/host/textual/widgets/payees.py +154 -0
  217. ynab_cli-0.1.0/src/ynab_cli/host/textual/widgets/transactions.py +89 -0
  218. ynab_cli-0.1.0/src/ynab_cli/py.typed +0 -0
  219. ynab_cli-0.1.0/tests/__init__.py +0 -0
  220. ynab_cli-0.1.0/tests/factories/__init__.py +0 -0
  221. ynab_cli-0.1.0/tests/factories/ynab.py +18 -0
  222. ynab_cli-0.1.0/tests/unit/__init__.py +0 -0
  223. ynab_cli-0.1.0/tests/unit/conftest.py +17 -0
  224. ynab_cli-0.1.0/tests/unit/domain/__init__.py +0 -0
  225. ynab_cli-0.1.0/tests/unit/domain/use_cases/__init__.py +0 -0
  226. ynab_cli-0.1.0/tests/unit/domain/use_cases/test_categories.py +68 -0
  227. ynab_cli-0.1.0/tests/unit/domain/use_cases/test_payees.py +72 -0
  228. ynab_cli-0.1.0/tests/unit/domain/use_cases/test_transactions.py +106 -0
  229. ynab_cli-0.1.0/uv.lock +1567 -0
@@ -0,0 +1,7 @@
1
+ # Make a copy of this file called `.env` and update the variables below if you want to use dotenv files
2
+
3
+ # Get this from your developer settings https://api.ynab.com/#personal-access-tokens
4
+ YNAB_CLI_ACCESS_TOKEN=YourAccessToken
5
+
6
+ # Uncomment the below line and update it if you only use ynab-cli with one budget
7
+ # YNAB_CLI_BUDGET_ID=YourBudgetID
@@ -0,0 +1 @@
1
+ github: jeffsawatzky
@@ -0,0 +1,24 @@
1
+ name: pr
2
+ on:
3
+ pull_request:
4
+ types: [opened, reopened, synchronize]
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ python-version: ['3.11', '3.12', '3.13']
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - name: Install the latest version of uv
14
+ uses: astral-sh/setup-uv@v6
15
+ with:
16
+ version: latest
17
+ python-version: ${{ matrix.python-version }}
18
+ - run: uv sync --locked # abort if the lockfile changes
19
+ - run: uv run ruff format --check . # check formatting is correct
20
+ - run: uv run ruff check --no-fix . # and linting
21
+ - run: uv run mypy . # typecheck too
22
+ - run: uv run pytest tests # then run your tests!
23
+ - run: uv build # make sure the package builds
24
+ - run: uv run mkdocs build # make sure the docs build
@@ -0,0 +1,43 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ push:
4
+ tags:
5
+ - v*
6
+ jobs:
7
+ build:
8
+ name: Build distribution
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ with:
13
+ persist-credentials: false
14
+ - name: Install the latest version of uv
15
+ uses: astral-sh/setup-uv@v6
16
+ with:
17
+ version: latest
18
+ - name: Build a binary wheel and a source tarball
19
+ run: uv build
20
+ - name: Store the distribution packages
21
+ uses: actions/upload-artifact@v4
22
+ with:
23
+ name: python-package-distributions
24
+ path: dist/
25
+ publish-to-pypi:
26
+ name: Publish to PyPI
27
+ if: 'startsWith(github.ref, ''refs/tags/'')'
28
+ needs:
29
+ - build
30
+ runs-on: ubuntu-latest
31
+ environment:
32
+ name: pypi
33
+ url: 'https://pypi.org/p/ynab-cli'
34
+ permissions:
35
+ id-token: write
36
+ steps:
37
+ - name: Download all the dists
38
+ uses: actions/download-artifact@v4
39
+ with:
40
+ name: python-package-distributions
41
+ path: dist/
42
+ - name: Publish to PyPI
43
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,12 @@
1
+ .coverage
2
+ .env
3
+ rules.json
4
+
5
+ __pycache__/
6
+ .my_cache/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .venv/
10
+ .vscode/
11
+ dist/
12
+ site/
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## v0.1.0 (2025-06-06)
9
+
10
+ ### BREAKING CHANGE
11
+
12
+ - changes the way the commands need to be run. You now need to specify the "run" command before any of the subcommands
13
+
14
+ ### Feat
15
+
16
+ - **budgets**: added a command to list all budgets
17
+ - added a feature to prefix unused payees to make them easier to find and delete in ynab
18
+ - added a list all command to payees
19
+ - add a textual based tui
20
+ - use rich for better user feedback
21
+ - implement initial cli
22
+
23
+ ### Refactor
24
+
25
+ - cleaned up some code, sorted lists, and improved the file selector
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jeff Sawatzky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,45 @@
1
+ .PHONY: lint test clean version
2
+
3
+ .venv: pyproject.toml # the python virtual environment
4
+ uv sync
5
+ touch .venv
6
+
7
+ lint: .venv # run linters and type checkers
8
+ uv run ruff format .
9
+ uv run ruff check .
10
+ uv run mypy .
11
+
12
+ test: .venv lint # run tests with coverage
13
+ uv run pytest --cov=src tests
14
+
15
+ clean: # clean up build artifacts and caches
16
+ rm -f .coverage
17
+ rm -rf dist
18
+ rm -rf htmlcov
19
+ rm -rf site
20
+ find . -type f -name .DS_Store | xargs rm -rf
21
+ find . -type d -name __pycache__ | xargs rm -rf
22
+ find . -type d -name .mypy_cache | xargs rm -rf
23
+ find . -type d -name .pytest_cache | xargs rm -rf
24
+ find . -type d -name .ruff_cache | xargs rm -rf
25
+ find . -type d -empty -delete
26
+
27
+ ynab-sdk: # regenerate the YNAB SDK from the OpenAPI spec
28
+ rm -rf ./src/ynab_cli/adapters/ynab
29
+ mkdir -p ./src/ynab_cli/adapters/ynab
30
+ uvx openapi-python-client generate --meta none --url https://api.ynab.com/papi/open_api_spec.yaml --output-path ./src/ynab_cli/adapters/ynab --overwrite
31
+
32
+ dist: clean # build the distribution package
33
+ uv build
34
+
35
+ site: clean # build the documentation site
36
+ uv run mkdocs build
37
+
38
+ site-serve: clean # serve the documentation site locally
39
+ uv run mkdocs serve
40
+
41
+ site-gh: clean # deploy the documentation site to GitHub Pages
42
+ uv run mkdocs gh-deploy
43
+
44
+ version: clean # update the version in pyproject.toml and create a new tag
45
+ cz bump
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.4
2
+ Name: ynab-cli
3
+ Version: 0.1.0
4
+ Summary: YNAB Command Line Interface
5
+ Project-URL: documentation, https://jeffsawatzky.github.io/ynab-cli/
6
+ Project-URL: source, https://github.com/jeffsawatzky/ynab-cli
7
+ Project-URL: funding, https://github.com/sponsors/jeffsawatzky
8
+ Author: Jeff Sawatzky
9
+ License-File: LICENSE.md
10
+ Keywords: budget,cli,click,textual,ynab
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: attrs~=25.3
13
+ Requires-Dist: click-default-group~=1.2
14
+ Requires-Dist: click~=8.2
15
+ Requires-Dist: httpx~=0.28
16
+ Requires-Dist: python-dotenv~=1.1
17
+ Requires-Dist: rapidfuzz~=3.13
18
+ Requires-Dist: rich~=14.0
19
+ Requires-Dist: rule-engine~=4.5
20
+ Requires-Dist: textual-fspicker~=0.4
21
+ Requires-Dist: textual~=3.3
22
+ Requires-Dist: typing-extensions~=4.14
23
+ Description-Content-Type: text/markdown
24
+
25
+ # YNAB CLI
26
+
27
+ A command-line interface for interacting with YNAB (You Need A Budget).
28
+
29
+ ## Usage
30
+
31
+ Full user documentation available [here](http://jeffsawatzky.github.io/ynab-cli)
32
+
33
+ ## Project Structure
34
+
35
+ - `src/ynab_cli/`: Main source code
36
+ - `tests/`: Unit and integration tests
37
+ - `docs/`: Documentation (built with MkDocs)
38
+
39
+ ## Getting Started
40
+
41
+ ### Prerequisites
42
+ - Python 3.11+
43
+ - [uv](https://docs.astral.sh/uv/)
44
+
45
+ ### Installation
46
+
47
+ Clone the repository:
48
+ ```sh
49
+ $ git clone https://github.com/jeffsawatzky/ynab-cli.git
50
+ $ cd ynab-cli
51
+ ```
52
+
53
+ Install dependencies with uv:
54
+ ```sh
55
+ $ uv sync
56
+ ```
57
+
58
+ ### Running the CLI
59
+
60
+ With uv:
61
+ ```sh
62
+ $ uv run ynab-cli --help
63
+ ```
64
+
65
+ ## Development
66
+
67
+ - Source code is in `src/ynab_cli/`.
68
+ - Use feature branches for new work.
69
+ - Follow PEP8 and use type hints where possible.
70
+
71
+ ### Linting & Formatting
72
+
73
+ ```sh
74
+ $ make lint
75
+ ```
76
+
77
+ ### Running Tests
78
+
79
+ ```sh
80
+ $ make test
81
+ ```
82
+ Or directly with pytest:
83
+ ```sh
84
+ uv run pytest
85
+ ```
86
+
87
+ ## Documentation
88
+
89
+ - Docs are in `docs/` and built with MkDocs.
90
+ - To serve docs locally:
91
+ ```sh
92
+ $ uv run mkdocs serve
93
+ ```
94
+
95
+ ## Contributing
96
+
97
+ 1. Fork the repository
98
+ 2. Create a feature branch (`git checkout -b feature/your-feature`)
99
+ 3. Commit your changes. Commits should follow conventional commits. The repo is configured with [commitizen](https://commitizen-tools.github.io/commitizen/)
100
+ 4. Push to your fork and open a pull request
101
+
102
+ Please include tests for new features and bug fixes.
103
+
104
+ ## License
105
+
106
+ See [LICENSE.md](LICENSE.md)
@@ -0,0 +1,82 @@
1
+ # YNAB CLI
2
+
3
+ A command-line interface for interacting with YNAB (You Need A Budget).
4
+
5
+ ## Usage
6
+
7
+ Full user documentation available [here](http://jeffsawatzky.github.io/ynab-cli)
8
+
9
+ ## Project Structure
10
+
11
+ - `src/ynab_cli/`: Main source code
12
+ - `tests/`: Unit and integration tests
13
+ - `docs/`: Documentation (built with MkDocs)
14
+
15
+ ## Getting Started
16
+
17
+ ### Prerequisites
18
+ - Python 3.11+
19
+ - [uv](https://docs.astral.sh/uv/)
20
+
21
+ ### Installation
22
+
23
+ Clone the repository:
24
+ ```sh
25
+ $ git clone https://github.com/jeffsawatzky/ynab-cli.git
26
+ $ cd ynab-cli
27
+ ```
28
+
29
+ Install dependencies with uv:
30
+ ```sh
31
+ $ uv sync
32
+ ```
33
+
34
+ ### Running the CLI
35
+
36
+ With uv:
37
+ ```sh
38
+ $ uv run ynab-cli --help
39
+ ```
40
+
41
+ ## Development
42
+
43
+ - Source code is in `src/ynab_cli/`.
44
+ - Use feature branches for new work.
45
+ - Follow PEP8 and use type hints where possible.
46
+
47
+ ### Linting & Formatting
48
+
49
+ ```sh
50
+ $ make lint
51
+ ```
52
+
53
+ ### Running Tests
54
+
55
+ ```sh
56
+ $ make test
57
+ ```
58
+ Or directly with pytest:
59
+ ```sh
60
+ uv run pytest
61
+ ```
62
+
63
+ ## Documentation
64
+
65
+ - Docs are in `docs/` and built with MkDocs.
66
+ - To serve docs locally:
67
+ ```sh
68
+ $ uv run mkdocs serve
69
+ ```
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork the repository
74
+ 2. Create a feature branch (`git checkout -b feature/your-feature`)
75
+ 3. Commit your changes. Commits should follow conventional commits. The repo is configured with [commitizen](https://commitizen-tools.github.io/commitizen/)
76
+ 4. Push to your fork and open a pull request
77
+
78
+ Please include tests for new features and bug fixes.
79
+
80
+ ## License
81
+
82
+ See [LICENSE.md](LICENSE.md)
@@ -0,0 +1,42 @@
1
+ # Welcome to YNAB CLI
2
+
3
+ This is a simple cli/tui application written in python to help manage your YNAB data.
4
+
5
+ ## Requirements
6
+
7
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/) which allows you to easily run python applications.
8
+ - Your [YNAB developer access token](https://api.ynab.com/#personal-access-tokens).
9
+
10
+ !!! warning
11
+ Developer access tokens are rate limited to 200 requests per hour. Some of the commands below will provide you an opportunity to enter a new developer access token when the current one has exceeded it's limit. It also seems like there is a limit to how many developer access tokens you can create from the developer settings UI.
12
+
13
+ - Your YNAB budget ID. Once you have `uv` and your `access token` you can list your budgets by running:
14
+
15
+ ```sh
16
+ $ uvx ynab-cli run --access-token your_access_token budgets list-all
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ !!! note
22
+ YNAB CLI supports environment variables and dotenv (`.env`) files for specifying options. See the `.env-sample` file for some examples. YNAB CLI looks for the `.env` file in current working directory. If you create a `.env` file with the following information you won't need to keep entering it on the command line.
23
+
24
+ ``` title=".env"
25
+ YNAB_CLI_ACCESS_TOKEN=your_access_token
26
+ YNAB_CLI_BUDGET_ID=your_budget_id
27
+ ```
28
+
29
+ To run the text ui, execute the following command:
30
+
31
+ ```sh
32
+ $ uvx ynab-cli
33
+ ```
34
+
35
+ The individual CLI commands can be similarily run using `uvx`. Full command line usage is below.
36
+
37
+ ::: mkdocs-click
38
+ :module: ynab_cli.host.cli
39
+ :command: cli
40
+ :prog_name: ynab-cli
41
+ :style: table
42
+ :list_subcommands: True
@@ -0,0 +1,42 @@
1
+ !!! note
2
+ Amounts are in milliunits and can be either positive or negative depending on if they are inflow or outflow.
3
+
4
+ !!! note
5
+ To get the category IDs you can use the `ynab run categories list-all` command.
6
+
7
+ The rules use the [rule-engine](https://zerosteiner.github.io/rule-engine/getting_started.html) library, so read that documentation to figure out how to write the rules. If ANY of the rules in the `rules` list match a transaction then it will be updated with the `patch` details.
8
+ The rules are supplied an instance of a `TransactionDetail`, and the `patch` needs to be an instance of a `SaveTransactionWithIdOrImportId`. Read the [YNAB API documention](https://api.ynab.com/v1) to see what properties are available to base your rules on and update.
9
+
10
+ This assumes you have a `rules.json` file with your rules to apply. It could look something like this:
11
+ ```json
12
+ {
13
+ "transaction_rules": [
14
+ {
15
+ "rules": [
16
+ "payee_name == 'My Payee' and amount == -213490"
17
+ ],
18
+ "patch": {
19
+ "category_id": "insert the category id you want to assign it to here"
20
+ }
21
+ },
22
+ {
23
+ "rules": [
24
+ "payee_name == 'My Split Transaction Payee' and amount == -346500"
25
+ ],
26
+ "patch": {
27
+ "category_id": null,
28
+ "subtransactions": [
29
+ {
30
+ "category_id": "insert the first category id you want to assign it to here",
31
+ "amount": -51980
32
+ },
33
+ {
34
+ "category_id": "insert the other category id you want to assign it to here",
35
+ "amount": -294520
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ ```
@@ -0,0 +1,28 @@
1
+ site_name: YNAB CLI
2
+ site_url: https://jeffsawatzky.github.io/ynab-cli/
3
+ repo_url: https://github.com/jeffsawatzky/ynab-cli
4
+
5
+ theme:
6
+ name: material
7
+ features:
8
+ - content.code.copy
9
+
10
+ plugins:
11
+ - search
12
+
13
+ markdown_extensions:
14
+ - admonition
15
+ - attr_list
16
+ - mkdocs-click
17
+ - pymdownx.details
18
+ - pymdownx.highlight:
19
+ anchor_linenums: true
20
+ line_spans: __span
21
+ pygments_lang_class: true
22
+ - pymdownx.inlinehilite
23
+ - pymdownx.snippets
24
+ - pymdownx.superfences
25
+
26
+ nav:
27
+ - Home: index.md
28
+ - Transaction Rules: transaction_rules.md
@@ -0,0 +1,133 @@
1
+ [project]
2
+ name = "ynab-cli"
3
+ version = "0.1.0"
4
+ description = "YNAB Command Line Interface"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license-files = [
8
+ "LICENSE.md"
9
+ ]
10
+ authors = [
11
+ { name = "Jeff Sawatzky" }
12
+ ]
13
+ keywords = [
14
+ "ynab",
15
+ "cli",
16
+ "textual",
17
+ "click",
18
+ "budget",
19
+ ]
20
+ dependencies = [
21
+ "attrs~=25.3",
22
+ "click-default-group~=1.2",
23
+ "click~=8.2",
24
+ "httpx~=0.28",
25
+ "python-dotenv~=1.1",
26
+ "rapidfuzz~=3.13",
27
+ "rich~=14.0",
28
+ "rule-engine~=4.5",
29
+ "textual-fspicker~=0.4",
30
+ "textual~=3.3",
31
+ "typing-extensions~=4.14",
32
+ ]
33
+
34
+ [project.urls]
35
+ documentation = "https://jeffsawatzky.github.io/ynab-cli/"
36
+ source = "https://github.com/jeffsawatzky/ynab-cli"
37
+ funding = "https://github.com/sponsors/jeffsawatzky"
38
+
39
+ [project.scripts]
40
+ ynab-cli = "ynab_cli.host.cli:main"
41
+
42
+
43
+ [dependency-groups]
44
+ dev = [
45
+ "factory-boy>=3.3.3",
46
+ "mkdocs-click>=0.9.0",
47
+ "mkdocs-material>=9.6.14",
48
+ "mkdocs>=1.6.1",
49
+ "mypy>=1.16.0",
50
+ "pytest-asyncio>=1.0.0",
51
+ "pytest-cov>=6.1.1",
52
+ "pytest-mock>=3.14.1",
53
+ "pytest>=8.4.0",
54
+ "ruff>=0.11.12",
55
+ "textual-dev>=1.7.0",
56
+ "types-python-dateutil>=2.9.0.20250516",
57
+ ]
58
+
59
+
60
+ [tool.mypy]
61
+ python_version = "3.11"
62
+ exclude = [
63
+ '^tests/.*\.py$'
64
+ ]
65
+ pretty = true
66
+ show_column_numbers = true
67
+ show_error_codes = true
68
+ show_error_context = true
69
+ strict = true
70
+ warn_unreachable = true
71
+ enable_error_code = [
72
+ "explicit-override",
73
+ ]
74
+
75
+ [[tool.mypy.overrides]]
76
+ module = [
77
+ "click_default_group.*",
78
+ "factory.*",
79
+ "rule_engine.*",
80
+ ]
81
+ ignore_missing_imports = true
82
+
83
+
84
+ [tool.ruff]
85
+ fix = true
86
+ line-length = 120
87
+ target-version = "py311"
88
+
89
+ [tool.ruff.lint]
90
+ extend-select = [
91
+ "W", # warnings
92
+ "I", # isort
93
+ "C90", # mccabe
94
+ "N", # pep8-naming
95
+ "UP", # pyupgrade
96
+ "S", # flake8-bandit
97
+ "B", # flake8-bugbear
98
+ "A", # flake8-builtins
99
+ "DTZ", # flake8-datetimez
100
+ "PT", # flake8-pytest-style
101
+ "TID", # flake8-tidy-imports
102
+ "RUF", # ruff specific rules
103
+ ]
104
+ extend-ignore = [
105
+ "S110", # `try`-`except`-`pass` detected
106
+ ]
107
+
108
+ [tool.ruff.lint.per-file-ignores]
109
+ "tests/**/*.py" = ["S"]
110
+
111
+ [tool.ruff.lint.isort]
112
+ known-first-party = ["ynab_cli", "tests"]
113
+
114
+ [tool.ruff.lint.mccabe]
115
+ max-complexity = 70
116
+
117
+ [tool.ruff.lint.flake8-builtins]
118
+ builtins-ignorelist = ["type", "id"]
119
+
120
+
121
+ [tool.commitizen]
122
+ name = "cz_conventional_commits"
123
+ annotated_tag = true
124
+ tag_format = "v$version"
125
+ version_scheme = "pep440"
126
+ version_provider = "uv"
127
+ update_changelog_on_bump = true
128
+ major_version_zero = true
129
+
130
+
131
+ [build-system]
132
+ requires = ["hatchling"]
133
+ build-backend = "hatchling.build"
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)