363 Commits

Author SHA1 Message Date
kolo da06099990 Merge pull request #8 from koloideal/benchmarks
Benchmarks
2026-02-07 01:30:03 +03:00
kolo 8ff9944d37 benchs 2026-02-07 01:27:03 +03:00
kolo c07ee92371 benchs 2026-02-07 01:24:37 +03:00
kolo a21570e779 benchs 2026-02-06 23:52:26 +03:00
kolo f1034ff447 benchs 2026-02-06 23:41:55 +03:00
kolo fcff6f4263 Update documentation 2026-02-02 22:23:03 +03:00
kolo 417e0e2905 benchs 2026-02-01 02:21:36 +03:00
kolo 31dc49a1bf fix tests 2026-02-01 02:00:54 +03:00
kolo f859451069 benchs 2026-02-01 01:18:27 +03:00
kolo 24aa75eb37 viewr 2026-02-01 00:26:25 +03:00
kolo 5f6b3368e1 extract presentation layer 2026-01-30 20:52:52 +03:00
kolo d03ce5061b benchs 2026-01-29 14:09:15 +03:00
kolo 107530a4b1 benchs 2026-01-29 02:22:48 +03:00
kolo 9aa99352fe fix tests 2026-01-28 14:52:41 +03:00
kolo 2a9281a421 benchs 2026-01-28 02:23:40 +03:00
kolo 0567a3f4a3 release generate 2026-01-25 16:04:47 +03:00
kolo dfe482c545 release generate 2026-01-25 16:01:34 +03:00
kolo 46c1ec02fd comm 2026-01-24 02:24:31 +03:00
kolo 70bbbd76ce benchs 2026-01-24 02:18:39 +03:00
kolo 19bbaab1ee diagrams 2026-01-24 02:06:46 +03:00
kolo 1c54f11f31 benchs 2026-01-24 00:04:28 +03:00
kolo 2ad86dbedd bench 2026-01-22 22:39:35 +03:00
kolo f27f7b135b Update documentation and code snippets 2026-01-22 22:02:19 +03:00
kolo f9a85da430 Merge branch 'main' into benchmarks 2026-01-22 05:01:16 +03:00
kolo 2f557b99b0 Merge pull request #10 from koloideal/dependabot/uv/urllib3-2.6.3
Bump urllib3 from 2.5.0 to 2.6.3
2026-01-22 05:00:14 +03:00
dependabot[bot] 63c4443ff6 Bump urllib3 from 2.5.0 to 2.6.3
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.5.0 to 2.6.3.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 01:59:06 +00:00
kolo 30761749b4 Merge branch 'main' into benchmarks 2026-01-22 04:56:27 +03:00
kolo 0c3048266a Merge pull request #9 from koloideal/prompt-toolkit
Prompt toolkit
2026-01-22 04:49:41 +03:00
kolo 088c1720c4 fix typechecker errors 2026-01-22 04:48:53 +03:00
kolo 838f33db87 remove pyreadline3 from dependencies 2026-01-22 04:31:22 +03:00
kolo b8e9fdcb9c Update documentation and code snippets 2026-01-22 04:29:13 +03:00
kolo 295e260a46 start work 2026-01-22 03:13:42 +03:00
kolo 3fa7b17de9 benchs 2026-01-22 01:59:03 +03:00
kolo a174e0d5ab bench 2026-01-19 00:29:24 +03:00
kolo 9d250fde9c bench 2026-01-18 23:53:52 +03:00
kolo e7d064908f bench 2026-01-18 18:41:03 +03:00
kolo ba9a7b5539 bbbbbbenchh 2026-01-18 02:30:13 +03:00
kolo 69e871a639 bbbbbbenchh 2026-01-18 01:59:55 +03:00
kolo 1648a8206a bbbbbbenchh 2026-01-17 23:43:59 +03:00
kolo 2e5b19f4d8 benchs 2026-01-17 01:21:39 +03:00
kolo 6aa6b0f179 benchs 2026-01-17 00:42:00 +03:00
kolo 00cb94ffe2 Merge pull request #7 from koloideal/improve-perf
Improve perf
2026-01-15 17:00:38 +03:00
kolo 285ea39fa9 ruff wtf 2026-01-15 16:59:57 +03:00
kolo 30e5fd6ebe perf 2026-01-15 16:41:50 +03:00
kolo 18f62d3e7c perffff 2026-01-15 14:52:41 +03:00
kolo 3cd74fc186 benchs 2026-01-15 03:02:41 +03:00
kolo 9bde1321e1 benchs 2026-01-15 02:49:12 +03:00
kolo 0f8b1c05fc pretty gifff 2026-01-15 02:02:50 +03:00
kolo cd3dd10d11 start build pretty benchmarks 2026-01-14 14:51:43 +03:00
kolo b8d8c44bdd start build pretty benchmarks 2026-01-14 14:40:47 +03:00
kolo 4957de95d3 Update documentation and code snippets 2026-01-13 22:18:57 +03:00
kolo c5dab43c87 fix tests and improve perf 2026-01-09 10:14:25 +03:00
kolo 56189be6ab better perf 2025-12-09 12:02:26 +03:00
kolo 725a1f2e40 perf 2025-12-08 21:49:46 +03:00
kolo 22970f7115 Update documentation 2025-12-08 19:53:03 +03:00
kolo 6598fb7fa6 Update documentation and code snippets 2025-12-08 19:30:14 +03:00
kolo 183f069766 Update documentation and code snippets 2025-12-08 19:29:54 +03:00
kolo 75b1efb259 better perf 2025-12-08 14:17:31 +03:00
kolo cb6549452d Merge pull request #6 from koloideal/better-tests
100% codebase test coverage
2025-12-07 01:55:04 +03:00
kolo 425342c059 new tests 2025-12-07 01:51:24 +03:00
kolo 9423034a08 better testsssssss 2025-12-07 01:33:39 +03:00
kolo dee328525d refactor system tests 2025-12-06 20:01:47 +03:00
kolo 1d2ab6f6bb refactor tests and add new 2025-12-06 11:55:50 +03:00
kolo a2ef2652ed refactor tests and add new 2025-12-06 09:26:53 +03:00
kolo 2423f57000 new tests, upgrade tests coverage 2025-12-05 22:57:19 +03:00
kolo 913e7f16ca refactor tests 2025-12-05 16:30:56 +03:00
kolo 20b638c421 refactor tests 2025-12-05 15:54:03 +03:00
kolo b0e6127c1e Update documentation 2025-12-05 10:03:34 +03:00
kolo 67bc8960e7 Merge branch 'docs/create_docs' 2025-12-04 22:13:59 +03:00
kolo 6b9cb586d5 Update documentation 2025-12-04 22:08:49 +03:00
kolo ce7e24b924 feat: impl docs (#4)
The entire public api is covered with documentation in two languages - Russian and English.

the library now supports the latest three versions of python - 3.12, 3.13 and 3.14

minor design changes: now, when a Boolean flag is entered, its value is an empty string, not None.

tests have been adapted to the supported versions of python, readmi has been redesigned in two languages, German is no longer available.
2025-12-04 21:55:19 +03:00
kolo 5c933ab656 Update documentation 2025-12-04 21:49:31 +03:00
kolo e1327c278c Update documentation and code snippets 2025-12-04 21:41:37 +03:00
kolo a57ea45c6f Update workflows 2025-12-04 21:04:59 +03:00
kolo baebeca55b Update documentation 2025-12-04 21:01:52 +03:00
kolo 6be0a94ba9 Update documentation and code snippets 2025-12-04 20:37:44 +03:00
kolo 087c76fed3 Update documentation and code snippets 2025-12-04 20:23:11 +03:00
kolo 723ed2210f Update documentation and code snippets 2025-12-04 18:26:28 +03:00
kolo c6fd01b7bc Update documentation and code snippets 2025-12-04 18:25:39 +03:00
kolo 9179eb8468 Update documentation and code snippets 2025-12-04 18:17:36 +03:00
kolo be083bb64d Update documentation and code snippets 2025-12-04 17:50:24 +03:00
kolo eeb5a752ec Update documentation and code snippets 2025-12-04 17:47:20 +03:00
kolo 9d420af0c5 Update documentation and code snippets 2025-12-04 17:31:45 +03:00
kolo d4129e27e7 Update documentation and code snippets 2025-12-04 17:23:22 +03:00
kolo 974d35fb82 Update documentation and code snippets 2025-12-04 15:46:48 +03:00
kolo da1ee9269a Update documentation and code snippets 2025-12-04 14:54:57 +03:00
kolo dca320297e Update documentation and code snippets 2025-12-03 16:21:22 +03:00
kolo 08660f81d7 Update documentation 2025-12-03 15:53:39 +03:00
kolo 52139e5405 Update documentation and code snippets 2025-12-03 14:30:33 +03:00
kolo 2a0ec209c3 Update documentation 2025-12-03 13:58:44 +03:00
kolo cd3095f42e Update documentation 2025-12-03 13:51:49 +03:00
kolo 2800a7ffc2 Update documentation and code snippets 2025-12-02 22:59:58 +03:00
kolo e6645730f0 Update documentation and code snippets 2025-12-02 22:26:30 +03:00
kolo eae8cdbb58 Update documentation and code snippets 2025-12-02 11:31:24 +03:00
kolo 7c20bf296b Update documentation and code snippets 2025-12-02 11:22:31 +03:00
kolo 2ff47398ba Update documentation 2025-12-02 11:02:09 +03:00
kolo 19906c1b1b Update documentation and code snippets 2025-12-02 10:51:44 +03:00
kolo 2a96dfcabe docs 2025-11-29 11:51:59 +03:00
kolo 47fda23431 docs 2025-11-28 17:24:31 +03:00
kolo d3bf5e703d docs 2025-11-28 14:54:27 +03:00
kolo be178b10c7 refactor and optimize argspace 2025-11-28 14:31:51 +03:00
kolo 1eaf2b6333 update 2025-11-27 21:50:30 +03:00
kolo e5be7b5d99 docs 2025-11-21 21:09:29 +03:00
kolo 2e76f68d4a docs 2025-11-21 19:41:35 +03:00
kolo 8edd59c1b8 docs 2025-11-07 21:25:35 +03:00
kolo 16e7cc21fb docs 2025-11-07 17:00:34 +03:00
kolo 4da876b774 docs 2025-11-04 11:21:35 +03:00
kolo 7b85b0f08d docs 2025-11-03 19:16:21 +03:00
kolo 270e91f705 Update translations 2025-11-03 19:01:43 +03:00
kolo 767d742060 docs 2025-11-03 14:53:07 +03:00
kolo b37096d790 add testing doc 2025-11-03 14:23:24 +03:00
kolo ad8c3af532 docs 2025-11-03 14:17:12 +03:00
kolo 02b02793d0 docs 2025-11-03 12:18:56 +03:00
kolo f0a18e89c8 docs 2025-11-02 18:34:33 +03:00
kolo 6f90712a17 docs 2025-11-02 18:02:48 +03:00
kolo 239e582241 docs 2025-11-02 15:30:41 +03:00
kolo 4967ec3d7f docs 2025-11-02 14:21:03 +03:00
kolo 7e02694cb0 docs 2025-11-02 01:19:59 +03:00
kolo 9c58c10152 docs 2025-11-02 01:04:31 +03:00
kolo 64c984a704 docs 2025-11-02 01:04:00 +03:00
kolo 15f97eab61 docs 2025-11-02 00:36:06 +03:00
kolo df7313912c docs 2025-11-02 00:17:28 +03:00
kolo acddb1fbc6 docs 2025-11-01 12:00:23 +03:00
kolo 9b28ef17ff docs 2025-11-01 11:54:46 +03:00
kolo e4a5c6d398 docs 2025-11-01 11:38:48 +03:00
kolo 0598f6e7a5 update docs 2025-11-01 11:27:46 +03:00
kolo c3395a3922 pretty gitignore 2025-11-01 10:25:56 +03:00
kolo b0924a9e89 dcos 2025-10-31 22:59:19 +03:00
kolo 1f15b4c093 docs 2025-10-28 10:34:34 +03:00
kolo bc6cb583a7 docs 2025-10-28 09:38:07 +03:00
kolo 7b40fff4c5 docs 2025-10-27 11:59:03 +03:00
kolo fc8597504f docs 2025-10-23 22:41:29 +03:00
kolo 667aeccc38 fix ci 2025-10-22 14:46:50 +03:00
kolo c88c1ac1cc fix ci 2025-10-22 14:01:27 +03:00
kolo ec42e63d80 fix ci and pyproject 2025-10-22 13:58:49 +03:00
kolo 4f5481fa70 tests 2025-10-22 13:40:26 +03:00
kolo f38da15bdb docs and fix 2025-10-21 22:56:29 +03:00
kolo 90e80d3454 docs 2025-10-21 12:19:05 +03:00
kolo 8a8a1739e7 docs 2025-10-21 11:54:36 +03:00
kolo bf6fe0f9ee docs 2025-10-21 10:33:46 +03:00
kolo 9ac24926af docs 2025-10-20 16:38:17 +03:00
kolo 6fa431a27a docs 2025-10-19 23:28:24 +03:00
kolo 87d232e835 docs 2025-10-19 23:26:06 +03:00
kolo 1314b11827 docs 2025-10-19 22:44:49 +03:00
kolo d146fc6b6b docs 2025-10-19 22:31:02 +03:00
kolo 9ff00ee785 docs 2025-10-19 21:10:07 +03:00
kolo 5d54375f14 docs 2025-10-19 20:34:23 +03:00
kolo 02bc775148 docs 2025-10-19 17:07:25 +03:00
kolo af73b9067d docs 2025-10-19 16:24:35 +03:00
kolo 67ac8c53ca docs 2025-10-19 16:21:44 +03:00
kolo dcbe03d08a docs 2025-10-19 16:20:16 +03:00
kolo 5b5668593c fix metadata 2025-10-19 15:12:18 +03:00
kolo f52932dc2e new metadata 2025-10-19 02:08:19 +03:00
kolo b6e5c57b8a docs 2025-10-19 01:13:14 +03:00
kolo 8324d3e5a2 docs 2025-10-18 02:04:06 +03:00
kolo a5af8337f3 Merge branch 'main' into docs/create_docs 2025-10-17 22:06:03 +03:00
kolo a2ac6a608f fix 2025-10-17 21:56:56 +03:00
kolo e4bff84c38 Merge pull request #5 from koloideal/feat/user_data_in_response
feat: bridge data between handlers, new tests for Response
2025-10-17 21:52:38 +03:00
kolo cd58f2a5d3 feat: bridge data between handlers, new tests for Response 2025-10-17 21:51:19 +03:00
kolo 182467502d fix: removing core documentation files, as there are separate pull requests for that 2025-10-17 21:11:12 +03:00
kolo db04a5bba7 docs: add new page in docs - Flags 2025-10-17 21:03:37 +03:00
kolo d37688392a docs: fix all references 2025-10-17 19:23:31 +03:00
kolo a25ede147f docs: continue making docs 2025-10-17 01:09:06 +03:00
kolo c87a0ce547 continue making docs 2025-10-16 18:51:07 +03:00
kolo 4e30aae916 fix ci 2025-10-16 17:03:18 +03:00
kolo 051b6f8b50 fix ci 2025-10-16 15:53:59 +03:00
kolo 5c14f9b8bc fix ci 2025-10-16 15:41:08 +03:00
kolo c38d539e33 fix ci 2025-10-16 09:43:51 +03:00
kolo cbf9c11a63 fix ci 2025-10-16 09:33:46 +03:00
kolo dfec91c509 fix ci 2025-10-16 09:14:47 +03:00
kolo eb18730789 fix ci 2025-10-15 19:25:04 +03:00
kolo 19716bdb5e fix ci 2025-10-15 19:23:01 +03:00
kolo 02687f5acd add new lang 2025-10-15 19:16:34 +03:00
kolo 7f5234b67a docs: create index.rst 2025-10-15 16:37:53 +03:00
kolo a4543cee92 docs: update translations 2025-10-15 16:23:52 +03:00
kolo 074ace7d54 fix ci 2025-10-15 16:17:52 +03:00
kolo e68a6c48ac fix ci 2025-10-15 15:31:45 +03:00
kolo fba2021114 fix ci 2025-10-15 15:30:53 +03:00
kolo 51d54ee9c8 fix ci 2025-10-15 15:25:31 +03:00
kolo 6359479b5b fix ci 2025-10-15 15:24:12 +03:00
kolo 4db3573292 fix conf 2025-10-15 15:23:17 +03:00
kolo 0cb41628dd fix img 2025-10-15 14:53:36 +03:00
kolo 648f9da2c6 fix img 2025-10-15 14:52:28 +03:00
kolo 79e768f943 img 2025-10-15 14:51:36 +03:00
kolo 2275ec1d00 docs 2025-10-15 14:47:36 +03:00
kolo bd37fab1ce continue create docs 2025-10-15 14:26:33 +03:00
kolo 6e3da8b4e4 docs: create index.rst 2025-10-15 13:40:19 +03:00
kolo f696805bc6 continue create docs 2025-10-15 11:22:20 +03:00
kolo 0fca3af35d start create docs 2025-10-14 22:34:19 +03:00
kolo a5e72161ef imports sort 2025-10-13 14:28:11 +03:00
kolo 36b4d16610 fix public api 2025-10-13 14:23:47 +03:00
kolo 4a895df52c feat: start make docs 2025-10-13 02:03:49 +03:00
kolo 35707e078e Merge pull request #3 from koloideal/feat/di
Implementation of the Dependency Injection principle
2025-10-13 01:55:28 +03:00
kolo 078cbdc4a8 fix typechecker error, chage version in readme and etc 2025-10-13 01:51:38 +03:00
kolo 462a8088e9 impl di in handlers with support custom provider 2025-10-13 01:13:28 +03:00
kolo e2753ef904 initial commit in new pr 2025-10-12 00:14:42 +03:00
kolo 8dfb95ec91 fix: docs config 2025-10-11 20:15:19 +03:00
kolo e67d08970f fix: docs config 2025-10-11 20:03:36 +03:00
kolo 1e5b220a22 feat/dcos 2025-10-11 19:59:50 +03:00
kolo 6f4f8c407a Merge pull request #2 from koloideal/feat/full_support_argparser
Added support for optional parameters for various types of arguments
2025-10-11 19:39:36 +03:00
kolo 2b76bea318 fix: tests, imports 2025-10-11 19:37:23 +03:00
kolo e481ee8775 extend arguments 2025-10-11 18:29:11 +03:00
kolo 0a1d462090 step by step 2025-10-09 22:01:06 +03:00
kolo b3b5e2e8a8 extend arguments 2025-10-09 20:23:52 +03:00
kolo 0bdc3f07c2 initial commit in new pr 2025-10-08 21:51:10 +03:00
kolo 77416cf22c release 1.1.1 2025-10-08 20:49:29 +03:00
kolo b6c84f1a91 fix ci 2025-10-08 13:44:12 +03:00
kolo c2d235e576 fix ci 2025-10-08 13:42:01 +03:00
kolo f7f5db58aa fix ci 2025-10-08 13:40:20 +03:00
kolo 73303b1c08 ref: typehints, enum instead of raw string, abc and other (#1)
Full code coverage with annotations, fixing errors in various linters: ruff, wps, etc. Fixing errors in type checkers: ty, mypy, pyright. Formatting and bringing code to a consistent style, applying best practices in various aspects.
2025-10-08 13:37:31 +03:00
kolo 22f1171192 fix: link to img in readme 2025-08-12 12:26:37 +03:00
kolo a844095fdc Update README.de.md 2025-08-06 14:57:31 +03:00
kolo a7c6a14705 Update README.md 2025-08-06 14:56:24 +03:00
kolo cfdb37330e Update README.ru.md 2025-08-06 14:52:33 +03:00
kolo aef6a9ca38 update .gitignore 2025-07-04 18:31:52 +03:00
kolo c8e0729be8 fix bugs 2025-05-27 14:19:54 +03:00
kolo c2bbc5f15d first steps sor adding metrics tests 2025-05-24 00:39:39 +03:00
kolo 0acbf54e44 first steps sor adding metrics tests 2025-05-23 22:12:12 +03:00
kolo c3d9541330 working 2025-05-23 14:33:13 +03:00
kolo f6561de9b3 wotk 2025-05-22 20:26:48 +03:00
kolo bebd84969b add Enum PossibleValues for bool values as values of possible_values argument in Flag 2025-05-22 12:10:32 +03:00
kolo 365347ea7f some fix 2025-05-21 17:01:35 +03:00
kolo 33cb528b1d some fix 2025-05-21 13:32:45 +03:00
kolo fd287c5da0 fix type hints with ty help, add ability to configure stdout capture when handling input by the router 2025-05-20 22:44:47 +03:00
kolo 45f410e3e8 make pre_cycle_setup faster on 4 sec, start implemtnation disable redirect stdout in router 2025-05-19 10:31:05 +03:00
kolo 8b06e9cd39 add metrics concept 2025-05-12 16:22:29 +03:00
kolo c38fe10006 translate readme on de 2025-05-10 22:07:52 +03:00
kolo 03cbc64f48 translate readme 2025-05-10 21:56:34 +03:00
kolo cbf7d3c578 new warning when triggers or aliases overlap 2025-05-10 21:31:59 +03:00
kolo ea2d068022 change dataclass to enum 2025-05-10 20:13:42 +03:00
kolo 5991851207 Update README.md 2025-05-10 00:29:03 +03:00
kolo f628c3b5b5 v1.0.2 2025-05-10 00:11:57 +03:00
kolo 05379712f4 some fix 2025-05-09 23:33:54 +03:00
kolo ed1cbf0fcf stable version 2025-05-09 23:27:34 +03:00
kolo 471f05369b Merge branch 'dev' of https://github.com/koloideal/Argenta into dev 2025-05-09 23:25:47 +03:00
kolo 13f7e33db1 ruff format 2025-05-09 23:25:21 +03:00
kolo 9a78aa9263 ruff check 2025-05-09 23:24:12 +03:00
kolo 58ccd6b26d Update README.md 2025-05-09 23:20:45 +03:00
kolo 73144f7ba4 Update README.md 2025-05-09 23:19:07 +03:00
kolo 650f4c9036 some fix 2025-05-09 18:23:08 +03:00
kolo 393f5c7d81 fix 2025-05-08 23:43:08 +03:00
kolo 9eb2bb6c46 new imgs 2025-05-08 23:37:42 +03:00
kolo 79b275eac7 some fix 2025-05-08 01:08:11 +03:00
kolo 07ac2af71e some fix 2025-05-07 19:14:19 +03:00
kolo c4b3aa7db8 working 2025-05-07 02:15:42 +03:00
kolo 61ef6a6466 all tests passed 2025-05-06 21:53:53 +03:00
kolo 477f3a7dec starting refactor tests 2025-05-04 16:40:10 +03:00
kolo adf3431388 more beautiful typehints warning 2025-05-04 03:08:54 +03:00
kolo 83955aa046 first beta - adding hints for similar commands, now - feature freezing 2025-05-04 02:13:05 +03:00
kolo 5a17e916eb work on stable major version 2025-04-30 15:48:38 +03:00
kolo 1159dda16e work on Response model 2025-04-30 00:08:49 +03:00
kolo 315508a36e work on Response 2025-04-29 20:40:47 +03:00
kolo 9d6598c4e0 work on Response model 2025-04-29 00:07:32 +03:00
kolo eb43806da6 new model - Response 2025-04-28 02:21:34 +03:00
kolo e076dbf84f new img in docs 2025-04-27 23:43:14 +03:00
kolo 2f090b6b47 new img in docs 2025-04-27 23:42:56 +03:00
kolo c9dbf2bbae fix print framed text with static dividing line 2025-04-27 23:27:08 +03:00
kolo e768c1bd2c fix 2025-04-27 21:29:14 +03:00
kolo 408450ec12 fix 2025-04-27 21:20:44 +03:00
kolo 106ca058be new tests 2025-04-27 14:11:01 +03:00
kolo b5ddfb3b35 new tests 2025-04-27 13:28:11 +03:00
kolo 61e4502e41 work, fix etc. 2025-04-26 22:23:35 +03:00
kolo 9b2fc87e33 release v1.0.0a1 2025-04-25 02:29:44 +03:00
kolo 89f09c42f8 pre-release v1.0.0 2025-04-24 21:26:41 +03:00
kolo 5bcae8fe68 Update README.md 2025-04-24 17:40:53 +03:00
kolo ca58008431 fix 2025-04-23 22:07:57 +03:00
kolo 30974f48eb fix 2025-04-23 22:06:10 +03:00
kolo df4ba080b0 new docs 2025-04-23 22:02:02 +03:00
kolo f93930d712 work 2025-04-23 21:45:04 +03:00
kolo 036c17ec9a last steps work on new docs, full complete write docstring for all objects 2025-04-23 20:54:03 +03:00
kolo 7281fdeabf new app preview img in docs 2025-04-23 20:50:31 +03:00
kolo 051ec6df28 steps 2025-04-20 23:58:15 +03:00
kolo 00a1e11fc1 new docs 2025-04-19 12:13:29 +03:00
kolo 584df9ba69 new docs 2025-04-18 12:50:30 +03:00
kolo a649022f1d work on docstrings 2025-04-15 23:49:51 +03:00
kolo 26a9d8a6da work on 2025-04-15 22:26:20 +03:00
kolo 9522b0161a work on 2025-04-15 01:09:03 +03:00
kolo e189f8d9aa big step 2025-04-14 16:38:53 +03:00
kolo 3ef8707cfa big step 2025-04-14 14:54:17 +03:00
kolo a5fdcab862 work on 2025-04-14 01:03:24 +03:00
kolo ba035881ee work on support args 2025-04-13 19:24:03 +03:00
kolo 34ebe55531 first steps 2025-04-13 14:39:53 +03:00
kolo 01c9d2dc6d first step 2025-04-13 14:12:08 +03:00
kolo a6db733204 some fix 2025-04-13 13:13:03 +03:00
kolo 8506e4ffcf some fix 2025-04-12 18:07:10 +03:00
kolo 04d3329572 0.5.0-beta 2025-04-11 13:12:44 +03:00
kolo 5bfdde4bd9 now command aliases auto added to autocomlete history for their use 2025-04-10 19:23:57 +03:00
kolo e2dd7e4aea 0.5.0-alpha: support autocomplete, aliases for command, fix many bugs and other 2025-04-10 13:12:36 +03:00
kolo d1d644d422 final adding 2025-04-10 00:23:03 +03:00
kolo 8b496aa782 final work on autocomplete 2025-04-09 23:32:21 +03:00
kolo 592d128ef6 work on autocomplete 2025-04-09 12:16:30 +03:00
kolo b44ee227fd fix many bugs 2025-04-08 20:40:52 +03:00
kolo 0dce4a0d9e refactor app 2025-04-08 10:33:45 +03:00
kolo ca6634c6f0 some fix 2025-04-08 10:04:57 +03:00
kolo c1805af420 final work on dividing line 2025-04-08 00:28:17 +03:00
kolo 0e308ce77f work on dividing line 2025-04-07 19:44:51 +03:00
kolo ab1d335f8e work 2025-04-06 18:57:30 +03:00
kolo 1a2e9d1487 successful adding framed text 2025-04-05 09:58:02 +03:00
kolo 76bcba9340 some 2025-04-05 00:47:32 +03:00
kolo ae9795bd53 some fix and final refactor in readme 2025-04-04 01:43:59 +03:00
kolo 7540728f1b fix 2025-04-03 16:16:05 +03:00
kolo 54da63dd03 fix 2025-04-03 01:14:33 +03:00
kolo 8e08d0fe09 some fix 2025-04-03 01:09:03 +03:00
kolo 55b88f7c8a modified tests 2025-04-02 22:03:30 +03:00
kolo 1cd616336f refactor default view 2025-04-02 21:51:20 +03:00
kolo 253790fe2e work 2025-04-02 16:34:43 +03:00
kolo 1c6f896b73 work 2025-04-02 16:02:22 +03:00
kolo 8810e12551 linter workflow 2025-04-02 00:36:47 +03:00
kolo 285007a59a linter workflow 2025-04-02 00:34:34 +03:00
kolo 6edd17646a final workflow 2025-04-02 00:11:19 +03:00
kolo 154ee25dde test2 workflow 2025-04-02 00:09:48 +03:00
kolo 30cf3cfd06 test workflow 2025-04-02 00:06:48 +03:00
kolo 0d98d80919 Create tests.yml 2025-04-02 00:03:48 +03:00
kolo 54992e55cb some changes in readme 2025-04-01 23:49:17 +03:00
kolo cc8135b733 more working 2025-03-31 23:53:49 +03:00
kolo 5c6fa5151a new models, a model is passed to the command handler instead of a dictionary, removal of checks for intersection of processed triggers in handlers and much, much more 2025-03-31 19:14:42 +03:00
kolo 2918bc9f81 refactor, new model e.t.c. 2025-03-31 01:12:01 +03:00
kolo 6e2fbc23e9 adding __all__ in __init__ 2025-03-28 13:11:40 +03:00
kolo 1ec8ea53b4 new models, logic refactor, renaminf constants and other 2025-03-28 00:54:12 +03:00
kolo 4256d67789 v0.4.1 2025-03-27 00:17:40 +03:00
kolo 0246ff4b22 adding new method for App and new system tests 2025-03-24 10:44:49 +03:00
kolo 956febc757 v0.4.0 2025-03-15 20:50:44 +03:00
kolo beafdd0afd new system tests 2025-03-15 18:47:26 +03:00
kolo b172e2cdc3 new system tests 2025-03-15 11:42:12 +03:00
kolo baaf0e25f3 some fix 2025-03-15 00:08:39 +03:00
kolo 09c40978a1 fix 2025-03-12 13:01:15 +03:00
kolo 0f4f48555e fix 2025-03-12 00:51:11 +03:00
kolo d30515c1a2 v0.3.9 2025-03-11 20:44:06 +03:00
kolo 5a6fc1d8ca first step 2025-03-08 13:49:29 +03:00
kolo e5d6ead38e v0.3.8 2025-03-06 01:35:28 +03:00
kolo b61c151e1c v0.3.8 2025-03-06 01:35:18 +03:00
kolo a57ce490c1 v0.3.7 2025-03-06 00:15:39 +03:00
kolo edbd45f0bf some fix 2025-03-05 15:47:31 +03:00
kolo d59d274bca v0.3.6, final adding in docs 2025-03-05 02:27:10 +03:00
kolo 2bf2144815 work on docs, tests and some fix 2025-03-05 02:20:02 +03:00
kolo 971258728c work on docs 2025-03-04 18:44:45 +03:00
kolo 2c9c8da13c fix 2025-03-04 00:03:15 +03:00
kolo 404758bd91 fix 2025-03-03 18:52:49 +03:00
kolo 8fbf651223 v0.3.5 2025-03-03 14:26:37 +03:00
kolo 459c16ec87 v0.3.5 2025-03-03 14:26:13 +03:00
kolo d9c74310c3 start make tests 2025-03-03 00:10:07 +03:00
kolo 5e6cdc342e v0.3.4 2025-03-02 00:54:34 +03:00
kolo a378163431 v0.3.3 2025-03-01 16:44:33 +03:00
kolo fd4f2e1570 v0.3.2 2025-03-01 00:25:01 +03:00
kolo 3f7c577c29 0.3.1 2025-02-28 16:19:22 +03:00
kolo b72fcc6a11 fix 2025-02-27 01:16:39 +03:00
kolo 158e5eb75a fix 2025-02-25 00:37:11 +03:00
kolo 46cb2f70c5 fix 2025-02-24 19:04:20 +03:00
kolo ef242a5732 fix 2025-02-23 18:53:11 +03:00
kolo f87f102ced v0.3.0 2025-02-23 13:26:12 +03:00
kolo ddf2a2fb10 v0.3.0 2025-02-23 13:25:51 +03:00
kolo eac5358ead work on v0.3.0 2025-02-22 12:14:25 +03:00
kolo 76c18ddbff v0.3.0-alpha 2025-02-21 18:05:40 +03:00
kolo 4eeb4eb182 work on v0.3.0 2025-02-21 17:50:53 +03:00
kolo 905698384a work on v0.3.0 2025-02-21 01:46:03 +03:00
kolo 79ccfbb3b1 work on v0.3.0 2025-02-20 22:10:29 +03:00
kolo a63c46a78b work on v0.3.0 2025-02-19 23:49:38 +03:00
kolo a3a7cbf2e6 work on v0.3.0 2025-02-18 23:35:36 +03:00
kolo a9e545f3d8 work on v0.3.0 2025-02-17 20:57:15 +03:00
kolo 37b62fd69b fix 2025-02-17 00:33:05 +03:00
kolo 0ae86d0b2b work on v0.3.0 2025-02-15 12:05:42 +03:00
kolo ebfd5a80b3 work on v0.3.0 2025-02-13 23:26:01 +03:00
kolo 250704fc88 some fix 2025-02-13 19:31:30 +03:00
264 changed files with 21636 additions and 1525 deletions
+31
View File
@@ -0,0 +1,31 @@
name: mypy
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install uv
uv sync --group typecheckers
- name: Run type checker
run: uv run python -m mypy -p argenta
+31
View File
@@ -0,0 +1,31 @@
name: ruff
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install uv
uv sync --group linters
- name: Run linter
run: uv run python -m ruff check ./src
+34
View File
@@ -0,0 +1,34 @@
name: tests
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install uv
uv sync --group tests
- name: Run tests
run: uv run python -m pytest tests
+323 -14
View File
@@ -1,15 +1,324 @@
#### joe made this: http://goel.io/joe
metrics/reports/diagrams
#### python ####
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
# poetry.lock
# poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
# pdm.lock
# pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
# pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# Redis
*.rdb
*.aof
*.pid
# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/
# ActiveMQ
activemq-data/
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
.idea
argenta/router/__pycache__/
argenta/app/__pycache__/
argenta/__pycache__/
dist
poetry.lock
tests/__pycache__
tests/mock_default_app/handlers/__pycache__/
tests/mock_default_app/__pycache__/
tests/mock_app/local_data_func/__pycache__/
tests/mock_app/handlers/handlers_implementation/__pycache__/
tests/mock_app/handlers/__pycache__/
tests/mock_app/business_logic/__pycache__/
tests/mock_app/__pycache__/
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
# .idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# Streamlit
.streamlit/secrets.toml
#### joe made this: http://goel.io/joe
#### visualstudiocode ####
.vscode/
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
!*.code-workspace
# Built Visual Studio Code Extensions
*.vsix
#### joe made this: http://goel.io/joe
#### jetbrains ####
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based HTTP Client
.idea/httpRequests
http-client.private.env.json
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Apifox Helper cache
.idea/.cache/.Apifox_Helper
.idea/ApifoxUploaderProjectSetting.xml
.zed
+17
View File
@@ -0,0 +1,17 @@
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
jobs:
post_install:
- sphinx-intl build --locale-dir docs/locales
sphinx:
configuration: docs/conf.py
python:
install:
- requirements: docs/requirements.txt
+20
View File
@@ -0,0 +1,20 @@
<a id='changelog-1.2.0'></a>
## 1.2.0 — 2026-02-07
### Added
- 100% coverage of the code base with tests
- 100% coverage with typhints
- 100% coverage of public API documentation in two languages - Russian and English
- cli attributes: highlighting valid commands, redesigned input history with auto-completion, interactive autocomplete selection menu for multiple candidates
- a metrics module that allows you to test the performance of various library units
- implementing a dependency injection pattern through an ioc container
- implementation of a context object for transferring data between handlers within a session
- adding a changelog
### Changed
- increased performance by several times (there will be real numbers in the next releases)
- reworking the internal API, highlighting different layers and reducing connectivity
- reworking the README and adding a translation for it
+66
View File
@@ -0,0 +1,66 @@
# Code of Conduct - Argenta
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, level of experience, education,
socio-economic status, nationality, personal appearance, race and religion.
## Our Standards
Examples of behaviour that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologising to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behaviour include:
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying and enforcing our standards of
acceptable behaviour and will take appropriate and fair corrective action in
response to any instances of unacceptable behaviour.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviours that they deem
inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behaviour may be
reported to the community leaders responsible for enforcement at .
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md)
+264
View File
@@ -0,0 +1,264 @@
<!-- omit in toc -->
# Contributing to Argenta
First off, thanks for taking the time to contribute! ❤️
All types of contributions are encouraged and valued. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues
<!-- omit in toc -->
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Improving The Documentation](#improving-the-documentation)
- [Styleguides](#styleguides)
- [Commit Messages](#commit-messages)
- [Join The Project Team](#join-the-project-team)
## Code of Conduct
This project and everyone participating in it is governed by the
[Argenta Code of Conduct](https://github.com/koloideal/Argenta/blob/main/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior
to .
-----
## I Have a Question
> If you want to ask a question, we assume that you have read the available [Documentation](https://argenta.readthedocs.io).
Before you ask a question, it is best to search for existing [Issues](https://github.com/koloideal/Argenta/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an [Issue](https://github.com/koloideal/Argenta/issues/new).
- Provide as much context as you can about what you're running into.
- Provide project and platform versions (cpython, pip, etc), depending on what seems relevant.
We will then take care of the issue as soon as possible.
<!--
You might want to create a separate issue tag for questions and include it in this description. People should then tag their issues accordingly.
Depending on how large the project is, you may want to outsource the questioning, e.g. to Stack Overflow or Gitter. You may add additional contact and information possibilities:
- IRC
- Slack
- Gitter
- Stack Overflow tag
- Blog
- FAQ
- Roadmap
- E-Mail List
- Forum
-->
-----
## I Want To Contribute
> ### Legal Notice <!-- omit in toc -->
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project licence.
### Reporting Bugs
<!-- omit in toc -->
#### Before Submitting a Bug Report
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://argenta.readthedocs.io). If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/koloideal/Argenta/issues?q=label%3Abug).
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Possibly your input and the output
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
<!-- omit in toc -->
#### How Do I Submit a Good Bug Report?
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to .
<!-- You may add a PGP key to allow the messages to be sent encrypted as well. -->
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
- Open an [Issue](https://github.com/koloideal/Argenta/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
- Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section.
Once it's filed:
- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution).
<!-- You might want to create an issue template for bugs and errors that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
-----
### Suggesting Enhancements
This section guides you through submitting an enhancement suggestion for Argenta, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
<!-- omit in toc -->
#### Before Submitting an Enhancement
- Make sure that you are using the latest version.
- Read the [documentation](https://argenta.readthedocs.io) carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/koloideal/Argenta/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
<!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion?
Enhancement suggestions are tracked as [GitHub issues](https://github.com/koloideal/Argenta/issues).
- Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
- You may want to **include screenshots or screen recordings** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [LICEcap](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and the built-in [screen recorder in GNOME](https://help.gnome.org/users/gnome-help/stable/screen-shot-record.html.en) or [SimpleScreenRecorder](https://github.com/MaartenBaert/ssr) on Linux. <!-- this should only be included if the project has a GUI -->
- **Explain why this enhancement would be useful** to most Argenta users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
<!-- You might want to create an issue template for enhancement suggestions that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
-----
### Your First Code Contribution
Unsure where to begin contributing to Argenta? You can start by looking through `good first issue` and `help wanted` issues on our GitHub repository. These are issues that are well-suited for new contributors.
To get started with your first code contribution, please follow these steps to set up your local development environment.
1. Fork the `Argenta` repository on GitHub.
2. Clone your forked repository to your local machine:
```bash
git clone https://github.com/<YOUR_USERNAME>/Argenta.git
cd Argenta
```
3. Create and activate a Python virtual environment.
```bash
# For macOS/Linux
python3 -m venv .venv
source .venv/bin/activate
# For Windows
python -m venv .venv
.venv\Scripts\activate
```
4. Install the project dependencies, including the development tools.
```bash
pip install -e .[dev]
```
5. Create a new branch for your feature or bug fix. Use a descriptive name, like `fix/login-bug` or `feat/new-widget`.
```bash
git checkout -b your-new-branch-name
```
6. Make your changes! Write your code, and don't forget to add or update tests for your changes.
7. Run the test suite to ensure everything is working correctly.
```bash
python -m pytest tests
```
8. Commit your changes following our commit message styleguide and push them to your fork.
```bash
git add .
git commit -m "feat(widget): add the new super widget"
git push origin your-new-branch-name
```
9. Open a Pull Request from your forked branch to the `main` branch of the official Argenta repository. Provide a clear description of the problem and your solution. Include the relevant issue number if applicable.
-----
### Improving The Documentation
Good documentation is crucial for any project. We use Sphinx to generate our documentation from source files located in the `docs/` directory. We welcome any improvements, from fixing a simple typo to writing a whole new section.
We support documentation in two languages: Russian and English
To improve the documentation, you can follow a similar workflow as for code contributions:
1. Ensure your development environment is set up as described in the "Your First Code Contribution" section.
2. Navigate to the documentation directory.
```bash
cd docs
```
3. Make the necessary changes to the **Russian** version of the documentation - ``docs/index.rst`` and ``docs/root/*``
4. To build the documentation locally and see your changes, run:
```bash
make live-ru
```
5. Open `127.0.0.1:8000` in your web browser to preview the generated documentation.
6. Make your desired changes to the `.rst` or `.md` files in the `docs/source` directory.
7. After completing the work on the Russian documentation, it is necessary to create an English translation:
```bash
make update-langs
```
8. After updating the translation template, update the necessary translation files located at ``docs/locales/en/LC_MESSAGES``
8. Once you are happy with your changes, commit them and open a Pull Request. Use the `docs:` prefix in your commit message.
---
## Styleguides
### Commit Messages
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for our commit messages. This leads to more readable messages that are easy to follow when looking through the project history and allows for automated changelog generation.
Each commit message consists of a **header**, a **body**, and a **footer**.
```
<type>(<scope>): <subject>
[optional body]
[optional footer]
```
The `<type>` must be one of the following:
* **feat**: A new feature for the user.
* **fix**: A bug fix for the user.
* **docs**: Documentation only changes.
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, etc).
* **refactor**: A code change that neither fixes a bug nor adds a feature.
* **perf**: A code change that improves performance.
* **test**: Adding missing tests or correcting existing tests.
* **chore**: Changes to the build process or auxiliary tools and libraries.
#### Examples
A simple fix:
``fix: correct typo in user authentication flow``
A new feature with a scope:
``feat(api): add new endpoint for user profiles``
---
## Join The Project Team
We are always looking for enthusiastic and dedicated people to join our project team. If you are a regular contributor and have shown a deep understanding of the project's goals and architecture, you might be a good candidate to become a maintainer.
Active members of the community can become team members. This typically involves:
* Consistently contributing high-quality code and documentation.
* Helping other users by answering questions and triaging issues.
* Reviewing Pull Requests from other contributors with constructive feedback.
If you are interested in becoming a more permanent part of the team, the best way to start is by being an active and helpful member of the community. The existing maintainers will notice your efforts and may reach out with an invitation to join the team.
+77 -245
View File
@@ -1,273 +1,105 @@
# Argenta
![preview](https://i.ibb.co/whkMfHw5/a-minimalist-logo-design-featuring-the-t-t-GXhfz-NFRwi-k-ROq-NMd-LWA-R7-6ru-YSh-G0kz-LKr5t-ZQ.jpg)
**Argenta** is a simple and elegant framework for building modular CLI applications. It provides a clean and intuitive way to create context-aware command-line tools with isolated command scopes.
Argenta is the **"Simplest"**, **"Most Modular"**, and **"Most Elegant"** way to build interactive CLI applications in Python.
📖 **Read the full documentation:** [argenta.readthedocs.io](https://argenta.readthedocs.io/)<br>
🌍 **Other languages:** [RU](https://github.com/koloideal/Argenta/blob/main/README.ru.md)
---
## Описание
**Argenta** — это библиотека для создания CLI-приложений на Python. Она предоставляет удобные инструменты для маршрутизации команд и обработки пользовательского ввода.
![preview](https://vhs.charm.sh/vhs-2hvLCEgclmwZPJZt1vLGKi.gif)
---
**Argenta** allows you to build interactive CLI applications incredibly easily. There's no need to manually parse complex command structures or manage state transitions — just use routers and commands!
# Установка
```bash
pip install argenta
```
or
```bash
poetry add argenta
## ✨ Installing Argenta
Argenta is available on ``PyPI``:
```console
$ python -m pip install argenta
```
---
or using ``uv``:
```console
$ uv add argenta
```
Argenta officially supports Python 3.12+.
## 🚀 Supported Features & Best Practices
Argenta is ready for the demands of building scalable, robust and maintainable CLI applications.
- **Interactive Sessions**: Unlike traditional CLI tools, ``Argenta`` creates cyclic sessions, allowing users to execute commands sequentially without restarting the application.
- **Declarative Syntax**: Commands and their handlers are declared using simple decorators, making the code intuitive and allowing you to focus on "what" you want to do, not "how".
- **Native DI**: Thanks to integration with [dishka](https://dishka.readthedocs.io/en/stable/), you can easily inject dependencies directly into command handlers, simplifying testing, avoiding mutable globals, and much more.
- **Automatic Validation and Parsing**: The library handles command-line flags and arguments processing, including parsing, validation, and type conversion.
- **Flexible Configuration**: You can easily customize system messages, output formatting, create custom handlers for non-standard behavior, and more.
Need something more? Create an **issue**, we're open to suggestions.
## 📝 Why did we create this?
Building complex CLI applications often requires managing different contexts and command scopes. For example, when creating a utility similar to the Metasploit Framework, users need to enter specific scopes (like selecting a scanning module) and then access commands specific only to that context.
Traditional CLI frameworks don't provide an elegant way to handle this kind of modular, context-aware architecture. Argenta was built to solve this problem by providing a simple and concise way to encapsulate CLI functionality in isolated, abstracted environments.
We believe that building CLI applications should be as pleasant as building web applications with modern frameworks. Argenta brings the router pattern and clean separation of concerns to the CLI world.
## 🚀 Quick Start
Here's a simple example to get you started:
# Быстрый старт
Пример базового CLI-приложения с Argenta:
```python
#routers.py
from argenta.router import Router
# routers.py
from argenta import Router, Response
from argenta.command import Flag, Command
router = Router()
@router.command("hello")
def hello():
@router.command(Command("hello"))
def handler(response: Response):
"""A simple hello world command"""
print("Hello, world!")
@router.unknown_command
def unlnown_command(command):
print(f'Command "{command}" undefined')
@router.command(Command("greet", flags=Flag('name')))
def greet_handler(response: Response):
"""Greet a user by name"""
name_flag = response.input_flags.get_flag_by_name('name')
if name_flag:
print(f"Hello, {name_flag.input_value}!")
else:
print("Hello, Stranger!")
```
```python
#main.py
from argenta.app import App
from routers import router
app: App = App()
```python
# main.py
from argenta import App, Orchestrator
from .routers import router
app = App()
orchestrator = Orchestrator()
def main() -> None:
# Include your routers
app.include_router(router)
app.start_polling()
# Start the interactive CLI
orchestrator.start_polling(app)
if __name__ == '__main__':
main()
```
---
That's it! You now have a fully functional interactive CLI application.
# Техническая документация
## 📚 Documentation
Full documentation is available at [argenta.readthedocs.io](https://argenta.readthedocs.io/)
---
## declared *classes* :
---
### *class* :: `App`
Класс, определяющий поведение и состояние приложения
#### Конструктор
```python
App(prompt: str = 'Enter a command',
initial_greeting: str = '\nHello, I am Argenta\n',
farewell_message: str = '\nGoodBye\n',
exit_command: str = 'Q',
exit_command_description: str = 'Exit command',
exit_command_title: str = 'System points:',
ignore_exit_command_register: bool = True,
ignore_command_register: bool = False,
line_separate: str = '',
command_group_description_separate: str = '',
repeat_command_groups: bool = True,
print_func: Callable[[str], None] = print)
```
**Аргументы:**
- **name : mean**
- `prompt` (`str`): Сообщение перед вводом команды.
- `initial_greeting` (`str`): Приветственное сообщение при запуске.
- `farewell_message` (`str`): Сообщение при выходе.
- `exit_command` (`str`): Команда выхода (по умолчанию `'Q'`).
- `exit_command_description` (`str`): Описание команды выхода.
- `exit_command_title` (`str`): Заголовок перед списком команд выхода.
- `ignore_exit_command_register` (`bool`): Игнорировать регистр команды выхода.
- `ignore_command_register` (`bool`): Игнорировать регистр всех команд.
- `line_separate` (`str`): Разделительная строка между командами.
- `command_group_description_separate` (`str`): Разделитель между группами команд.
- `repeat_command_groups` (`bool`): Повторять описание команд перед вводом.
- `print_func` (`Callable[[str], None]`): Функция вывода текста в терминал (по умолчанию `print`).
---
#### **declared *methods***
---
**App().**`start_polling() -> None`
*method mean* **::** запускает жизненный цикл приложения
---
**App().**`include_router(router: Router, is_main: bool = False) -> None`
*param* `router: Router` **::** регистрируемый роутер
*param* `is_main: bool` **::** будет ли являться регистрируемый роутер главным
*example* **::** `True` или `False`
*method mean* **::** регистрирует роутер в приложении
---
**App().**`set_initial_message(message: str) -> None`
*param* `message: str` **::** устанавливаемое приветственное сообщение
*example* **::** `"Hello, I'm a cli example app"`
*method mean* **::** устанавливает сообщение, которое будет отображено при запуске программы
---
**App().**`set_farewell_message(message: str) -> None`
*param* `message: str` **::** устанавливаемое сообщение при выходе
*example* **::** `"GoodBye !"`
*method mean* **::** устанавливает сообщение, которое будет отображено при выходе
---
**App().**`set_description_message_pattern(pattern: str) -> None`
*param* `pattern: str` **::** паттерн описания команды при её выводе в консоль
*example* **::** `"[{command}] *=*=* {description}"`
*method mean* **::** устанавливает приветственное сообщение
---
**App().**`get_main_router() -> Router`
*method mean* **::** возвращает `Router()`, который является главным в приложении
---
**App().**`get_all_app_commands() -> list[str]`
*method mean* **::** возвращает список команд всех зарегистрированных роутеров, сохраняя их регистр
---
#### Примечания
- Среди зарегистрированных в приложении роутеров должен быть один главный, является ли роутер главным
определяется значением аргумента `is_main` равным `True`, в методе `App().include_router()`, который по умолчанию равен
`False`, если в приложении зарегистрирован лишь один роутер, то он неявно устанавливается главным, если
зарегистрировано больше одного роутера, то требуется явное указание главного. При регистрации более одного
главного роутера вызывается исключение `OnlyOneMainRouterIsAllowedException`. При регистрации более одного
роутера и отсутствии указания главного вызывается исключение `MissingMainRouterException`
- В устанавливаемом паттерне сообщения описания команды необходимы быть два ключевых слова:
`command` и `description`, каждое из которых должно быть заключено в фигурные скобки, после обработки
паттерна на места этих ключевых слов будут подставлены соответствующие значения команды, при отсутствии
этих двух ключевых слов будет вызвано исключение `InvalidDescriptionMessagePatternException`
- Команды приложения не должны повторяться, при значении атрибута `ignore_command_register` равным `True`
допускается создание обработчиков для разных регистров одинаковых символов в команде, для примера `u` и `U`,
при значении атрибута `ignore_command_register` класса `App` равным `False` тот же пример вызывает исключение
`RepeatedCommandInDifferentRoutersException`. Исключение вызывается только при наличии пересекающихся команд
у __<u>разных</u>__ роутеров
- У главного обработчика должен быть зарегистрирован обработчик неизвестных команд:
```python
router = Router()
@router.unknown_command
def unknown_command(command):
print(f'Command "{command}" undefined')
```
При отсутствии обработчика неизвестных команд у главного роутера будет вызвано исключение
`MissingHandlerForUnknownCommandsException`. При регистрации обработчика неизвестных команд у
__<u>не</u>__ главного роутера будет вызвано исключение `HandlerForUnknownCommandsOnNonMainRouterException`
#### Исключения
- `InvalidRouterInstanceException` — Переданный объект в метод `App().include_router()` не является экземпляром класса `Router`.
- `InvalidDescriptionMessagePatternException` — Неправильный формат паттерна описания команд.
- `OnlyOneMainRouterIsAllowedException` — Регистрация более одного главного роутера.
- `MissingMainRouterException` — Отсутствует главный роутер.
- `MissingHandlerForUnknownCommandsException` — В основном роутере отсутствует обработчик неизвестных команд.
- `HandlerForUnknownCommandsOnNonMainRouterException` — Обработчик неизвестных команд определён не у основного роутера.
- `NoRegisteredRoutersException` — Отсутствуют зарегистрированные роутеры.
- `NoRegisteredHandlersException` — У роутера нет ни одного обработчика команд.
- `RepeatedCommandInDifferentRoutersException` — Одна и та же команда зарегистрирована в разных роутерах.
---
### *class* :: `Router`
Класс, который определяет и конфигурирует обработчики команд
#### Конструктор
```python
Router(title: str = 'Commands group title:',
name: str = 'subordinate')
```
**Аргументы:**
- **name : mean**
- `title` (`str`): Заголовок группы команд.
- `name` (`str`): Персональное название роутера
#### **declared *methods***
---
**`@`Router().**`command(command: str, description: str = None)`
*param* `command: str` **::** строковый триггер, который будет выполнять указанные действия
*example* **::** `U` / `update` / `ExaMPLE`
*param* `description: str` **::** описание команды, которое будет выведено в консоль
*example* **::** `description for update command` или `example description`
*method mean* **::** декоратор регистрирует функцию как обработчик команды
---
**`@`Router().**`unknown_command`
*method mean* **::** декоратор регистрирует функцию как обработчик неизвестных команд
---
**Router().**`get_name() -> str`
*method mean* **::** возвращает установленное название роутера
---
**Router().**`get_title() -> str`
*method mean* **::** возвращает установленный заголовок группы команд данного роутера
---
**Router().**`get_router_info() -> dict`
*method mean* **::** возвращает информацию о роутере
---
**Router().**`get_all_commands() -> list[str]`
*method mean* **::** возвращает все зарегистрированные команды для данного роутера
---
#### Исключения
- `InvalidCommandInstanceException` - Переданный объект для регистрации команды не является строкой
- `InvalidDescriptionInstanceException` - Переданный объект для регистрации описания команды не является строкой
- `UnknownCommandHandlerHasAlreadyBeenCreatedException` - Обработчик неизвестных команд уже создан
- `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
+108
View File
@@ -0,0 +1,108 @@
![preview](https://i.ibb.co/whkMfHw5/a-minimalist-logo-design-featuring-the-t-t-GXhfz-NFRwi-k-ROq-NMd-LWA-R7-6ru-YSh-G0kz-LKr5t-ZQ.jpg)
**Argenta** — это простой и элегантный фреймворк для создания модульных CLI-приложений. Он предоставляет чистый и интуитивный способ создания контекстно-зависимых инструментов командной строки с изолированными областями команд.
Argenta — это **"Самый простой"**, **"Самый модульный"** и **"Самый элегантный"** способ создания интерактивных CLI-приложений на Python.
📖 **Читайте полную документацию:** [argenta.readthedocs.io](https://argenta.readthedocs.io/)<br>
🌍 **Другие языки:** [EN](https://github.com/koloideal/Argenta/blob/main/README.md)
---
![preview](https://vhs.charm.sh/vhs-2hvLCEgclmwZPJZt1vLGKi.gif)
**Argenta** позволяет создавать интерактивные CLI-приложения невероятно легко. Не нужно вручную парсить сложные структуры команд или управлять переходами состояний — просто используйте роутеры и команды!
## ✨ Установка Argenta
Argenta доступна на ``PyPI``:
```console
$ python -m pip install argenta
```
или с использованием ``uv``:
```console
$ uv add argenta
```
Argenta официально поддерживает Python 3.12+.
## 🚀 Поддерживаемые возможности и лучшие практики
Argenta готова к требованиям создания масштабируемых, надежных и поддерживаемых CLI-приложений.
- **Интерактивные сессии**: В отличие от традиционных CLI-инструментов, ``Argenta`` создаёт циклические сессии, позволяя пользователю выполнять команды последовательно, не перезапуская приложение.
- **Декларативный синтаксис**: Команды и их обработчики объявляются с помощью простых декораторов, что делает код интуитивно понятным и позволяет сосредоточиться на том, "что" вы хотите сделать, а не "как".
- **Нативный DI**: Благодаря интеграции с [dishka](https://dishka.readthedocs.io/en/stable/), вы можете легко внедрять зависимости прямо в обработчики команд, что упрощает их тестирование, позволяет избежать мутабельных глобалов и многое другое.
- **Автоматическая валидация и парсинг**: Библиотека берёт на себя обработку флагов и аргументов командной строки, включая их парсинг, валидацию и преобразование типов.
- **Гибкая настройка**: Вы можете легко кастомизировать системные сообщения, форматирование вывода, ссоздавать кастомные обработчики нестандартного поведения и т.д.
Нужно что-то еще? Создайте **issue**, мы открыты к предложениям.
## 📝 Зачем мы это создали?
Создание сложных CLI-приложений часто требует управления различными контекстами и областями команд. Например, при создании утилиты, подобной Metasploit Framework, пользователям нужно входить в определенные области (например, выбирать модуль сканирования), а затем получать доступ к командам, специфичным только для этого контекста.
Традиционные CLI-фреймворки не предоставляют элегантного способа обработки такой модульной, контекстно-зависимой архитектуры. Argenta была создана для решения этой проблемы, предоставляя простой и лаконичный способ инкапсуляции CLI-функциональности в изолированные, абстрагированные среды.
Мы считаем, что создание CLI-приложений должно быть таким же приятным, как создание веб-приложений с современными фреймворками. Argenta привносит паттерн роутеров и чистое разделение ответственности в мир CLI.
## 🚀 Быстрый старт
Вот простой пример для начала работы:
```python
# routers.py
from argenta import Router, Response
from argenta.command import Flag, Command
router = Router()
@router.command(Command("hello"))
def handler(response: Response):
"""Простая команда hello world"""
print("Привет, мир!")
@router.command(Command("greet", flags=Flag('name')))
def greet_handler(response: Response):
"""Поприветствовать пользователя по имени"""
name_flag = response.input_flags.get_flag_by_name('name')
if name_flag:
print(f"Привет, {name_flag.input_value}!")
else:
print("Привет, Незнакомец!")
```
```python
# main.py
from argenta import App, Orchestrator
from .routers import router
app = App()
orchestrator = Orchestrator()
def main() -> None:
# Подключите ваши роутеры
app.include_router(router)
# Запустите интерактивный CLI
orchestrator.start_polling(app)
if __name__ == '__main__':
main()
```
Вот и всё! Теперь у вас есть полностью функциональное интерактивное CLI-приложение.
## 📚 Документация
Полная документация доступна на [argenta.readthedocs.io](https://argenta.readthedocs.io/)
---
MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
+54
View File
@@ -0,0 +1,54 @@
# Security Policy
The Argenta team takes security seriously. We appreciate your efforts to responsibly disclose your findings, and we will make every effort to acknowledge your contributions.
## Supported Versions
This table shows the versions of Argenta that are currently supported with security updates.
| Version | Supported |
|---------|-----------------|
| 1.1.x | ✅ |
| < 1.1 | ❌ |
## Reporting a Vulnerability
If you believe you have found a security vulnerability in Argenta, please report it to us through one of the following methods:
- **Email**: Send a detailed report to `kolo.is.main@gmailcom`.
- **GitHub Security Advisories**: You can create a new security advisory directly in the Argenta repository.
**Please do not report security vulnerabilities through public GitHub issues.**
### What to Include
To help us understand and resolve the issue quickly, please include the following information in your report:
- A clear and descriptive title.
- The affected version(s) of Argenta.
- A detailed description of the vulnerability.
- Step-by-step instructions to reproduce the issue (a Proof-of-Concept).
- The potential impact of the vulnerability.
- Any suggested mitigations or fixes, if you have any.
You can expect a response from us within 48 hours to acknowledge receipt of your report.
## Disclosure Process
1. Upon receiving a vulnerability report, we will assign it to a team member and begin our investigation.
2. We will confirm the vulnerability and determine its severity.
3. We will work on a patch to address the issue.
4. Once the patch is ready, we will coordinate with you to schedule a release and a public disclosure. We prefer to disclose vulnerabilities through a GitHub Security Advisory.
5. We will credit you for your discovery in the advisory, unless you prefer to remain anonymous.
## Security Best Practices
As a user of Argenta, we recommend the following best practices to keep your application secure:
- Always use the latest version of Argenta.
- Regularly scan your project's dependencies for known vulnerabilities.
- If your application handles sensitive data, ensure it is stored and transmitted securely.
## Bug Bounty Program
Currently, we do not have a formal bug bounty program. However, we deeply appreciate the work of security researchers and may offer non-monetary recognition for significant contributions.
-7
View File
@@ -1,7 +0,0 @@
from .entity import App
from .exceptions import (HandlerForUnknownCommandsOnNonMainRouterException,
InvalidDescriptionMessagePatternException,
InvalidRouterInstanceException,
OnlyOneMainRouterIsAllowedException,
MissingMainRouterException,
MissingHandlerForUnknownCommandsException)
-223
View File
@@ -1,223 +0,0 @@
from typing import Callable
from ..router.entity import Router
from .exceptions import (InvalidRouterInstanceException,
InvalidDescriptionMessagePatternException,
OnlyOneMainRouterIsAllowedException,
MissingMainRouterException,
MissingHandlerForUnknownCommandsException,
HandlerForUnknownCommandsOnNonMainRouterException,
NoRegisteredRoutersException,
NoRegisteredHandlersException,
RepeatedCommandInDifferentRoutersException)
class App:
def __init__(self,
prompt: str = 'Enter a command',
initial_message: str = '\nHello, I am Argenta\n',
farewell_message: str = '\nGoodBye\n',
exit_command: str = 'Q',
exit_command_description: str = 'Exit command',
exit_command_title: str = 'System points:',
ignore_exit_command_register: bool = True,
ignore_command_register: bool = False,
line_separate: str = '',
command_group_description_separate: str = '',
repeat_command_groups: bool = True,
print_func: Callable[[str], None] = print) -> None:
self.prompt = prompt
self.print_func = print_func
self.exit_command = exit_command
self.exit_command_description = exit_command_description
self.exit_command_title = exit_command_title
self.ignore_exit_command_register = ignore_exit_command_register
self.farewell_message = farewell_message
self.initial_message = initial_message
self.line_separate = line_separate
self.command_group_description_separate = command_group_description_separate
self.ignore_command_register = ignore_command_register
self.repeat_command_groups = repeat_command_groups
self._routers: list[Router] = []
self._registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | str]] | Router]] = []
self._app_main_router: Router | None = None
self._description_message_pattern: str = '[{command}] *=*=* {description}'
def start_polling(self) -> None:
self._validate_number_of_routers()
self._validate_included_routers()
self._validate_main_router()
self._validate_all_router_commands()
self.print_func(self.initial_message)
if not self.repeat_command_groups:
self._print_command_group_description()
self.print_func(self.prompt)
while True:
if self.repeat_command_groups:
self._print_command_group_description()
self.print_func(self.prompt)
command: str = input()
self._checking_command_for_exit_command(command)
self.print_func(self.line_separate)
is_unknown_command: bool = self._check_is_command_unknown(command)
if is_unknown_command:
if not self.repeat_command_groups:
self.print_func(self.prompt)
continue
for router in self._routers:
router.input_command_handler(command)
self.print_func(self.line_separate)
self.print_func(self.command_group_description_separate)
if not self.repeat_command_groups:
self.print_func(self.prompt)
def set_initial_message(self, message: str) -> None:
self.initial_message: str = message
def set_farewell_message(self, message: str) -> None:
self.farewell_message: str = message
def set_description_message_pattern(self, pattern: str) -> None:
try:
pattern.format(command='command',
description='description')
except KeyError:
raise InvalidDescriptionMessagePatternException(pattern)
self._description_message_pattern: str = pattern
def get_main_router(self) -> Router:
return self._app_main_router
def get_all_app_commands(self) -> list[str]:
all_commands: list[str] = []
for router in self._routers:
all_commands.extend(router.get_all_commands())
return all_commands
def include_router(self, router: Router, is_main: True | False = False) -> None:
if not isinstance(router, Router):
raise InvalidRouterInstanceException()
if is_main:
if not self._app_main_router:
self._app_main_router = router
router.set_router_as_main()
else:
raise OnlyOneMainRouterIsAllowedException(self._app_main_router.get_name())
router.set_ignore_command_register(self.ignore_command_register)
self._routers.append(router)
command_entities: list[dict[str, Callable[[], None] | str]] = router.get_command_entities()
self._registered_router_entities.append({'name': router.get_name(),
'title': router.get_title(),
'entity': router,
'commands': command_entities})
def _validate_number_of_routers(self) -> None:
if not self._routers:
raise NoRegisteredRoutersException()
def _validate_included_routers(self) -> None:
for router in self._routers:
if not router.get_command_entities():
raise NoRegisteredHandlersException(router.get_name())
def _validate_main_router(self):
if not self._app_main_router:
if len(self._routers) > 1:
raise MissingMainRouterException()
else:
router = self._routers[0]
router.set_router_as_main()
self._app_main_router = router
if not self._app_main_router.unknown_command_func:
raise MissingHandlerForUnknownCommandsException()
for router in self._routers:
if router.unknown_command_func and self._app_main_router is not router:
raise HandlerForUnknownCommandsOnNonMainRouterException()
def _validate_all_router_commands(self) -> None:
for idx in range(len(self._registered_router_entities)):
current_router: Router = self._registered_router_entities[idx]['entity']
routers_without_current_router = self._registered_router_entities.copy()
routers_without_current_router.pop(idx)
current_router_all_commands: list[str] = current_router.get_all_commands()
for router_entity in routers_without_current_router:
if len(set(current_router_all_commands).intersection(set(router_entity['entity'].get_all_commands()))) > 0:
raise RepeatedCommandInDifferentRoutersException()
if self.ignore_command_register:
if len(set([x.lower() for x in current_router_all_commands]).intersection(set([x.lower() for x in router_entity['entity'].get_all_commands()]))) > 0:
raise RepeatedCommandInDifferentRoutersException()
def _checking_command_for_exit_command(self, command: str):
if command.lower() == self.exit_command.lower():
if self.ignore_exit_command_register:
self.print_func(self.farewell_message)
exit(0)
else:
if command == self.exit_command:
self.print_func(self.farewell_message)
exit(0)
def _check_is_command_unknown(self, command: str):
registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | str]] | Router]] = self._registered_router_entities
for router_entity in registered_router_entities:
for command_entity in router_entity['commands']:
if command_entity['command'].lower() == command.lower():
if self.ignore_command_register:
return False
else:
if command_entity['command'] == command:
return False
self._app_main_router.unknown_command_handler(command)
self.print_func(self.line_separate)
self.print_func(self.command_group_description_separate)
return True
def _print_command_group_description(self):
for router_entity in self._registered_router_entities:
self.print_func(router_entity['title'])
for command_entity in router_entity['commands']:
self.print_func(self._description_message_pattern.format(
command=command_entity['command'],
description=command_entity['description']
)
)
self.print_func(self.command_group_description_separate)
self.print_func(self.exit_command_title)
self.print_func(self._description_message_pattern.format(
command=self.exit_command,
description=self.exit_command_description
)
)
self.print_func(self.command_group_description_separate)
-56
View File
@@ -1,56 +0,0 @@
class InvalidRouterInstanceException(Exception):
def __str__(self):
return "Invalid Router Instance"
class InvalidDescriptionMessagePatternException(Exception):
def __init__(self, pattern: str):
self.pattern = pattern
def __str__(self):
return ("Invalid Description Message Pattern\n"
"Correct pattern example: [{command}] *=*=* {description}\n"
"The pattern must contain two variables: `command` and `description` - description of the command\n"
f"Your pattern: {self.pattern}")
class OnlyOneMainRouterIsAllowedException(Exception):
def __init__(self, existing_main_router):
self.existing_main_router = existing_main_router
def __str__(self):
return ("Only One Main Router Allowed\n"
f"Existing main router is: {self.existing_main_router}")
class MissingMainRouterException(Exception):
def __str__(self):
return ("Missing Main Router\n"
"One of the registered routers must be the main one")
class MissingHandlerForUnknownCommandsException(Exception):
def __str__(self):
return ("Missing Handlers For Unknown Commands On The Main Router\n"
"The main router must have a declared handler for unknown commands")
class HandlerForUnknownCommandsOnNonMainRouterException(Exception):
def __str__(self):
return '\nThe handler for unknown commands can only be declared for the main router'
class NoRegisteredRoutersException(Exception):
def __str__(self):
return "No Registered Router Found"
class NoRegisteredHandlersException(Exception):
def __init__(self, router_name):
self.router_name = router_name
def __str__(self):
return f"No Registered Handlers Found For '{self.router_name}'"
class RepeatedCommandInDifferentRoutersException(Exception):
def __str__(self):
return "Commands in different handlers cannot be repeated"
-4
View File
@@ -1,4 +0,0 @@
from .entity import Router
from .exceptions import (UnknownCommandHandlerHasAlreadyBeenCreatedException,
InvalidDescriptionInstanceException,
InvalidCommandInstanceException)
-123
View File
@@ -1,123 +0,0 @@
from typing import Callable, Any
from ..router.exceptions import (InvalidCommandInstanceException,
UnknownCommandHandlerHasAlreadyBeenCreatedException,
InvalidDescriptionInstanceException,
RepeatedCommandException)
class Router:
def __init__(self,
title: str = 'Commands group title:',
name: str = 'subordinate'):
self.title = title
self.name = name
self._command_entities: list[dict[str, Callable[[], None] | str]] = []
self.unknown_command_func: Callable[[str], None] | None = None
self._is_main_router: bool = False
self.ignore_command_register: bool = False
def command(self, command: str, description: str = None) -> Callable[[Any], Any]:
processed_description = Router._validate_description(command, description)
self._validate_command(command)
def command_decorator(func):
self._command_entities.append({'handler_func': func,
'command': command,
'description': processed_description})
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return command_decorator
def unknown_command(self, func):
if self.unknown_command_func is not None:
raise UnknownCommandHandlerHasAlreadyBeenCreatedException()
self.unknown_command_func: Callable = func
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def input_command_handler(self, input_command):
for command_entity in self._command_entities:
if input_command.lower() == command_entity['command'].lower():
if self.ignore_command_register:
return command_entity['handler_func']()
else:
if input_command == command_entity['command']:
return command_entity['handler_func']()
def unknown_command_handler(self, unknown_command):
self.unknown_command_func(unknown_command)
def _validate_command(self, command: str):
if not isinstance(command, str):
raise InvalidCommandInstanceException()
if command in self.get_all_commands():
raise RepeatedCommandException()
if self.ignore_command_register:
if command.lower() in [x.lower() for x in self.get_all_commands()]:
raise RepeatedCommandException()
@staticmethod
def _validate_description(command: str, description: str):
if not isinstance(description, str):
if description is None:
description = f'description for "{command}" command'
else:
raise InvalidDescriptionInstanceException()
return description
def set_router_as_main(self):
if self.name == 'subordinate':
self.name = 'main'
self._is_main_router = True
def set_ignore_command_register(self, ignore_command_register: bool):
self.ignore_command_register = ignore_command_register
def get_command_entities(self) -> list[dict[str, Callable[[], None] | str]]:
return self._command_entities
def get_name(self) -> str:
return self.name
def get_title(self) -> str:
return self.title
def get_router_info(self) -> dict:
return {
'title': self.title,
'name': self.name,
'ignore_command_register': self.ignore_command_register,
'attributes': {
'command_entities': self._command_entities,
'unknown_command_func': self.unknown_command_func,
'is_main_router': self._is_main_router
}
}
def get_all_commands(self) -> list[str]:
all_commands: list[str] = []
for command_entity in self._command_entities:
all_commands.append(command_entity['command'])
return all_commands
-18
View File
@@ -1,18 +0,0 @@
class InvalidCommandInstanceException(Exception):
def __str__(self):
return "Invalid Command Instance"
class InvalidDescriptionInstanceException(Exception):
def __str__(self):
return "Invalid Description Instance"
class UnknownCommandHandlerHasAlreadyBeenCreatedException(Exception):
def __str__(self):
return "Only one unknown command handler can be declared"
class RepeatedCommandException(Exception):
def __str__(self):
return "Commands in handler cannot be repeated"
+3
View File
@@ -0,0 +1,3 @@
_build/
_static/
*.mo
+35
View File
@@ -0,0 +1,35 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
LANGUAGES = en ru
build-all:
sphinx-build -b html -D language=ru $(SOURCEDIR) $(BUILDDIR)/html/ru
sphinx-build -b html -D language=en $(SOURCEDIR) $(BUILDDIR)/html/en
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
live-ru:
sphinx-autobuild -b html . _build/html/ru -D language=ru
live-en:
sphinx-autobuild -b html . _build/html/en -D language=en
update-langs:
sphinx-build -b gettext . _build/gettext
sphinx-intl update -p _build/gettext -l en
.PHONY: help Makefile serve-all
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+17
View File
@@ -0,0 +1,17 @@
from argenta import App, Orchestrator
from argenta.orchestrator.argparser import ArgParser, BooleanArgument
arg_parser = ArgParser(
processed_args=[
BooleanArgument("dev")
]
)
orchestrator = Orchestrator(
arg_parser=arg_parser,
)
if __name__ == "__main__":
if arg_parser.parsed_argspace.get_by_name("dev"):
orchestrator.start_polling(App(initial_message="ArgentaDev"))
else:
orchestrator.start_polling(App())
+29
View File
@@ -0,0 +1,29 @@
from argenta import App, Orchestrator
from argenta.orchestrator.argparser import ArgParser, ValueArgument
arguments = [
ValueArgument("host", help="Server host", is_required=True),
ValueArgument("port", help="Server port", is_required=True),
]
argparser = ArgParser(processed_args=arguments, name="WebServer", description="Simple web server")
app = App()
orchestrator = Orchestrator(argparser)
def main():
argspace = argparser.parsed_argspace
host = argspace.get_by_name("host")
port = argspace.get_by_name("port")
print("Server configuration:")
print(f" Host: {host.value}")
print(f" Port: {port.value}")
orchestrator.start_polling(app)
if __name__ == "__main__":
main()
+10
View File
@@ -0,0 +1,10 @@
from argenta import Response, Router
from argenta.di import FromDishka
from argenta.orchestrator.argparser import ArgSpace
router = Router()
@router.command("get_args")
async def get_args(response: Response, argspace: FromDishka[ArgSpace]):
print(argspace.all_arguments)
+21
View File
@@ -0,0 +1,21 @@
from argenta import Response, Router
from argenta.di import FromDishka
from argenta.orchestrator.argparser import ArgSpace, BooleanArgument, ValueArgument
router = Router()
@router.command("get_args")
def get_args(response: Response, argspace: FromDishka[ArgSpace]):
# Get all boolean flags
boolean_flags = argspace.get_by_type(BooleanArgument)
print(f"Active flags: {[arg.name for arg in boolean_flags if arg.value]}")
# Get all value arguments
value_args = argspace.get_by_type(ValueArgument)
for arg in value_args:
print(f"{arg.name} = {arg.value}")
# Count arguments of each type
print(f"Boolean arguments: {len(argspace.get_by_type(BooleanArgument))}")
print(f"Value arguments: {len(argspace.get_by_type(ValueArgument))}")
+20
View File
@@ -0,0 +1,20 @@
from argenta import Response, Router
from argenta.di import FromDishka
from argenta.orchestrator.argparser import ArgSpace
router = Router()
@router.command("get_args")
def get_args(response: Response, argspace: FromDishka[ArgSpace]):
config_arg = argspace.get_by_name("config")
if config_arg:
print(f"Config path: {config_arg.value}")
verbose_arg = argspace.get_by_name("verbose")
if verbose_arg and verbose_arg.value:
print("Verbose mode enabled")
unknown_arg = argspace.get_by_name("nonexistent")
if unknown_arg is None:
print("Argument not found")
+20
View File
@@ -0,0 +1,20 @@
from argenta.orchestrator.argparser import ArgParser, ValueArgument
# Create arguments
config_arg = ValueArgument("config", help="Path to configuration file", default="config.yaml")
log_level_arg = ValueArgument(
"log-level",
help="Logging level",
possible_values=["DEBUG", "INFO", "WARNING", "ERROR"],
default="INFO",
)
host_arg = ValueArgument("host", help="Server host address", is_required=True)
# Register in ArgParser
parser = ArgParser(
processed_args=[config_arg, log_level_arg, host_arg],
name="MyApp",
description="My application with CLI arguments",
)
+9
View File
@@ -0,0 +1,9 @@
from argenta.orchestrator.argparser import ArgParser, BooleanArgument
# Create boolean arguments
verbose_arg = BooleanArgument("verbose", help="Enable verbose output")
debug_arg = BooleanArgument("debug", help="Enable debug mode")
no_cache_arg = BooleanArgument("no-cache", help="Disable caching")
# Register in ArgParser
parser = ArgParser(processed_args=[verbose_arg, debug_arg, no_cache_arg], name="MyApp")
@@ -0,0 +1,10 @@
from argenta import App
from argenta.app import AutoCompleter
# Setting up autocompletion with saving history to a file
my_autocompleter = AutoCompleter(history_filename="argenta_history.txt")
# Passing the configured autocompleter to the application
app = App(autocompleter=my_autocompleter)
# ... the rest of the application logic
+20
View File
@@ -0,0 +1,20 @@
from argenta.command import Flag, Flags, Command
# Simple command without flags
hello_cmd = Command("hello", description="Greet the user")
# Command with description and aliases
quit_cmd = Command("quit", description="Exit the application", aliases=["exit", "q"])
# Command with flags
deploy_cmd = Command(
"deploy",
description="Deploy application to server",
flags=Flags(
[
Flag("env", possible_values=["dev", "prod"]),
Flag("force"),
]
),
aliases=["dep"],
)
+19
View File
@@ -0,0 +1,19 @@
from argenta import Command, Response, Router
router = Router(title="User Management")
@router.command(Command("create-user", description="Create a new user account"))
def handle_create_user(response: Response):
print("Creating new user...")
@router.command(
Command(
"delete-user",
description="Delete existing user account",
aliases=["remove-user", "rm-user"],
)
)
def handle_delete_user(response: Response):
print("Deleting user...")
+33
View File
@@ -0,0 +1,33 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
router = Router(title="Server Management")
@router.command(
Command(
"start",
description="Start the server",
flags=Flags(
[
Flag("port"),
Flag("host"),
Flag("debug"),
]
),
aliases=["run"],
)
)
def handle_start(response: Response):
input_flags = response.input_flags
port_flag = input_flags.get_flag_by_name("port")
host_flag = input_flags.get_flag_by_name("host")
debug_flag = input_flags.get_flag_by_name("debug")
host = host_flag.input_value if host_flag else "localhost"
port = port_flag.input_value if port_flag else "8080"
debug = debug_flag and debug_flag.input_value
print(f"Starting server on {host}:{port}")
if debug:
print("Debug mode: ON")
+11
View File
@@ -0,0 +1,11 @@
from argenta.command import InputCommand
# Parse command without flags
cmd1 = InputCommand.parse("hello")
print(cmd1.trigger) # "hello"
print(len(cmd1.input_flags)) # 0
# Parse command with flags
cmd2 = InputCommand.parse("deploy --env prod --force")
print(cmd2.trigger) # "deploy"
print(len(cmd2.input_flags)) # 2
+14
View File
@@ -0,0 +1,14 @@
from argenta import Router, Command, Response
router = Router(title="System")
@router.command(
Command(
"shutdown",
description="Shutdown the system",
aliases=["poweroff", "halt", "stop"]
)
)
def handle_shutdown(response: Response):
print("Shutting down the system...")
@@ -0,0 +1,9 @@
from sqlite3 import Connection
from argenta import Response, Router
from argenta.di import FromDishka
router = Router()
@router.command("connect")
def connect_handler(response: Response, connection: FromDishka[Connection]):
connection.execute("...")
@@ -0,0 +1,13 @@
import sqlite3
from sqlite3 import Connection
from typing import Iterable
from dishka import Provider, Scope, provide
class ConnectionProvider(Provider):
@provide(scope=Scope.REQUEST)
def new_connection(self) -> Iterable[Connection]:
conn = sqlite3.connect(":memory:")
yield conn
conn.close()
@@ -0,0 +1,3 @@
from argenta import Orchestrator
orchestrator = Orchestrator(custom_providers=[ConnectionProvider()])
@@ -0,0 +1,9 @@
from argenta import Response, Router
from argenta.di import FromDishka
from argenta.orchestrator.argparser import ArgSpace
router = Router()
@router.command("info")
def connect_handler(response: Response, argspace: FromDishka[ArgSpace]):
print(argspace.get_by_name("type"))
@@ -0,0 +1,7 @@
from argenta import App
def empty_command_handler():
print("Empty command handler called")
app: App = App()
app.set_empty_command_handler(empty_command_handler)
@@ -0,0 +1,7 @@
from argenta import App
def incorrect_input_syntax_handler(raw_command: str):
print(f"Incorrect input syntax for command: {raw_command}")
app: App = App()
app.set_incorrect_input_syntax_handler(incorrect_input_syntax_handler)
@@ -0,0 +1,7 @@
from argenta import App
def repeated_input_flags_handler(raw_command: str):
print(f"Repeated input flags: {raw_command}")
app: App = App()
app.set_repeated_input_flags_handler(repeated_input_flags_handler)
@@ -0,0 +1,7 @@
from argenta import App
def empty_command_handler():
print("Empty input command")
app: App = App()
app.set_empty_command_handler(empty_command_handler)
@@ -0,0 +1,8 @@
from argenta import App
from argenta.command import InputCommand
def unknown_command_handler(command: InputCommand):
print(f"Unknown input command with trigger: {command.trigger}")
app: App = App()
app.set_unknown_command_handler(unknown_command_handler)
@@ -0,0 +1,7 @@
from argenta import App, Response
def exit_command_handler(response: Response):
print("Exit command handler")
app: App = App()
app.set_exit_command_handler(exit_command_handler)
@@ -0,0 +1,36 @@
from argenta.command import Flags, PredefinedFlags
# Using predefined flags when creating a command
command_flags = Flags(
[
PredefinedFlags.HELP,
PredefinedFlags.SHORT_HELP,
PredefinedFlags.INFO,
]
)
# Using Network Flags
network_flags = Flags(
[
PredefinedFlags.HOST,
PredefinedFlags.PORT,
]
)
# Validating the values of predefined flags
print(PredefinedFlags.HOST.validate_input_flag_value("192.168.1.1")) # True
print(PredefinedFlags.HOST.validate_input_flag_value("invalid")) # False
print(PredefinedFlags.PORT.validate_input_flag_value("8080")) # True
print(PredefinedFlags.PORT.validate_input_flag_value("99999")) # True
print(PredefinedFlags.PORT.validate_input_flag_value("abc")) # False
# Flags without values
print(PredefinedFlags.HELP.validate_input_flag_value(None)) # True
print(PredefinedFlags.HELP.validate_input_flag_value("something")) # False
# Checking string representations
print(PredefinedFlags.HELP.string_entity) # --help
print(PredefinedFlags.SHORT_HELP.string_entity) # -H
print(PredefinedFlags.HOST.string_entity) # --host
print(PredefinedFlags.SHORT_PORT.string_entity) # -P
+20
View File
@@ -0,0 +1,20 @@
import re
from argenta.command import Flag, PossibleValues
# Simple flag with any values
verbose_flag = Flag(name="verbose")
# Flag with short prefix
short_flag = Flag(name="v", prefix="-")
# Flag that does not take a value
help_flag = Flag(name="help", possible_values=PossibleValues.NEITHER)
# Flag with list of possible values
format_flag = Flag(name="format", possible_values=["json", "xml", "csv"])
# Flag with regexp for validation input value
email_flag = Flag(
name="email",
possible_values=re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"),
)
+20
View File
@@ -0,0 +1,20 @@
import re
from argenta.command.flag.models import Flag, PossibleValues
# Flag with list of allowed values
format_flag = Flag(name="format", possible_values=["json", "xml", "csv"])
# Value validation
print(format_flag.validate_input_flag_value("json")) # True
print(format_flag.validate_input_flag_value("pdf")) # False
# Flag without value
help_flag = Flag(name="help", possible_values=PossibleValues.NEITHER)
print(help_flag.validate_input_flag_value(None)) # True
print(help_flag.validate_input_flag_value("value")) # False
# Flag with regular expression
port_flag = Flag(name="port", possible_values=re.compile(r"^\d{1,5}$"))
print(port_flag.validate_input_flag_value("8080")) # True
print(port_flag.validate_input_flag_value("abc")) # False
+9
View File
@@ -0,0 +1,9 @@
from argenta.command import Flag
help_flag = Flag(name="help")
version_flag = Flag(name="V", prefix="-")
print(help_flag) # --help
message = f"Use {help_flag} to see help"
print(message) # Use --help to see help
+12
View File
@@ -0,0 +1,12 @@
from argenta.command import Flag
verbose_flag = Flag(name="verbose", prefix="--")
short_flag = Flag(name="v", prefix="-")
# Debug presentation
print(repr(verbose_flag)) # Flag<prefix=--, name=verbose>
print(repr(short_flag)) # Flag<prefix=-, name=v>
# In an interactive console or debugger
# >>> verbose_flag
# Flag<prefix=--, name=verbose>
+21
View File
@@ -0,0 +1,21 @@
from argenta.command import Flag, PossibleValues
# Creating two flags with the same name and prefix
flag1 = Flag(name="verbose", prefix="--")
flag2 = Flag(name="verbose", prefix="--")
# Flag comparison
print(flag1 == flag2) # True
# Flags with different prefixes are not equal
flag3 = Flag(name="verbose", prefix="-")
print(flag1 == flag3) # False
# Flags with different names are not equal
flag4 = Flag(name="help", prefix="--")
print(flag1 == flag4) # False
# Different possible_values do not affect equality
flag5 = Flag(name="verbose", prefix="--", possible_values=PossibleValues.NEITHER)
flag6 = Flag(name="verbose", prefix="--", possible_values=["value1", "value2"])
print(flag5 == flag6)
@@ -0,0 +1,21 @@
from argenta import Router, Response
from argenta.command import Command, Flag, PossibleValues
from argenta.command.flag import ValidationStatus
router = Router()
@router.command(Command("deploy", flags=Flag("verbose", possible_values=PossibleValues.NEITHER)))
def deploy_handler(response: Response):
# Check for toggle flag presence
verbose_flag = response.input_flags.get_flag_by_name("verbose")
if verbose_flag and verbose_flag.status == ValidationStatus.VALID:
print("Deploying with verbose output...")
# Detailed logic
elif verbose_flag and verbose_flag.status == ValidationStatus.INVALID:
print("Incorrect flag value")
return
else:
print("Deploying...")
# Normal logic
+16
View File
@@ -0,0 +1,16 @@
from argenta import Router, Response
from argenta.command import Command, Flag
router = Router()
@router.command(Command("greet", flags=Flag("name")))
def greet_handler(response: Response):
# Get flag by name
name_flag = response.input_flags.get_flag_by_name("name")
# Check if flag was passed
if name_flag:
print(f"Hello, {name_flag.input_value}!")
else:
print("Hello, stranger!")
+11
View File
@@ -0,0 +1,11 @@
import re
from argenta.command import Command, Flag, Flags
flags = Flags(
[
Flag("host", possible_values=re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")),
Flag("port", possible_values=re.compile(r"^\d{1,5}$")),
]
)
cmd = Command("start", description="Start the server", flags=flags)
+9
View File
@@ -0,0 +1,9 @@
from argenta.command import Flag, Flags
flags: Flags = Flags()
flags.add_flag(Flag("config"))
flags.add_flag(Flag("debug"))
flags.add_flag(Flag("log-level", possible_values=["INFO", "DEBUG", "ERROR"]))
print(len(flags)) # 3
+15
View File
@@ -0,0 +1,15 @@
from argenta.command import Flag, Flags
from argenta.command.flag.defaults import PredefinedFlags
flags = Flags([PredefinedFlags.HOST])
additional_flags = [
PredefinedFlags.PORT,
Flag("database"),
Flag("ssl"),
Flag("verbose"),
]
flags.add_flags(additional_flags)
print(len(flags)) # 5
+13
View File
@@ -0,0 +1,13 @@
from argenta.command import Flag, Flags
from argenta.command.flag.defaults import PredefinedFlags
flags = Flags([PredefinedFlags.HOST, PredefinedFlags.PORT, Flag("verbose")])
host_flag = flags.get_flag_by_name("host")
if host_flag:
print(f"Found flag: {host_flag.name}")
unknown_flag = flags.get_flag_by_name("nonexistent")
if unknown_flag is None:
print("Flag not found")
+13
View File
@@ -0,0 +1,13 @@
from argenta.command.flag import InputFlag, ValidationStatus
flag_with_value = InputFlag(
name="output", prefix="--", input_value="result.txt", status=ValidationStatus.VALID
)
flag_without_value = InputFlag(
name="help", prefix="-", input_value='', status=ValidationStatus.VALID
)
# String representation includes value
print(str(flag_with_value)) # --output result.txt
print(str(flag_without_value)) # -help
+12
View File
@@ -0,0 +1,12 @@
from argenta.command.flag import InputFlag, ValidationStatus
flag = InputFlag(
name="config",
prefix="--",
input_value="settings.json",
status=ValidationStatus.VALID,
)
# Debug representation of the object
print(repr(flag))
# InputFlag<prefix='--', name='config', value='settings.json', status=ValidationStatus.VALID>
@@ -0,0 +1,20 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
router = Router(title="Example")
@router.command(
Command(
"example",
description="Example command with flags",
flags=Flags([Flag("name"), Flag("age")]),
)
)
def example_handler(response: Response):
input_flags = response.input_flags
if input_flags:
print(f"Received {len(input_flags)} flag(s)")
else:
print("No flags provided")
@@ -0,0 +1,49 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags, InputFlag
from argenta.command.flag import ValidationStatus
router = Router(title="Comprehensive Example")
@router.command(
Command(
"validate",
description="Validate all flags",
flags=Flags(
[
Flag("format", possible_values=["json", "xml"]),
Flag("output"),
Flag("force"),
]
),
)
)
def validate_handler(response: Response):
input_flags = response.input_flags
print("Flag validation results:")
valid_flags: list[InputFlag] = []
invalid_flags: list[InputFlag] = []
undefined_flags: list[InputFlag] = []
for flag in input_flags:
if flag.status == ValidationStatus.VALID:
valid_flags.append(flag)
print(f"{flag.string_entity}: {flag.input_value} (VALID)")
elif flag.status == ValidationStatus.INVALID:
invalid_flags.append(flag)
print(f"{flag.string_entity}: {flag.input_value} (INVALID)")
elif flag.status == ValidationStatus.UNDEFINED:
undefined_flags.append(flag)
print(f" ? {flag.string_entity}: {flag.input_value} (UNDEFINED)")
print("\nSummary:")
print(f" Valid flags: {len(valid_flags)}")
print(f" Invalid flags: {len(invalid_flags)}")
print(f" Undefined flags: {len(undefined_flags)}")
if valid_flags:
print("\nProcessing valid flags:")
for flag in valid_flags:
print(f" Processing {flag.name} = {flag.input_value}")
@@ -0,0 +1,32 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
router = Router(title="Get Flag Example")
@router.command(
Command(
"config",
description="Configure settings",
flags=Flags([Flag("host"), Flag("port"), Flag("debug")]),
)
)
def config_handler(response: Response):
input_flags = response.input_flags
host_flag = input_flags.get_flag_by_name("host")
port_flag = input_flags.get_flag_by_name("port")
debug_flag = input_flags.get_flag_by_name("debug")
if host_flag:
print(f"Host: {host_flag.input_value}")
if port_flag:
print(f"Port: {port_flag.input_value}")
if debug_flag:
print("Debug mode enabled")
missing_flag = input_flags.get_flag_by_name("nonexistent")
if missing_flag is None:
print("Flag 'nonexistent' not found")
@@ -0,0 +1,20 @@
from argenta import Command, Response, Router
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command import InputFlags
router = Router(title="Add Flag Example")
@router.command(Command("test", description="Test command"))
def test_handler(response: Response):
# Create new InputFlags collection
new_flags = InputFlags()
# Add one flag
test_flag = InputFlag(
name="test", prefix="--", input_value="value", status=ValidationStatus.VALID
)
new_flags.add_flag(test_flag)
print(f"Flags count: {len(new_flags.flags)}")
print(f"First flag: {new_flags.flags[0].name}")
@@ -0,0 +1,19 @@
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command import InputFlags
# Create InputFlags collection
flags = InputFlags()
# Create several flags
flag1 = InputFlag(name="option1", prefix="--", input_value="value1", status=ValidationStatus.VALID)
flag2 = InputFlag(name="option2", prefix="--", input_value="value2", status=ValidationStatus.VALID)
flag3 = InputFlag(name="option3", prefix="---", input_value="value3", status=ValidationStatus.VALID)
# Add all flags in one call
flags.add_flags([flag1, flag2, flag3])
print(f"Total flags: {len(flags.flags)}")
for flag in flags:
print(f" - {flag.string_entity}: {flag.input_value}")
@@ -0,0 +1,27 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
router = Router(title="Bool Check Example")
@router.command(
Command(
"action",
description="Action with optional flags",
flags=Flags([Flag("option1"), Flag("option2")]),
)
)
def action_handler(response: Response):
input_flags = response.input_flags
# Check for flags presence
if input_flags:
print("Flags were provided:")
for flag in input_flags:
print(f" - {flag.name}: {flag.input_value}")
else:
print("No flags provided, using defaults")
# Alternative way to check
has_flags = bool(input_flags)
print(f"\nHas flags: {has_flags}")
@@ -0,0 +1,33 @@
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command import InputFlags
# Create first collection
flags1 = InputFlags(
[
InputFlag(name="flag1", input_value="value1", status=ValidationStatus.VALID),
InputFlag(name="flag2", input_value="value2", status=ValidationStatus.VALID),
]
)
# Create second collection with same flags
flags2 = InputFlags(
[
InputFlag(name="flag1", input_value="value1", status=ValidationStatus.VALID),
InputFlag(name="flag2", input_value="value2", status=ValidationStatus.VALID),
]
)
# Create third collection with different values
flags3 = InputFlags(
[
InputFlag(name="flag1", input_value="different", status=ValidationStatus.VALID),
InputFlag(name="flag2", input_value="value2", status=ValidationStatus.VALID),
]
)
print(f"flags1 == flags2: {flags1 == flags2}") # True (same names)
print(f"flags1 == flags3: {flags1 == flags3}") # True (same names, values are not considered)
# Different collections
flags4 = InputFlags([InputFlag(name="flag3", input_value="value3", status=ValidationStatus.VALID)])
print(f"flags1 == flags4: {flags1 == flags4}") # False (different flags)
@@ -0,0 +1,33 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
from argenta.command.flag import InputFlag
router = Router(title="Contains Example")
@router.command(
Command(
"check",
description="Check flags",
flags=Flags([Flag("verbose"), Flag("debug"), Flag("quiet")]),
)
)
def check_handler(response: Response):
input_flags = response.input_flags
# Check for specific flag presence
verbose_flag = input_flags.get_flag_by_name("verbose")
debug_flag = input_flags.get_flag_by_name("debug")
# Use 'in' operator for checking
if verbose_flag and verbose_flag in input_flags:
print("Verbose flag is present")
if debug_flag and debug_flag in input_flags:
print("Debug flag is present")
# You can create a flag for checking (comparison is by name)
test_flag = InputFlag(name="verbose", prefix="--", input_value="any", status=None)
if test_flag in input_flags:
print("Verbose flag found using 'in' operator")
@@ -0,0 +1,9 @@
from metrics.benchmarks.entity import benchmarks
@benchmarks.register(
type_="my_category",
description="Description of what is being measured"
)
def benchmark_my_operation() -> None:
# Code whose performance is being measured
pass
@@ -0,0 +1,27 @@
import sqlite3
from sqlite3 import Connection
from typing import Iterable
from dishka import Provider, Scope, provide
from argenta import App, Orchestrator
class ConnectionProvider(Provider):
@provide(scope=Scope.REQUEST)
def new_connection(self) -> Iterable[Connection]:
conn = sqlite3.connect(":memory:")
yield conn
conn.close()
# 2. Create and configure App
app = App()
# ... you can add routers here ...
# 3. Create Orchestrator, passing our provider
orchestrator = Orchestrator(custom_providers=[ConnectionProvider()])
# 4. Start the application
if __name__ == "__main__":
orchestrator.start_polling(app)
@@ -0,0 +1,5 @@
from argenta.command import Flag, PossibleValues
# Creating flags with any values
message_flag = Flag(name="message", possible_values=PossibleValues.ALL)
name_flag = Flag(name="name", possible_values=PossibleValues.ALL)
@@ -0,0 +1,14 @@
import re
from argenta.command import Flag, PossibleValues
# Flag without value
verbose_flag = Flag(name="verbose", possible_values=PossibleValues.NEITHER)
# Flag with any value
output_flag = Flag(name="output", possible_values=PossibleValues.ALL)
# Flag with a list of valid values
format_flag = Flag(name="format", possible_values=["json", "xml", "csv", "yaml"])
# Flag with regular expression
email_flag = Flag(name="email", possible_values=re.compile(r"^[\w\.-]+@[\w\.-]+\.\w+$"))
@@ -0,0 +1,6 @@
from argenta.command import Flag, PossibleValues
# Creating flags without values
help_flag = Flag(name="help", possible_values=PossibleValues.NEITHER)
verbose_flag = Flag(name="verbose", possible_values=PossibleValues.NEITHER)
force_flag = Flag(name="force", possible_values=PossibleValues.NEITHER)
@@ -0,0 +1,67 @@
import operator
import re
from argenta import App, Orchestrator, Response, Router
from argenta.app import DynamicDividingLine
from argenta.command import Command, Flag, Flags
from argenta.response.status import ResponseStatus
router = Router("Calculator")
operations = {"mul": operator.mul, "sub": operator.sub, "add": operator.add}
@router.command(
Command(
"calc",
description="Calculator with two numbers",
flags=Flags(
[
Flag("a", possible_values=re.compile(r"^\d{,5}$")), # First number
Flag("b", possible_values=re.compile(r"^\d{,5}$")), # Second number
Flag(
"operation", possible_values=["add", "sub", "mul"]
), # Operation: add, sub, mul
]
),
)
)
def calc_handler(response: Response):
# Get flag values
a_flag = response.input_flags.get_flag_by_name("a")
b_flag = response.input_flags.get_flag_by_name("b")
op_flag = response.input_flags.get_flag_by_name("op")
# Check that all flags are provided
if response.status != ResponseStatus.ALL_FLAGS_VALID or not all([a_flag, b_flag, op_flag]):
print("Error: must specify --a, --b and --op")
return
a = float(a_flag.input_value)
b = float(b_flag.input_value)
operation = op_flag.input_value
try:
result = operations[operation](a, b)
except ZeroDivisionError:
print("Can't divide by zero")
else:
print(f"Result: {result}")
app = App(
initial_message="Calculator",
repeat_command_groups_printing=False,
prompt=">> ",
dividing_line=DynamicDividingLine("~"),
)
orchestrator = Orchestrator()
def main():
app.include_router(router)
orchestrator.start_polling(app)
if __name__ == "__main__":
main()
+16
View File
@@ -0,0 +1,16 @@
# main.py
from .routers import router
from argenta import App, Orchestrator
app: App = App()
orchestrator: Orchestrator = Orchestrator()
def main() -> None:
app.include_router(router)
orchestrator.start_polling(app)
if __name__ == "__main__":
main()
+9
View File
@@ -0,0 +1,9 @@
# routers.py
from argenta import Command, Response, Router
router = Router(title="Quickstart Example")
@router.command(Command("hello", description="Say hello"))
def handler(response: Response):
print("Hello, world!")
@@ -0,0 +1,33 @@
from argenta import App, Command, Orchestrator, Router, Response
from argenta.command import Flag
# 1. Create app and orchestrator instances
app = App(
prompt=">> ",
initial_message="Simple App",
farewell_message="Goodbye!",
repeat_command_groups_printing=False,
)
orchestrator = Orchestrator()
# 2. Create router for grouping commands
main_router = Router(title="Main commands")
# 3. Define command and its handler
@main_router.command(Command("hello", description="Prints greeting message", flags=Flag("name")))
def hello_handler(response: Response):
"""This handler will be called for 'hello' command."""
name = response.input_flags.get_flag_by_name("name")
if name:
print(f"Hello, {name.input_value}!")
else:
print("Hello, world!")
# 4. Include router to application
app.include_router(main_router)
# 5. Start application
if __name__ == "__main__":
orchestrator.start_polling(app)
@@ -0,0 +1,59 @@
from typing import cast
from argenta import Command, Response, Router
from argenta.command.flag import Flag, ValidationStatus
from argenta.command import Flags
from argenta.di import FromDishka
from .repository import Priority, Task, TaskRepository
router = Router(title="Task Manager")
@router.command(
Command(
"add-task",
description="Add a new task",
flags=Flags(
[
Flag("description"),
Flag("priority", possible_values=["low", "medium", "high"]),
]
),
)
)
def add_task(response: Response, repo: FromDishka[TaskRepository]):
description_flag = response.input_flags.get_flag_by_name("description")
if not description_flag or not description_flag.status == ValidationStatus.VALID:
print("Error: --description flag is required.")
return
task_description = description_flag.input_value or ""
priority_flag = response.input_flags.get_flag_by_name("priority")
if priority_flag and priority_flag.status == ValidationStatus.VALID:
priority_value = priority_flag.input_value
else:
priority_value = "medium"
priority = cast(Priority, priority_value)
task = Task(description=task_description, priority=priority)
repo.add_task(task)
print(f"Added task: '{task.description}' with priority '{task.priority}'")
@router.command(Command("list-tasks", description="List all tasks"))
def list_tasks(response: Response, repo: FromDishka[TaskRepository]):
tasks = repo.get_all_tasks()
if not tasks:
print("No tasks found.")
return
print("Tasks:")
for i, task in enumerate(tasks, 1):
print(f" {i}. {task.description} (Priority: {task.priority})")
@@ -0,0 +1,18 @@
from argenta import App, Orchestrator
from .handlers import router
from .provider import TaskProvider
# 1. Create app and orchestrator instances
app = App(
initial_message="Task Manager",
prompt="Enter a command: ",
)
orchestrator = Orchestrator(custom_providers=[TaskProvider()])
# 2. Include router with our commands
app.include_router(router)
# 3. Start polling via orchestrator
if __name__ == "__main__":
orchestrator.start_polling(app)
@@ -0,0 +1,9 @@
from dishka import Provider, Scope, provide
from .repository import TaskRepository
class TaskProvider(Provider):
@provide(scope=Scope.APP)
def get_repository(self) -> TaskRepository:
return TaskRepository()
@@ -0,0 +1,21 @@
from dataclasses import dataclass
from typing import Literal
Priority = Literal["low", "medium", "high"]
@dataclass
class Task:
description: str
priority: Priority = "medium"
class TaskRepository:
def __init__(self):
self._tasks: list[Task] = []
def add_task(self, task: Task):
self._tasks.append(task)
def get_all_tasks(self) -> list[Task]:
return self._tasks
@@ -0,0 +1,10 @@
from argenta import Response, Router
# For this router stdout redirect will be disabled
interactive_router = Router(disable_redirect_stdout=True)
@interactive_router.command("ask")
def ask_name(response: Response):
name = input("What is your name? ")
print(f"Nice to meet you, {name}!")
@@ -0,0 +1,5 @@
from argenta import App
from argenta.app import StaticDividingLine
# All routers will use static line with length 50 by default
app = App(dividing_line=StaticDividingLine(length=50))
@@ -0,0 +1,43 @@
from argenta import Router, Response, Command, DataBridge
from argenta.command import Flag
from argenta.di import FromDishka
router = Router(title="Authentication")
def authenticate_user(username: str) -> str:
return f"token_for_{username}"
@router.command(Command("login", flags=Flag("username")))
def login_handler(response: Response, data_bridge: FromDishka[DataBridge]):
username_flag = response.input_flags.get_flag_by_name("username")
if not username_flag or not username_flag.input_value:
print("Error: username must be specified using the --username flag.")
return
username = username_flag.input_value
token = authenticate_user(username)
data_bridge.update({"auth_token": token})
print(f"Login successful! User '{username}' authenticated.")
@router.command("get-profile")
def get_profile_handler(response: Response, data_bridge: FromDishka[DataBridge]):
token = data_bridge.get_by_key("auth_token")
if not token:
print("Error: you are not authenticated. Please run the 'login' command first.")
return
print(f"Loading profile using token: [yellow]{token}[/yellow]")
@router.command("logout")
def logout_handler(response: Response, data_bridge: FromDishka[DataBridge]):
try:
data_bridge.delete_by_key("auth_token")
print("Logout successful. Session data cleared.")
except KeyError:
print("You were not authenticated anyway.")
+12
View File
@@ -0,0 +1,12 @@
from argenta import Command, Response, Router
from argenta.response import ResponseStatus
router = Router(title="Example")
@router.command(Command("greet", description="Greet the user"))
def greet_handler(response: Response):
if response.status == ResponseStatus.ALL_FLAGS_VALID:
print("Hello! All flags are valid.")
else:
print("Warning: Some flags have issues.")
+35
View File
@@ -0,0 +1,35 @@
from argenta import Command, Response, Router
from argenta.command import Flag, Flags
from argenta.command.flag import ValidationStatus
from argenta.response import ResponseStatus
router = Router(title="Flags Example")
@router.command(
Command(
"process",
description="Process with flags",
flags=Flags([Flag("format", possible_values=["json", "xml"]), Flag("verbose")]),
)
)
def process_handler(response: Response):
print(f"Status: {response.status}")
format_flag = response.input_flags.get_flag_by_name("format")
verbose_flag = response.input_flags.get_flag_by_name("verbose")
if format_flag:
format_value = format_flag.input_value
print(f"Format: {format_value}")
if verbose_flag:
print("Verbose mode enabled")
if response.status == ResponseStatus.ALL_FLAGS_VALID:
print("All flags are valid, proceeding...")
elif response.status == ResponseStatus.INVALID_VALUE_FLAGS:
print("Warning: Some flags have invalid values")
for flag in response.input_flags:
if flag.status == ValidationStatus.INVALID:
print(f" Invalid flag: {flag.string_entity} = {flag.input_value}")
+7
View File
@@ -0,0 +1,7 @@
from argenta import Command, Response, Router
user_router = Router(title="User Management")
@user_router.command(Command("add-user", description="Adds a new user"))
def add_user_handler(response: Response):
print("User added successfully!")
@@ -0,0 +1,31 @@
import sys
from unittest.mock import patch
import pytest
from pytest import CaptureFixture
from argenta import App, Orchestrator, Router, Command, Response
@pytest.fixture(autouse=True)
def patched_argv():
with patch.object(sys, "argv", ["program.py"]):
yield
def test_input_incorrect_command(capsys: CaptureFixture[str]):
router = Router()
orchestrator = Orchestrator()
@router.command(Command("test"))
def test(response: Response) -> None:
print("test command")
app = App(override_system_messages=True, printer=print)
app.include_router(router)
app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.trigger}"))
with patch("builtins.input", side_effect=["help", "q"]):
orchestrator.start_polling(app)
output = capsys.readouterr().out
assert "\nUnknown command: help\n" in output
@@ -0,0 +1,21 @@
import io
from contextlib import redirect_stdout
from argenta import App, Router, Command, Response
from argenta.command import InputCommand
def test_simple_app() -> None:
app = App(override_system_messages=True, repeat_command_groups_printing=False)
router = Router(title="App")
@router.command(Command("HELP", description="Show help"))
def help_cmd(response: Response):
print("Available commands: HELP")
app.include_router(router)
with redirect_stdout(io.StringIO()) as stdout:
router.finds_appropriate_handler(InputCommand.parse("HELP"))
assert "Available commands:" in stdout.getvalue()
@@ -0,0 +1,44 @@
import io
from contextlib import redirect_stdout
from argenta.command import InputCommand
from dishka import Provider, make_container, Scope
from argenta import Router, Response
from argenta.di.integration import setup_dishka, FromDishka
class Service:
def hello(self) -> str:
return "world"
def get_service() -> Service:
return Service()
router = Router(title="DI")
@router.command("HELLO")
def hello(response: Response, service: FromDishka[Service]) -> None:
print(f"hello {service.hello()}")
class _FakeApp:
# Minimal stub for setup_dishka; app object is not used in unit tests
registered_routers = [router]
def test_hello_uses_service():
provider = Provider(scope=Scope.APP)
provider.provide(get_service)
container = make_container(provider)
setup_dishka(app=_FakeApp(), container=container, auto_inject=True)
# Call handler
with redirect_stdout(io.StringIO()) as stdout:
router.finds_appropriate_handler(InputCommand.parse("HELLO"))
assert "hello world" in stdout.getvalue()
@@ -0,0 +1,20 @@
import io
from contextlib import redirect_stdout
from argenta import Router, Command, Response
from argenta.command import InputCommand
router = Router(title="Demo")
@router.command(Command("PING", description="Ping command"))
def ping(response: Response):
print("PONG")
def test_ping_prints_pong():
# Call handler
with redirect_stdout(io.StringIO()) as stdout:
router.finds_appropriate_handler(InputCommand.parse("PING"))
assert "PONG" in stdout.getvalue()
+48
View File
@@ -0,0 +1,48 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "Argenta"
copyright = "2025, kolo"
author = "kolo"
root_doc = "index"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
locale_dirs = ['locales/']
gettext_compact = False
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = "shibuya"
html_static_path = ["_static"]
html_context = {
"languages": [
("English", "/en/latest/%s.html", "en"),
("Русский", "/ru/latest/%s.html", "ru"),
]
}
html_theme_options = {
"accent_color": "cyan",
"nav_links": [
{
"title": "Sponsor me",
"url": "https://github.com/sponsors/koloideal"
},
],
"github_url": "https://github.com/koloideal/Argenta",
"linkedin_url": "https://www.linkedin.com/in/dmitry-shevelev-31b9a6324"
}
+74
View File
@@ -0,0 +1,74 @@
.. Argenta documentation master file, created by
sphinx-quickstart on Sat Oct 11 19:54:43 2025.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Argenta
=======
Что это и зачем?
----------------
**Библиотека для построения модульных CLI-приложений с простым и приятным API.**
Если у вас есть функциональность, которую вы хотите предоставить в виде CLI-приложения, Argenta поможет вам в этом.
Основная цель библиотеки — дать разработчикам возможность сосредоточиться на реализации своих идей, предоставляя для этого удобные абстракции.
.. image:: https://i.ibb.co/fzWcfgFq/2025-12-04-173045.png
:alt: App example
Argenta предназначена для создания приложений, работающих в собственном контексте (scope). Это означает, что приложение запускается один раз и создаёт интерактивную сессию, похожую на Python REPL или MySQL консоль. При запуске пользователь входит в эту сессию, где ему доступна вся реализованная вами функциональность.
Один из ключевых принципов библиотеки — цикличность. После выполнения команды пользователь остаётся в интерактивной сессии, в отличие от таких библиотек, как ``argparse``, ``click`` и ``typer``, где приложение завершается после каждой команды. Выход из сессии контролируется пользователем.
**Ключевые особенности:**
* **Интерактивные сессии**: В отличие от традиционных CLI-инструментов, ``Argenta`` создаёт циклические сессии, позволяя пользователю выполнять команды последовательно, не перезапуская приложение.
* **Декларативный синтаксис**: Команды и их обработчики объявляются с помощью простых декораторов, что делает код интуитивно понятным и позволяет сосредоточиться на том, "что" вы хотите сделать, а не "как".
* **Нативный DI**: Благодаря интеграции с `dishka <https://dishka.readthedocs.io/en/stable/>`_, вы можете легко внедрять зависимости прямо в обработчики команд, что упрощает их тестирование, позволяет избежать мутабельных глобалов и многое другое.
* **Автоматическая валидация и парсинг**: Библиотека берёт на себя обработку флагов и аргументов командной строки, включая их парсинг, валидацию и преобразование типов.
* **Гибкая настройка**: Вы можете легко кастомизировать системные сообщения, форматирование вывода, создавать кастомные обработчики нестандартного поведения и т.д.
-----
Архитектура и жизненный цикл
-----------------------------
Следующая диаграмма иллюстрирует, как компоненты Argenta взаимодействуют друг с другом, обрабатывая ввод пользователя.
.. image:: https://i.ibb.co/hF3FdFr1/argenta-intro-drawio-2.png
:alt: Request Lifecycle Diagram
:align: center
.. toctree::
:hidden:
:caption: Контент:
root/quickstart
root/error_handling
root/flags
root/overriding_formatting
root/api/index
.. toctree::
:hidden:
:caption: Продвинутое использование:
root/redirect_stdout
root/dependency_injection
root/testing
.. toctree::
:hidden:
:caption: Для разработчиков:
root/contributing
root/code_of_conduct
root/metrics
.. toctree::
:hidden:
:caption: Ссылки проекта:
GitHub <https://github.com/koloideal/argenta>
PyPI <https://pypi.org/project/argenta>
+30
View File
@@ -0,0 +1,30 @@
set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
set shell := ["bash", "-c"]
# Variables
sphinxopts := ""
sphinxbuild := "sphinx-build"
sourcedir := "."
builddir := "_build"
# Default recipe (help)
default:
@{{sphinxbuild}} -M help "{{sourcedir}}" "{{builddir}}" {{sphinxopts}}
# Build all language versions
build:
{{sphinxbuild}} -b html -D language=ru {{sourcedir}} {{builddir}}/html/ru
{{sphinxbuild}} -b html -D language =en {{sourcedir}} {{builddir}}/html/en
# Live preview for Russian version
live-ru:
sphinx-autobuild -b html . _build/html/ru -D language=ru
# Live preview for English version
live-en:
sphinx-autobuild -b html . _build/html/en -D language=en
# Update translation files
update-langs:
{{sphinxbuild}} -b gettext . _build/gettext
sphinx-intl update -p _build/gettext -l en
+177
View File
@@ -0,0 +1,177 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-04 20:41+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../index.rst:43
msgid "Контент:"
msgstr "Content:"
#: ../../index.rst:53
msgid "Продвинутое использование:"
msgstr "Advanced usage:"
#: ../../index.rst:61
msgid "Для разработчиков:"
msgstr "For developers:"
#: ../../index.rst:68
msgid "GitHub"
msgstr ""
#: ../../index.rst:68
msgid "PyPI"
msgstr ""
#: ../../index.rst:68
msgid "Ссылки проекта:"
msgstr "Project links:"
#: ../../index.rst:7
msgid "Argenta"
msgstr ""
#: ../../index.rst:10
msgid "Что это и зачем?"
msgstr "What is it and why?"
#: ../../index.rst:12
msgid ""
"**Библиотека для построения модульных CLI-приложений с простым и приятным"
" API.**"
msgstr ""
"**A library for building modular CLI applications with a simple and "
"pleasant API.**"
#: ../../index.rst:14
msgid ""
"Если у вас есть функциональность, которую вы хотите предоставить в виде "
"CLI-приложения, Argenta поможет вам в этом. Основная цель библиотеки — "
"дать разработчикам возможность сосредоточиться на реализации своих идей, "
"предоставляя для этого удобные абстракции."
msgstr ""
"If you have functionality that you want to provide as a CLI application, "
"Argenta will help you with that. The main goal of the library is to "
"enable developers to focus on implementing their ideas by providing "
"convenient abstractions."
#: ../../index.rst:17
msgid "App example"
msgstr ""
#: ../../index.rst:20
msgid ""
"Argenta предназначена для создания приложений, работающих в собственном "
"контексте (scope). Это означает, что приложение запускается один раз и "
"создаёт интерактивную сессию, похожую на Python REPL или MySQL консоль. "
"При запуске пользователь входит в эту сессию, где ему доступна вся "
"реализованная вами функциональность."
msgstr ""
"Argenta is designed for creating applications that work in their own "
"context (scope). This means that the application starts once and creates "
"an interactive session, similar to Python REPL or MySQL console. When "
"launched, the user enters this session where all the functionality you've"
" implemented is available."
#: ../../index.rst:22
msgid ""
"Один из ключевых принципов библиотеки — цикличность. После выполнения "
"команды пользователь остаётся в интерактивной сессии, в отличие от таких "
"библиотек, как ``argparse``, ``click`` и ``typer``, где приложение "
"завершается после каждой команды. Выход из сессии контролируется "
"пользователем."
msgstr ""
"One of the key principles of the library is cyclicity. After executing a "
"command, the user remains in the interactive session, "
"unlike libraries such as ``argparse``, ``click``, "
"and ``typer``, where the application terminates after each command. "
"Exiting the session is controlled by the user."
#: ../../index.rst:24
msgid "**Ключевые особенности:**"
msgstr "**Key features:**"
#: ../../index.rst:26
msgid ""
"**Интерактивные сессии**: В отличие от традиционных CLI-инструментов, "
"``Argenta`` создаёт циклические сессии, позволяя пользователю выполнять "
"команды последовательно, не перезапуская приложение."
msgstr ""
"**Interactive sessions**: Unlike traditional CLI tools, ``Argenta`` "
"creates cyclical sessions, allowing users to execute commands "
"sequentially without restarting the application."
#: ../../index.rst:27
msgid ""
"**Декларативный синтаксис**: Команды и их обработчики объявляются с "
"помощью простых декораторов, что делает код интуитивно понятным и "
"позволяет сосредоточиться на том, \"что\" вы хотите сделать, а не "
"\"как\"."
msgstr ""
"**Declarative syntax**: Commands and their handlers are declared using "
"simple decorators, making the code intuitive and allowing you to focus on"
" \"what\" you want to do, not \"how\"."
#: ../../index.rst:28
msgid ""
"**Нативный DI**: Благодаря интеграции с "
"`dishka <https://dishka.readthedocs.io/en/stable/>`_, вы можете легко "
"внедрять зависимости прямо в обработчики команд, что упрощает их "
"тестирование, позволяет избежать мутабельных глобалов и многое другое."
msgstr ""
"**Native DI**: Thanks to integration with `dishka "
"<https://dishka.readthedocs.io/en/stable/>`_, you can easily inject "
"dependencies directly into command handlers, simplifying their testing, "
"avoiding mutable globals, and much more."
#: ../../index.rst:29
msgid ""
"**Автоматическая валидация и парсинг**: Библиотека берёт на себя "
"обработку флагов и аргументов командной строки, включая их парсинг, "
"валидацию и преобразование типов."
msgstr ""
"**Automatic validation and parsing**: The library handles command-line "
"flags and arguments, including their parsing, validation, and type "
"conversion."
#: ../../index.rst:30
msgid ""
"**Гибкая настройка**: Вы можете легко кастомизировать системные "
"сообщения, форматирование вывода, создавать кастомные обработчики "
"нестандартного поведения и т.д."
msgstr ""
"**Flexible configuration**: You can easily customize system messages, "
"output formatting, create custom handlers for non-standard behavior, and "
"more."
#: ../../index.rst:35
msgid "Архитектура и жизненный цикл"
msgstr "Architecture and lifecycle"
#: ../../index.rst:37
msgid ""
"Следующая диаграмма иллюстрирует, как компоненты Argenta взаимодействуют "
"друг с другом, обрабатывая ввод пользователя."
msgstr ""
"The following diagram illustrates how Argenta components interact with "
"each other while processing user input."
#: ../../index.rst:39
msgid "Request Lifecycle Diagram"
msgstr ""
@@ -0,0 +1,135 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-22 04:26+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/app/autocompleter.rst:4
msgid "AutoCompleter"
msgstr ""
#: ../../root/api/app/autocompleter.rst:6
msgid ""
"``AutoCompleter`` — это компонент, отвечающий за интерактивное "
"автодополнение команд. Он улучшает пользовательский опыт, предлагая "
"подсказки и завершая ввод на основе истории команд, что ускоряет работу и"
" снижает вероятность опечаток."
msgstr ""
"``AutoCompleter`` is a component responsible for interactive command "
"autocompletion. It improves user experience by offering suggestions and "
"completing input based on command history, which speeds up work and "
"reduces the likelihood of typos."
#: ../../root/api/app/autocompleter.rst:11
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/app/autocompleter.rst:21
msgid "Создаёт и настраивает экземпляр ``AutoCompleter``."
msgstr "Creates and configures an ``AutoCompleter`` instance."
#: ../../root/api/app/autocompleter.rst:23
msgid ""
"``history_filename``: Имя файла для сохранения истории команд. Если "
"указано, история будет сохраняться между сессиями. При значении ``None`` "
"история хранится только в контексте сессии."
msgstr ""
"``history_filename``: Filename for saving command history. If specified, "
"history will be saved between sessions. When set to ``None``, history is "
"stored only within the session context."
#: ../../root/api/app/autocompleter.rst:24
msgid ""
"``autocomplete_button``: Клавиша, активирующая автодополнение. По "
"умолчанию — **Tab**."
msgstr ""
"``autocomplete_button``: Key that activates autocompletion. Defaults to "
"**Tab**."
#: ../../root/api/app/autocompleter.rst:25
msgid ""
"``command_highlighting``: Если True, то в реальном времени при вводе "
"команды она будет подсвечиваться: зелёным, если такой триггер существует "
"и красный, если нет."
msgstr ""
"``command_highlighting``: If True, then in real time, when entering a "
" command, it will be highlighted: green if such a trigger exists "
"and red if not."
#: ../../root/api/app/autocompleter.rst:26
msgid ""
"``auto_suggestions``: Если True, то дополнение до раннее введённой "
"команды будет сразу отображаться светло-серым в строке ввода."
msgstr ""
"``auto_suggestions``: If True, the addition to the previously entered "
" command will immediately be displayed in light gray in the input line."
#: ../../root/api/app/autocompleter.rst:31
msgid "Назначение и возможности"
msgstr "Purpose and Features"
#: ../../root/api/app/autocompleter.rst:33
msgid "Основные возможности ``AutoCompleter``:"
msgstr "Main features of ``AutoCompleter``:"
#: ../../root/api/app/autocompleter.rst:35
msgid ""
"**Автодополнение по истории**: При нажатии клавиши автодополнения (по "
"умолчанию **Tab**) система ищет в истории команды, начинающиеся с уже "
"введённого текста."
msgstr ""
"**History-based autocompletion**: When the autocompletion key is pressed "
"(by default **Tab**), the system searches history for commands starting "
"with the already entered text."
#: ../../root/api/app/autocompleter.rst:37
msgid ""
"**Общий префикс**: Если найдено несколько команд с общим префиксом, будет"
" подставлена только общая часть. Например, для команд ``show_users`` и "
"``show_profile`` при вводе ``sho`` и нажатии **Tab** ввод дополнится до "
"``show_``."
msgstr ""
"**Common prefix**: If multiple commands with a common prefix are found, "
"only the common part will be inserted. For example, for commands "
"``show_users`` and ``show_profile``, when entering ``sho`` and pressing "
"**Tab**, the input will be completed to ``show_``."
#: ../../root/api/app/autocompleter.rst:39
msgid ""
"**Постоянная история**: Если указан ``history_filename``, история команд "
"сохраняется в файл при выходе и загружается при следующем запуске. Это "
"делает автодополнение со временем «умнее»."
msgstr ""
"**Persistent history**: If ``history_filename`` is specified, command "
"history is saved to a file on exit and loaded on the next startup. This "
"makes autocompletion \"smarter\" over time."
#: ../../root/api/app/autocompleter.rst:41
msgid ""
"**Настройка клавиши**: Клавишу автодополнения можно изменить с помощью "
"параметра ``autocomplete_button``."
msgstr ""
"**Key customization**: The autocompletion key can be changed using the "
"``autocomplete_button`` parameter."
#: ../../root/api/app/autocompleter.rst:46
msgid "Пример использования"
msgstr "Usage Example"
#: ../../root/api/app/autocompleter.rst:48
msgid "``AutoCompleter`` передаётся как аргумент при инициализации `App`."
msgstr "``AutoCompleter`` is passed as an argument when initializing `App`."
@@ -0,0 +1,150 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-02 22:27+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/app/dividing_lines.rst:4
msgid "Dividing Lines"
msgstr "Dividing Lines"
#: ../../root/api/app/dividing_lines.rst:6
msgid ""
"Разделительные линии в ``Argenta`` используются для визуального "
"структурирования вывода и отделения блоков информации друг от друга. "
"Библиотека предлагает два типа линий: статическую и динамическую."
msgstr ""
"Dividing lines in ``Argenta`` are used for visual structuring of output and separating "
"information blocks from each other. The library offers two types of lines: static and dynamic."
#: ../../root/api/app/dividing_lines.rst:11
msgid "``StaticDividingLine``"
msgstr "``StaticDividingLine``"
#: ../../root/api/app/dividing_lines.rst:13
msgid ""
"``StaticDividingLine`` создаёт разделительную линию **фиксированной** "
"длины. Этот тип линии полезен для создания предсказуемого и "
"унифицированного интерфейса."
msgstr ""
"``StaticDividingLine`` creates a dividing line of **fixed** length. This type of line "
"is useful for creating a predictable and unified interface."
#: ../../root/api/app/dividing_lines.rst:21
msgid "Создаёт экземпляр статической разделительной линии."
msgstr "Creates a static dividing line instance."
#: ../../root/api/app/dividing_lines.rst:23
msgid ""
"``unit_part``: Символ для построения линии (учитывается только первый "
"символ). По умолчанию: ``-``."
msgstr ""
"``unit_part``: Character for building the line (only the first character is considered). "
"Defaults to: ``-``."
#: ../../root/api/app/dividing_lines.rst:24
msgid "``length``: Фиксированная длина линии. По умолчанию: ``25``."
msgstr "``length``: Fixed line length. Defaults to: ``25``."
#: ../../root/api/app/dividing_lines.rst:29
msgid "``DynamicDividingLine``"
msgstr "``DynamicDividingLine``"
#: ../../root/api/app/dividing_lines.rst:31
msgid ""
"``DynamicDividingLine`` создаёт линию, длина которой **динамически** "
"подстраивается под самую длинную строку в выводе команды. Это требует "
"перехвата ``stdout``, в результате чего разделители идеально обрамляют "
"выводимый контент."
msgstr ""
"``DynamicDividingLine`` creates a line whose length **dynamically** adjusts to the longest "
"line in the command output. This requires capturing ``stdout``, resulting in dividers that "
"perfectly frame the output content."
#: ../../root/api/app/dividing_lines.rst:38
msgid "Создаёт экземпляр динамической разделительной линии."
msgstr "Creates a dynamic dividing line instance."
#: ../../root/api/app/dividing_lines.rst:40
msgid "``unit_part``: Символ для построения линии. По умолчанию: ``-``."
msgstr "``unit_part``: Character for building the line. Defaults to: ``-``."
#: ../../root/api/app/dividing_lines.rst:42
msgid "Длина вычисляется автоматически и не задаётся при инициализации."
msgstr "Length is calculated automatically and is not set during initialization."
#: ../../root/api/app/dividing_lines.rst:45
msgid ""
"Обязательно почитайте про нюансы использования динамических линий и "
"перехвата ``stdout`` в :ref:`этом разделе<root_redirect_stdout>`."
msgstr ""
"Be sure to read about the nuances of using dynamic lines and capturing ``stdout`` "
"in :ref:`this section<root_redirect_stdout>`."
#: ../../root/api/app/dividing_lines.rst:50
msgid "Назначение и использование"
msgstr "Purpose and Usage"
#: ../../root/api/app/dividing_lines.rst:52
msgid "Выбор между статической и динамической линией зависит от ваших задач."
msgstr "The choice between static and dynamic lines depends on your needs."
#: ../../root/api/app/dividing_lines.rst:54
msgid "**StaticDividingLine** идеально подходит, если:"
msgstr "**StaticDividingLine** is ideal if:"
#: ../../root/api/app/dividing_lines.rst:56
msgid "Вам нужен строгий и консистентный дизайн."
msgstr "You need a strict and consistent design."
#: ../../root/api/app/dividing_lines.rst:57
msgid ""
"Вы используете роутеры с отключённым перехватом ``stdout`` "
"(``disable_redirect_stdout=True``), где динамическое вычисление длины "
"невозможно."
msgstr ""
"You are using routers with disabled ``stdout`` capture (``disable_redirect_stdout=True``), "
"where dynamic length calculation is not possible."
#: ../../root/api/app/dividing_lines.rst:59
msgid ""
"**DynamicDividingLine** (поведение по умолчанию) — предпочтительный "
"выбор, если:"
msgstr "**DynamicDividingLine** (default behavior) is the preferred choice if:"
#: ../../root/api/app/dividing_lines.rst:61
msgid "Вы хотите, чтобы интерфейс был адаптивным."
msgstr "You want the interface to be adaptive."
#: ../../root/api/app/dividing_lines.rst:62
msgid "Вывод ваших команд имеет разную длину."
msgstr "Your command output has varying lengths."
#: ../../root/api/app/dividing_lines.rst:63
msgid ""
"В ваших обработчиках нет интерактивных операций ввода (например, "
"``input()``)."
msgstr "Your handlers do not have interactive input operations (e.g., ``input()``)."
#: ../../root/api/app/dividing_lines.rst:65
msgid ""
"Тип разделителя для всего приложения задаётся при инициализации ``App`` "
"через параметр ``dividing_line``."
msgstr ""
"The divider type for the entire application is set during ``App`` initialization "
"via the ``dividing_line`` parameter."
@@ -0,0 +1,290 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-06 23:44+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/app/index.rst:4
msgid "App"
msgstr "App"
#: ../../root/api/app/index.rst:6
msgid ""
"Объект ``App`` — это ядро вашего консольного приложения. Он отвечает за "
"конфигурацию, управление жизненным циклом, обработку команд и "
"взаимодействие с пользователем, координируя работу всех компонентов: "
"роутеров, обработчиков и системных сообщений."
msgstr ""
"The ``App`` object is the implementations of your console application. It"
" handles configuration, lifecycle management, command processing, and "
"user interaction, coordinating the work of all components: routers, "
"handlers, and system messages."
#: ../../root/api/app/index.rst:11
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/app/index.rst:31
msgid "Создаёт и настраивает экземпляр приложения."
msgstr "Creates and configures an application instance."
#: ../../root/api/app/index.rst:33
msgid "``prompt``: Приглашение к вводу, отображаемое перед каждой командой."
msgstr "``prompt``: Input prompt displayed before each command."
#: ../../root/api/app/index.rst:34
msgid "``initial_message``: Сообщение, выводимое при запуске приложения."
msgstr "``initial_message``: Message displayed when the application starts."
#: ../../root/api/app/index.rst:35
msgid "``farewell_message``: Сообщение, выводимое при выходе из приложения."
msgstr "``farewell_message``: Message displayed when exiting the application."
#: ../../root/api/app/index.rst:36
msgid ""
"``exit_command``: Команда, которая маркируется как триггер для выхода из "
"приложения."
msgstr ""
"``exit_command``: Command that is marked as a trigger for exiting the "
"application."
#: ../../root/api/app/index.rst:37
msgid ""
"``system_router_title``: Заголовок для системного роутера (содержит "
"команду выхода)."
msgstr ""
"``system_router_title``: Title for the system router (contains the exit "
"command)."
#: ../../root/api/app/index.rst:38
msgid ""
"``dividing_line``: Тип разделительной линии (``StaticDividingLine`` или "
"``DynamicDividingLine``)."
msgstr ""
"``dividing_line``: Type of dividing line (``StaticDividingLine`` or "
"``DynamicDividingLine``)."
#: ../../root/api/app/index.rst:39
msgid ""
"``repeat_command_groups_printing``: Если ``True``, список доступных "
"команд выводится перед каждым вводом."
msgstr ""
"``repeat_command_groups_printing``: If ``True``, the list of available "
"commands is displayed before each input."
#: ../../root/api/app/index.rst:40
msgid ""
"``override_system_messages``: Если ``True``, стандартное форматирование "
"(цвета, ASCII-арт) отключается."
msgstr ""
"``override_system_messages``: If ``True``, standard formatting (colors, "
"ASCII art) is disabled."
#: ../../root/api/app/index.rst:41
msgid ""
"``autocompleter``: Экземпляр класса :ref:`AutoCompleter "
"<root_api_app_autocompleter>`, отвечающий за автодополнение команд."
msgstr ""
"``autocompleter``: Instance of the :ref:`AutoCompleter "
"<root_api_app_autocompleter>` class responsible for command "
"autocompletion."
#: ../../root/api/app/index.rst:42
#, fuzzy
msgid "``printer``: Функция для вывода всех системных сообщений."
msgstr ""
"``print_func``: Function for outputting all system messages (defaults to "
"``rich.Console().print``)."
#: ../../root/api/app/index.rst:47
msgid ""
"В приложениях на Argenta регистр вводимых команд не важен, проверка на "
"существование и роутинг команд производится на основании триггеров, "
"приведённых к нижнему регистру."
msgstr ""
"In applications on Argenta, the case of the entered commands is not "
"important, checking for the existence and routing of commands is "
"performed based on triggers reduced to lowercase."
#: ../../root/api/app/index.rst:50
msgid "Основные методы"
msgstr "Main Methods"
#: ../../root/api/app/index.rst:54
msgid ""
"Регистрирует роутер в приложении. Все команды из этого роутера становятся"
" доступными для вызова."
msgstr ""
"Registers a router in the application. All commands from this router "
"become available for invocation."
#: ../../root/api/app/index.rst
msgid "Parameters"
msgstr "Parameters"
#: ../../root/api/app/index.rst:56
msgid "Экземпляр ``Router`` для регистрации."
msgstr "``Router`` instance to register."
#: ../../root/api/app/index.rst:60
msgid "Регистрирует несколько роутеров одновременно."
msgstr "Registers multiple routers simultaneously."
#: ../../root/api/app/index.rst:62
msgid "Последовательность экземпляров ``Router`` для регистрации."
msgstr "Sequence of ``Router`` instances to register."
#: ../../root/api/app/index.rst:66
msgid ""
"Добавляет текстовое сообщение, которое выводится при запуске приложения "
"после ``initial_message``."
msgstr ""
"Adds a text message that is displayed when the application starts after "
"``initial_message``."
#: ../../root/api/app/index.rst:68
msgid "Строка с сообщением."
msgstr "String with the message."
#: ../../root/api/app/index.rst:71
msgid ""
"Для вывода стандартных сообщений можно использовать готовые шаблоны из "
":ref:`PredefinedMessages <root_api_predefined_messages>`."
msgstr ""
"For outputting standard messages, you can use ready-made templates from "
":ref:`PredefinedMessages <root_api_predefined_messages>`."
#: ../../root/api/app/index.rst:76
msgid "Методы установки обработчиков"
msgstr "Handler Setup Methods"
#: ../../root/api/app/index.rst:78
msgid ""
"``App`` позволяет настраивать реакцию на различные события, такие как "
"ошибки ввода или неизвестные команды."
msgstr ""
"``App`` allows you to configure responses to various events, such as "
"input errors or unknown commands."
#: ../../root/api/app/index.rst:81
msgid ""
"Подробнее об исключениях и их обработке в соответствующем :ref:`разделе "
"документации <root_error_handling>`."
msgstr ""
"For more details on exceptions and their handling, see the corresponding "
":ref:`documentation section <root_error_handling>`."
#: ../../root/api/app/index.rst:87
msgid "Устанавливает шаблон для форматирования описания команды."
msgstr "Sets the template for formatting command descriptions."
#: ../../root/api/app/index.rst:89
msgid "Обработчик принимает триггер команды (``str``) и её описание (``str``)."
msgstr ""
"The handler accepts the command trigger (``str``) and its description "
"(``str``)."
#: ../../root/api/app/index.rst:95
msgid "Устанавливает обработчик при некорректном введённом синтаксисе флагов."
msgstr "Sets the handler for incorrect flag syntax input."
#: ../../root/api/app/index.rst:97 ../../root/api/app/index.rst:105
msgid "Обработчик принимает строку, введённую пользователем."
msgstr "The handler accepts the string entered by the user."
#: ../../root/api/app/index.rst:103
msgid "Устанавливает обработчик при повторяющихся флагах в введённой команде."
msgstr "Sets the handler for duplicate flags in the entered command."
#: ../../root/api/app/index.rst:111
msgid "Устанавливает обработчик при вводе неизвестной команды."
msgstr "Sets the handler for entering an unknown command."
#: ../../root/api/app/index.rst:113
msgid "Обработчик принимает объект ``InputCommand`` - объект введённой команды."
msgstr ""
"The handler accepts an ``InputCommand`` object - the entered command "
"object."
#: ../../root/api/app/index.rst:119
msgid "Устанавливает обработчик при вводе пустой строки."
msgstr "Sets the handler for entering an empty string."
#: ../../root/api/app/index.rst:121
msgid "Обработчик не принимает аргументов."
msgstr "The handler accepts no arguments."
#: ../../root/api/app/index.rst:127
msgid "Переопределяет стандартное поведение при вызове команды выхода."
msgstr "Overrides the default behavior when the exit command is invoked."
#: ../../root/api/app/index.rst:129
msgid "Обработчик принимает объект ``Response``."
msgstr "The handler accepts a ``Response`` object."
#: ../../root/api/app/index.rst:142
msgid "PredefinedMessages"
msgstr "PredefinedMessages"
#: ../../root/api/app/index.rst:144
msgid ""
"``PredefinedMessages`` — это контейнер, содержащий набор готовых к "
"использованию сообщений. Они отформатированы с использованием синтаксиса "
"``rich`` и предназначены для вывода стандартной информации, такой как "
"подсказки по использованию."
msgstr ""
"``PredefinedMessages`` is a container containing a set of ready-to-use "
"messages. They are formatted using ``rich`` syntax and are intended for "
"displaying standard information, such as usage hints."
#: ../../root/api/app/index.rst:146
msgid "Рекомендуется использовать их при старте приложения."
msgstr "It is recommended to use them when starting the application."
#: ../../root/api/app/index.rst:173
msgid "Строка: ``[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]``"
msgstr "String: ``[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]``"
#: ../../root/api/app/index.rst:175
msgid "Отображается как: ``Usage: <command> <flags>``"
msgstr "Displayed as: ``Usage: <command> <flags>``"
#: ../../root/api/app/index.rst:179
msgid "Строка: ``[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]``"
msgstr "String: ``[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]``"
#: ../../root/api/app/index.rst:181
msgid "Отображается как: ``Help: <command> --help``"
msgstr "Displayed as: ``Help: <command> --help``"
#: ../../root/api/app/index.rst:185
msgid "Строка: ``[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>``"
msgstr "String: ``[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>``"
#: ../../root/api/app/index.rst:187
msgid "Отображается как: ``Autocomplete: <part> <tab>``"
msgstr "Displayed as: ``Autocomplete: <part> <tab>``"
#~ msgid ""
#~ "``ignore_command_register``: Если ``True``, регистр"
#~ " вводимых команд игнорируется при поиске"
#~ " обработчика."
#~ msgstr ""
#~ "``ignore_command_register``: If ``True``, command"
#~ " case is ignored when searching for"
#~ " a handler."
@@ -0,0 +1,105 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-04 20:39+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/bridge.rst:4
msgid "DataBridge"
msgstr "DataBridge"
#: ../../root/api/bridge.rst:6
msgid ""
"``DataBridge`` — это сущность, предоставляющая временное хранилище "
"данных, которое существует в рамках одной сессии приложения (от запуска "
"до выхода). Она предназначена для обмена данными между обработчиками."
msgstr ""
"``DataBridge`` is an entity that provides temporary data storage that "
"exists within a single application session (from startup to exit). It is "
"designed for data exchange between handlers."
#: ../../root/api/bridge.rst:8
msgid "Основной способ получения доступа к ``DataBridge`` — через DI."
msgstr "The main way to access ``DataBridge`` is through DI."
#: ../../root/api/bridge.rst:21
msgid "**Практический пример: Аутентификация**"
msgstr "**Practical Example: Authentication**"
#: ../../root/api/bridge.rst:23
msgid ""
"Рассмотрим пример, где команда `login` сохраняет токен аутентификации, а "
"команда `get-profile` использует его."
msgstr ""
"Let's consider an example where the `login` command saves an "
"authentication token, and the `get-profile` command uses it."
#: ../../root/api/bridge.rst:29
msgid "**Как это работает:**"
msgstr "**How it works:**"
#: ../../root/api/bridge.rst:31
msgid ""
"При вызове обработчика ``dishka`` автоматически внедряет экземпляр "
"``DataBridge``."
msgstr ""
"When calling a handler, ``dishka`` automatically injects a ``DataBridge``"
" instance."
#: ../../root/api/bridge.rst:32
msgid ""
"Команда ``login --username <имя>`` вызывает ``login_handler``, который "
"через внедрённый ``data_bridge`` сохраняет токен."
msgstr ""
"The ``login --username <name>`` command calls ``login_handler``, which "
"saves the token through the injected ``data_bridge``."
#: ../../root/api/bridge.rst:33
msgid ""
"Команда ``get-profile`` вызывает ``get_profile_handler``, который так же "
"получает ``data_bridge`` и извлекает из него токен."
msgstr ""
"The ``get-profile`` command calls ``get_profile_handler``, which also "
"receives ``data_bridge`` and extracts the token from it."
#: ../../root/api/bridge.rst:42
msgid ""
"Инициализирует хранилище. При использовании через DI вызывается "
"автоматически."
msgstr ""
"Initializes the storage. When used through DI, it is called automatically."
#: ../../root/api/bridge.rst:46
msgid "Обновляет хранилище данными из словаря."
msgstr "Updates the storage with data from a dictionary."
#: ../../root/api/bridge.rst:50
msgid "Возвращает все данные из хранилища."
msgstr "Returns all data from the storage."
#: ../../root/api/bridge.rst:54
msgid "Возвращает значение по ключу или ``None``, если ключ не найден."
msgstr "Returns the value by key or ``None`` if the key is not found."
#: ../../root/api/bridge.rst:58
msgid "Удаляет значение по ключу. Вызывает ``KeyError``, если ключ не найден."
msgstr "Deletes the value by key. Raises ``KeyError`` if the key is not found."
#: ../../root/api/bridge.rst:62
msgid "Полностью очищает хранилище."
msgstr "Completely clears the storage."
@@ -0,0 +1,335 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-02 22:27+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/command/flag.rst:4
msgid "Flag"
msgstr ""
#: ../../root/api/command/flag.rst:6
msgid ""
"``Flag`` — это сущность, описывающая флаг команды. Её основная задача — "
"определить параметры флага, включая его имя, префикс и правила валидации."
msgstr ""
"``Flag`` is an entity describing a command flag. Its main purpose is to define "
"flag parameters, including its name, prefix, and validation rules."
#: ../../root/api/command/flag.rst:10
msgid ""
"Документация по :ref:`PossibleValues <root_api_command_possible_values>` "
"— перечисление, определяющее типы допустимых значений."
msgstr ""
"Documentation for :ref:`PossibleValues <root_api_command_possible_values>` "
"— an enumeration defining types of allowed values."
#: ../../root/api/command/flag.rst:12
msgid ""
"Документация по :ref:`InputFlag <root_api_command_input_flag>` — объект "
"обработанного флага, введённого пользователем."
msgstr ""
"Documentation for :ref:`InputFlag <root_api_command_input_flag>` — an object "
"representing a processed flag entered by the user."
#: ../../root/api/command/flag.rst:14
msgid ""
":ref:`Общая информация <root_flags>` о флагах и их использовании в "
"``Argenta``"
msgstr ":ref:`General information <root_flags>` about flags and their usage in ``Argenta``"
#: ../../root/api/command/flag.rst:19
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/command/flag.rst:30
msgid "Создаёт новый флаг для регистрации в команде."
msgstr "Creates a new flag for registration in a command."
#: ../../root/api/command/flag.rst:32
msgid "``name``: Имя флага (обязательный параметр)."
msgstr "``name``: Flag name (required parameter)."
#: ../../root/api/command/flag.rst:33
msgid "``prefix``: Префикс флага (``-``, ``--``, ``---``). По умолчанию ``--``."
msgstr "``prefix``: Flag prefix (``-``, ``--``, ``---``). Defaults to ``--``."
#: ../../root/api/command/flag.rst:34
msgid ""
"``possible_values``: Правила валидации значения. Может быть списком "
"строк, регулярным выражением или значением из ``PossibleValues``. По "
"умолчанию ``PossibleValues.ALL``, то есть любое значение допустимо."
msgstr ""
"``possible_values``: Value validation rules. Can be a list of strings, a regular "
"expression, or a value from ``PossibleValues``. Defaults to ``PossibleValues.ALL``, "
"meaning any value is allowed."
#: ../../root/api/command/flag.rst:36
msgid "**Атрибуты:**"
msgstr "**Attributes:**"
#: ../../root/api/command/flag.rst:40
msgid "Имя флага в виде строки."
msgstr "Flag name as a string."
#: ../../root/api/command/flag.rst:44
msgid "Префикс флага. Один из: ``\"-\"``, ``\"--\"``, ``\"---\"``."
msgstr "Flag prefix. One of: ``\"-\"``, ``\"--\"``, ``\"---\"``."
#: ../../root/api/command/flag.rst:48
msgid "Допустимые значения для флага."
msgstr "Allowed values for the flag."
#: ../../root/api/command/flag.rst:50 ../../root/api/command/flag.rst:93
#: ../../root/api/command/flag.rst:113 ../../root/api/command/flag.rst:136
#: ../../root/api/command/flag.rst:253
msgid "**Пример использования:**"
msgstr "**Usage example:**"
#: ../../root/api/command/flag.rst:59
msgid "Свойства"
msgstr "Properties"
#: ../../root/api/command/flag.rst:62
msgid "string_entity"
msgstr ""
#: ../../root/api/command/flag.rst:70
msgid "Возвращает строковое представление флага в формате ``prefix + name``."
msgstr "Returns the string representation of the flag in the format ``prefix + name``."
#: ../../root/api/command/flag.rst
msgid "return"
msgstr "return"
#: ../../root/api/command/flag.rst:72 ../../root/api/command/flag.rst:91
msgid "Строковое представление флага"
msgstr "String representation of the flag"
#: ../../root/api/command/flag.rst:74
msgid ""
"Это свойство объединяет префикс и имя в единую строку, которая "
"представляет флаг так, как он выглядел бы в командной строке."
msgstr ""
"This property combines the prefix and name into a single string that represents "
"the flag as it would appear on the command line."
#: ../../root/api/command/flag.rst:79
msgid "Магические методы"
msgstr "Magic Methods"
#: ../../root/api/command/flag.rst:82
msgid "__str__"
msgstr ""
#: ../../root/api/command/flag.rst:89
msgid "Возвращает строковое представление флага (аналогично ``string_entity``)."
msgstr "Returns the string representation of the flag (similar to ``string_entity``)."
#: ../../root/api/command/flag.rst:102
msgid "__repr__"
msgstr ""
#: ../../root/api/command/flag.rst:109
msgid "Возвращает отладочное представление объекта."
msgstr "Returns the debug representation of the object."
#: ../../root/api/command/flag.rst:111
msgid "Строка в формате ``Flag<prefix=..., name=...>``."
msgstr "String in the format ``Flag<prefix=..., name=...>``."
#: ../../root/api/command/flag.rst:122
msgid "__eq__"
msgstr ""
#: ../../root/api/command/flag.rst:129
msgid ""
"Сравнивает два флага на равенство по их строковому представлению "
"(``string_entity``)."
msgstr ""
"Compares two flags for equality based on their string representation (``string_entity``)."
#: ../../root/api/command/flag.rst
msgid "param other"
msgstr "param other"
#: ../../root/api/command/flag.rst:131
msgid "Объект для сравнения"
msgstr "Object to compare"
#: ../../root/api/command/flag.rst:132
msgid "**True**, если флаги равны, иначе **False**"
msgstr "**True** if flags are equal, otherwise **False**"
#: ../../root/api/command/flag.rst:134
msgid "Два флага считаются равными, если их ``string_entity`` идентичны."
msgstr "Two flags are considered equal if their ``string_entity`` are identical."
#: ../../root/api/command/flag.rst:147
msgid "PredefinedFlags"
msgstr "PredefinedFlags"
#: ../../root/api/command/flag.rst:149
msgid "``argenta.command.PredefinedFlags``"
msgstr "``argenta.command.PredefinedFlags``"
#: ../../root/api/command/flag.rst:151
msgid ""
"Класс ``PredefinedFlags`` предоставляет набор готовых флагов для "
"использования в приложениях без их ручного создания. Эти флаги покрывают "
"распространённые сценарии."
msgstr ""
"The ``PredefinedFlags`` class provides a set of ready-made flags for use in "
"applications without manual creation. These flags cover common scenarios."
#: ../../root/api/command/flag.rst:153
msgid ""
"Все предопределённые флаги являются атрибутами класса и представляют "
"собой готовые экземпляры ``Flag``."
msgstr ""
"All predefined flags are class attributes and represent ready-made ``Flag`` instances."
#: ../../root/api/command/flag.rst:158
msgid "Информационные флаги"
msgstr "Informational Flags"
#: ../../root/api/command/flag.rst:163
msgid "Флаг для отображения справки: ``--help``"
msgstr "Flag for displaying help: ``--help``"
#: ../../root/api/command/flag.rst:165
msgid "``name``: ``\"help\"``"
msgstr "``name``: ``\"help\"``"
#: ../../root/api/command/flag.rst:166 ../../root/api/command/flag.rst:182
#: ../../root/api/command/flag.rst:224 ../../root/api/command/flag.rst:240
msgid "``prefix``: ``\"--\"`` (по умолчанию)"
msgstr "``prefix``: ``\"--\"`` (default)"
#: ../../root/api/command/flag.rst:167 ../../root/api/command/flag.rst:175
#: ../../root/api/command/flag.rst:183 ../../root/api/command/flag.rst:191
#: ../../root/api/command/flag.rst:204 ../../root/api/command/flag.rst:212
msgid "``possible_values``: ``PossibleValues.NEITHER``"
msgstr "``possible_values``: ``PossibleValues.NEITHER``"
#: ../../root/api/command/flag.rst:171
msgid "Короткая версия флага справки: ``-H``"
msgstr "Short version of the help flag: ``-H``"
#: ../../root/api/command/flag.rst:173
#: ../../root/api/command/flag.rst:231
msgid "``name``: ``\"H\"``"
msgstr "``name``: ``\"H\"``"
#: ../../root/api/command/flag.rst:174
#: ../../root/api/command/flag.rst:190
#: ../../root/api/command/flag.rst:211
#: ../../root/api/command/flag.rst:232
#: ../../root/api/command/flag.rst:248
msgid "``prefix``: ``\"-\"``"
msgstr "``prefix``: ``\"-\"``"
#: ../../root/api/command/flag.rst:179
msgid "Флаг для отображения информации: ``--info``"
msgstr "Flag for displaying information: ``--info``"
#: ../../root/api/command/flag.rst:181
msgid "``name``: ``\"info\"``"
msgstr "``name``: ``\"info\"``"
#: ../../root/api/command/flag.rst:187
msgid "Короткая версия флага информации: ``-I``"
msgstr "Short version of the info flag: ``-I``"
#: ../../root/api/command/flag.rst:189
msgid "``name``: ``\"I\"``"
msgstr "``name``: ``\"I\"``"
#: ../../root/api/command/flag.rst:196
msgid "Флаги выбора"
msgstr "Selection Flags"
#: ../../root/api/command/flag.rst:200
msgid "Флаг для выбора всех элементов: ``--all``"
msgstr "Flag for selecting all items: ``--all``"
#: ../../root/api/command/flag.rst:202
msgid "``name``: ``\"all\"``"
msgstr "``name``: ``\"all\"``"
#: ../../root/api/command/flag.rst:203
msgid "``prefix``: ``\"--\"``"
msgstr "``prefix``: ``\"--\"``"
#: ../../root/api/command/flag.rst:208
msgid "Короткая версия флага выбора всех элементов: ``-A``"
msgstr "Short version of the select all flag: ``-A``"
#: ../../root/api/command/flag.rst:210
msgid "``name``: ``\"A\"``"
msgstr "``name``: ``\"A\"``"
#: ../../root/api/command/flag.rst:217
msgid "Сетевые флаги"
msgstr "Network Flags"
#: ../../root/api/command/flag.rst:221
msgid "Флаг для указания IP-адреса хоста: ``--host``"
msgstr "Flag for specifying host IP address: ``--host``"
#: ../../root/api/command/flag.rst:223
msgid "``name``: ``\"host\"``"
msgstr "``name``: ``\"host\"``"
#: ../../root/api/command/flag.rst:225 ../../root/api/command/flag.rst:233
#, python-brace-format
msgid ""
"``possible_values``: Регулярное выражение для валидации IPv4: "
"``r\"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$\"``"
msgstr ""
"``possible_values``: Regular expression for IPv4 validation: "
"``r\"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$\"``"
#: ../../root/api/command/flag.rst:229
msgid "Короткая версия флага хоста: ``-H``"
msgstr "Short version of the host flag: ``-H``"
#: ../../root/api/command/flag.rst:237
msgid "Флаг для указания порта: ``--port``"
msgstr "Flag for specifying port: ``--port``"
#: ../../root/api/command/flag.rst:239
msgid "``name``: ``\"port\"``"
msgstr "``name``: ``\"port\"``"
#: ../../root/api/command/flag.rst:241 ../../root/api/command/flag.rst:249
#, python-brace-format
msgid ""
"``possible_values``: Регулярное выражение для валидации порта: "
"``r\"^\\d{1,5}$\"``"
msgstr ""
"``possible_values``: Regular expression for port validation: "
"``r\"^\\d{1,5}$\"``"
#: ../../root/api/command/flag.rst:245
msgid "Короткая версия флага порта: ``-P``"
msgstr "Short version of the port flag: ``-P``"
#: ../../root/api/command/flag.rst:247
msgid "``name``: ``\"P\"``"
msgstr "``name``: ``\"P\"``"
@@ -0,0 +1,172 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-02 22:27+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/command/flags.rst:4
msgid "Flags"
msgstr "Flags"
#: ../../root/api/command/flags.rst:6
msgid ""
"``Flags`` — это коллекция флагов команды. Её основная задача — "
"группировать и управлять набором флагов, зарегистрированных для "
"конкретной команды. ``Flags`` служит контейнером, который позволяет "
"удобно добавлять, извлекать, итерировать флаги и проверять их наличие."
msgstr ""
"``Flags`` is a collection of command flags. Its main purpose is to group and manage "
"the set of flags registered for a specific command. ``Flags`` serves as a container "
"that allows convenient addition, retrieval, iteration of flags, and checking their presence."
#: ../../root/api/command/flags.rst:10
msgid ""
"Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, "
":ref:`InputFlag <root_api_command_input_flag>`)"
msgstr ""
"Documentation for individual flags (:ref:`Flag <root_api_command_flag>`, "
":ref:`InputFlag <root_api_command_input_flag>`)"
#: ../../root/api/command/flags.rst:12
msgid ""
"Документация по :ref:`InputFlags <root_api_command_input_flags>` — "
"коллекция обработанных флагов, введённых пользователем."
msgstr ""
"Documentation for :ref:`InputFlags <root_api_command_input_flags>` — "
"a collection of processed flags entered by the user."
#: ../../root/api/command/flags.rst:14
msgid ""
":ref:`Общая информация <root_flags>` о флагах и их использовании в "
"приложении ``Argenta``"
msgstr ""
":ref:`General information <root_flags>` about flags and their usage in "
"the ``Argenta`` application"
#: ../../root/api/command/flags.rst:19
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/command/flags.rst:26
msgid "Создаёт новую коллекцию флагов."
msgstr "Creates a new flag collection."
#: ../../root/api/command/flags.rst:28
msgid ""
"``flags``: Необязательный список флагов типа ``Flag`` для инициализации "
"коллекции. Если не указан, создаётся пустая коллекция."
msgstr ""
"``flags``: Optional list of flags of type ``Flag`` for initializing the collection. "
"If not specified, an empty collection is created."
#: ../../root/api/command/flags.rst:30
msgid "**Атрибуты:**"
msgstr "**Attributes:**"
#: ../../root/api/command/flags.rst:35
msgid "Список всех зарегистрированных флагов типа ``Flag``."
msgstr "List of all registered flags of type ``Flag``."
#: ../../root/api/command/flags.rst:37 ../../root/api/command/flags.rst:63
#: ../../root/api/command/flags.rst:86 ../../root/api/command/flags.rst:109
msgid "**Пример использования:**"
msgstr "**Usage example:**"
#: ../../root/api/command/flags.rst:46
msgid "Методы"
msgstr "Methods"
#: ../../root/api/command/flags.rst:49
msgid "add_flag"
msgstr ""
#: ../../root/api/command/flags.rst:56
msgid "Добавляет флаг в коллекцию."
msgstr "Adds a flag to the collection."
#: ../../root/api/command/flags.rst
msgid "param flag"
msgstr "param flag"
#: ../../root/api/command/flags.rst:58
msgid "Флаг типа ``Flag`` для добавления."
msgstr "Flag of type ``Flag`` to add."
#: ../../root/api/command/flags.rst
msgid "return"
msgstr "return"
#: ../../root/api/command/flags.rst:59 ../../root/api/command/flags.rst:82
msgid "None."
msgstr "None."
#: ../../root/api/command/flags.rst:61
msgid "Используется для динамического расширения набора флагов."
msgstr "Used for dynamically extending the set of flags."
#: ../../root/api/command/flags.rst:72
msgid "add_flags"
msgstr ""
#: ../../root/api/command/flags.rst:79
msgid "Добавляет в коллекцию список флагов."
msgstr "Adds a list of flags to the collection."
#: ../../root/api/command/flags.rst
msgid "param flags"
msgstr "param flags"
#: ../../root/api/command/flags.rst:81
msgid "Список флагов типа ``Flag`` для добавления."
msgstr "List of flags of type ``Flag`` to add."
#: ../../root/api/command/flags.rst:84
msgid ""
"Метод расширяет коллекцию, добавляя в неё все флаги из переданного "
"списка. Эффективен для пакетного добавления."
msgstr ""
"The method extends the collection by adding all flags from the provided list. "
"Efficient for batch addition."
#: ../../root/api/command/flags.rst:95
msgid "get_flag_by_name"
msgstr ""
#: ../../root/api/command/flags.rst:102
msgid "Возвращает флаг по имени."
msgstr "Returns a flag by name."
#: ../../root/api/command/flags.rst
msgid "param name"
msgstr "param name"
#: ../../root/api/command/flags.rst:104
msgid "Имя искомого флага."
msgstr "Name of the flag to search for."
#: ../../root/api/command/flags.rst:105
msgid "Объект ``Flag`` или ``None``, если флаг не найден."
msgstr "``Flag`` object or ``None`` if the flag is not found."
#: ../../root/api/command/flags.rst:107
msgid ""
"Метод возвращает флаг с соответствующим именем. Если флаг не найден, "
"возвращается ``None``."
msgstr ""
"The method returns a flag with the corresponding name. If the flag is not found, "
"``None`` is returned."
@@ -0,0 +1,196 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-08 19:48+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/command/index.rst:4
msgid "Command"
msgstr "Command"
#: ../../root/api/command/index.rst:6
msgid ""
"``Command`` — это основная единица функциональности в приложении. Каждая "
"команда связывает хэндлер с триггером, введя который он будет вызван для "
"обработки."
msgstr ""
"``Command`` is the basic unit of functionality in an application. Each "
"command links a handler to a trigger, which when entered will invoke it "
"for processing."
#: ../../root/api/command/index.rst:8
msgid ""
"``Command`` инкапсулирует всю информацию о команде: её триггер (ключевое "
"слово для вызова), описание, набор флагов и множество псевдонимов."
msgstr ""
"``Command`` encapsulates all information about a command: its trigger "
"(keyword for invocation), description, set of flags, and set of aliases."
#: ../../root/api/command/index.rst:13
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/command/index.rst:23
msgid "Создаёт новую команду для регистрации в роутере."
msgstr "Creates a new command for registration in a router."
#: ../../root/api/command/index.rst:25
msgid ""
"``trigger``: Строковый триггер, который пользователь вводит для вызова "
"команды. Является основным идентификатором."
msgstr ""
"``trigger``: String trigger that the user enters to invoke the command. "
"Serves as the primary identifier."
#: ../../root/api/command/index.rst:26
msgid ""
"``description``: Необязательное описание, объясняющее назначение команды."
" Отображается в справке."
msgstr ""
"``description``: Optional description explaining the command's purpose. "
"Displayed in help."
#: ../../root/api/command/index.rst:27
msgid ""
"``flags``: Набор флагов для настройки поведения. Может быть одиночным "
"объектом ``Flag`` или коллекцией ``Flags``."
msgstr ""
"``flags``: Set of flags for configuring behavior. Can be a single "
"``Flag`` object or a ``Flags`` collection."
#: ../../root/api/command/index.rst:28
msgid "``aliases``: Множество строковых псевдонимов для основного триггера."
msgstr "``aliases``: Set of string aliases for the main trigger."
#: ../../root/api/command/index.rst:30 ../../root/api/command/index.rst:108
msgid "**Атрибуты:**"
msgstr "**Attributes:**"
#: ../../root/api/command/index.rst:34
msgid ""
"Основной триггер команды. Используется для её идентификации при обработке"
" пользовательского ввода."
msgstr ""
"The main command trigger. Used for its identification when processing "
"user input."
#: ../../root/api/command/index.rst:38
msgid ""
"Текстовое описание команды. Если не передано, используется значение по "
"умолчанию."
msgstr ""
"Text description of the command. If not provided, the default value is "
"used."
#: ../../root/api/command/index.rst:42
msgid ""
"Объект ``Flags``, содержащий все зарегистрированные флаги. Если был "
"передан ``Flag``, то автоматически конвертируется из одиночного в "
"коллекцию при инициализации."
msgstr ""
"A ``Flags`` object containing all registered flags. If a ``Flag`` was "
"passed, it is automatically converted from a single flag to a collection "
"during initialization."
#: ../../root/api/command/index.rst:46
msgid "Множество строковых псевдонимов. Пуст, если псевдонимы не заданы."
msgstr "Set of string aliases. Empty if no aliases are defined."
#: ../../root/api/command/index.rst:48
msgid "**Пример использования:**"
msgstr "**Usage example:**"
#: ../../root/api/command/index.rst:54
msgid ""
"Подробнее про флаги: :ref:`Flags <root_api_command_flags>` и :ref:`Флаги "
"команд <root_flags>`."
msgstr ""
"More about flags: :ref:`Flags <root_api_command_flags>` and :ref:`Command"
" flags <root_flags>`."
#: ../../root/api/command/index.rst:59
msgid "Регистрация команд"
msgstr "Command Registration"
#: ../../root/api/command/index.rst:61
msgid "Команды передаются в качестве аргумента в декоратор ``@router.command()``."
msgstr "Commands are passed as an argument to the ``@router.command()`` decorator."
#: ../../root/api/command/index.rst:63
msgid "**Базовый пример:**"
msgstr "**Basic example:**"
#: ../../root/api/command/index.rst:68
msgid "**Команды с флагами:**"
msgstr "**Commands with flags:**"
#: ../../root/api/command/index.rst:76
msgid "Работа с псевдонимами"
msgstr "Working with Aliases"
#: ../../root/api/command/index.rst:78
msgid ""
"Псевдонимы позволяют вызывать один и тот же обработчик разными "
"триггерами, сохраняя флаги и описание команды."
msgstr ""
"Aliases allow invoking the same handler with different triggers while "
"preserving the command's flags and description."
#: ../../root/api/command/index.rst:80
msgid "**Пример с псевдонимами:**"
msgstr "**Example with aliases:**"
#: ../../root/api/command/index.rst:85
msgid "Теперь пользователь может вызвать команду любым из способов:"
msgstr "Now the user can invoke the command in any of the following ways:"
#: ../../root/api/command/index.rst:94
msgid "Все эти варианты вызовут один и тот же хэндлер ``handle_shutdown``."
msgstr "All these variants will invoke the same handler ``handle_shutdown``."
#: ../../root/api/command/index.rst:101
msgid "InputCommand"
msgstr "InputCommand"
#: ../../root/api/command/index.rst:103
msgid ""
"``InputCommand`` представляет собой обработанную команду, введённую "
"пользователем. Этот внутренний класс создаётся автоматически при "
"обработке пользовательского ввода. Прямая работа с ним возможна при "
"создании пользовательского обработчика для неизвестных команд."
msgstr ""
"``InputCommand`` represents a processed command entered by the user. This"
" internal class is created automatically when processing user input. "
"Direct work with it is possible when creating a custom handler for "
"unknown commands."
#: ../../root/api/command/index.rst:106
msgid ""
"Подробнее о пользовательских обработчиках исключений см. :ref:`здесь "
"<root_error_handling_unknown_command>`."
msgstr ""
"For more details on custom exception handlers, see :ref:`here "
"<root_error_handling_unknown_command>`."
#: ../../root/api/command/index.rst:113
msgid "Строковый триггер, введённый пользователем."
msgstr "String trigger entered by the user."
#: ../../root/api/command/index.rst:118
msgid "Объект ``InputFlags``, содержащий все введённые и распаршенные флаги."
msgstr "An ``InputFlags`` object containing all entered and parsed flags."
@@ -0,0 +1,171 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-04 20:39+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/command/input_flag.rst:4
msgid "InputFlag"
msgstr "InputFlag"
#: ../../root/api/command/input_flag.rst:6
msgid ""
"Объект ``InputFlag`` представляет собой флаг, введённый пользователем. Он"
" создаётся в результате обработки пользовательского ввода и содержит "
"информацию о распознанном флаге: его имя, префикс, значение и статус "
"валидации."
msgstr ""
"The ``InputFlag`` object represents a flag entered by the user. It is "
"created as a result of processing user input and contains information "
"about the recognized flag: its name, prefix, value, and validation "
"status."
#: ../../root/api/command/input_flag.rst:10
msgid ""
"Документация по :ref:`Flag <root_api_command_flag>` — класс для "
"регистрации флага."
msgstr ""
"Documentation for :ref:`Flag <root_api_command_flag>` — class for "
"registering a flag."
#: ../../root/api/command/input_flag.rst:12
msgid ""
"Документация по :ref:`ValidationStatus "
"<root_api_command_validation_status>` — статусы валидации флагов."
msgstr ""
"Documentation for :ref:`ValidationStatus "
"<root_api_command_validation_status>` — flag validation statuses."
#: ../../root/api/command/input_flag.rst:17
msgid ""
"Экземпляры этого класса не предназначены для прямого создания. Они "
"содержатся в объекте :ref:`Response <root_api_response>`."
msgstr ""
"Instances of this class are not intended for direct creation. They are "
"contained in the :ref:`Response <root_api_response>` object."
#: ../../root/api/command/input_flag.rst:19
msgid "**Атрибуты:**"
msgstr "**Attributes:**"
#: ../../root/api/command/input_flag.rst:24
msgid "Имя введённого флага."
msgstr "Name of the entered flag."
#: ../../root/api/command/input_flag.rst:29
msgid "Префикс флага: ``-``, ``--`` или ``---``."
msgstr "Flag prefix: ``-``, ``--``, or ``---``."
#: ../../root/api/command/input_flag.rst:33
msgid ""
"Значение, переданное с флагом. Может быть ``''`` (пустой строкой) для "
"флагов без значений."
msgstr ""
"Value passed with the flag. Can be ``''`` (empty string) for flags "
"without values."
#: ../../root/api/command/input_flag.rst:38
msgid ""
"Статус валидации флага: ``ValidationStatus.VALID``, "
"``ValidationStatus.INVALID`` или ``ValidationStatus.UNDEFINED``."
msgstr ""
"Flag validation status: ``ValidationStatus.VALID``, "
"``ValidationStatus.INVALID``, or ``ValidationStatus.UNDEFINED``."
#: ../../root/api/command/input_flag.rst:43
msgid "Свойства"
msgstr "Properties"
#: ../../root/api/command/input_flag.rst:46
msgid "string_entity"
msgstr "string_entity"
#: ../../root/api/command/input_flag.rst:54
msgid "Возвращает строковое представление флага в формате ``prefix + name``."
msgstr ""
"Returns the string representation of the flag in the format ``prefix + "
"name``."
#: ../../root/api/command/input_flag.rst
msgid "return"
msgstr "return"
#: ../../root/api/command/input_flag.rst:56
msgid "Строковое представление флага"
msgstr "String representation of the flag"
#: ../../root/api/command/input_flag.rst:61
msgid "Магические методы"
msgstr "Magic Methods"
#: ../../root/api/command/input_flag.rst:64
msgid "__str__"
msgstr "__str__"
#: ../../root/api/command/input_flag.rst:71
msgid "Возвращает строковое представление флага вместе с его значением."
msgstr "Returns the string representation of the flag along with its value."
#: ../../root/api/command/input_flag.rst:73
msgid "Строка в формате ``флаг значение``."
msgstr "String in the format ``flag value``."
#: ../../root/api/command/input_flag.rst:75
#: ../../root/api/command/input_flag.rst:95
msgid "**Пример использования:**"
msgstr "**Usage example:**"
#: ../../root/api/command/input_flag.rst:84
msgid "__repr__"
msgstr "__repr__"
#: ../../root/api/command/input_flag.rst:91
msgid "Возвращает отладочное представление объекта."
msgstr "Returns the debug representation of the object."
#: ../../root/api/command/input_flag.rst:93
msgid ""
"Строка в формате ``InputFlag<prefix=..., name=..., value=..., "
"status=...>``."
msgstr ""
"String in the format ``InputFlag<prefix=..., name=..., value=..., "
"status=...>``."
#: ../../root/api/command/input_flag.rst:104
msgid "__eq__"
msgstr "__eq__"
#: ../../root/api/command/input_flag.rst:111
msgid "Сравнивает два введённых флага на равенство по имени."
msgstr "Compares two entered flags for equality by name."
#: ../../root/api/command/input_flag.rst
msgid "param other"
msgstr "param other"
#: ../../root/api/command/input_flag.rst:113
msgid "Объект для сравнения."
msgstr "Object to compare."
#: ../../root/api/command/input_flag.rst:114
msgid "**True**, если имена флагов совпадают, иначе **False**."
msgstr "**True** if flag names match, otherwise **False**."
#: ../../root/api/command/input_flag.rst:116
msgid "Два введённых флага считаются равными, если их имена совпадают."
msgstr "Two entered flags are considered equal if their names match."
@@ -0,0 +1,219 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2025, kolo
# This file is distributed under the same license as the Argenta package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: Argenta \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-12-02 22:27+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"
#: ../../root/api/command/input_flags.rst:4
msgid "InputFlags"
msgstr "InputFlags"
#: ../../root/api/command/input_flags.rst:6
msgid ""
"``InputFlags`` — это коллекция флагов, введённых пользователем. Её "
"основная задача — группировать и управлять набором флагов, переданных "
"вместе с командой. ``InputFlags`` служит контейнером, который позволяет "
"удобно извлекать, итерировать и проверять наличие флагов, а также "
"работать с их значениями и статусами валидации."
msgstr ""
"``InputFlags`` is a collection of flags entered by the user. Its main purpose is to "
"group and manage the set of flags passed with a command. ``InputFlags`` serves as a "
"container that allows convenient retrieval, iteration, and checking of flag presence, "
"as well as working with their values and validation statuses."
#: ../../root/api/command/input_flags.rst:10
msgid ""
"Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, "
":ref:`InputFlag <root_api_command_input_flag>`)"
msgstr ""
"Documentation for individual flags (:ref:`Flag <root_api_command_flag>`, "
":ref:`InputFlag <root_api_command_input_flag>`)"
#: ../../root/api/command/input_flags.rst:12
msgid ""
"Документация по :ref:`InputFlags <root_api_command_input_flags>` — "
"коллекция обработанных флагов, введённых пользователем."
msgstr ""
"Documentation for :ref:`InputFlags <root_api_command_input_flags>` — "
"a collection of processed flags entered by the user."
#: ../../root/api/command/input_flags.rst:14
msgid ""
"Документация по :ref:`Response <root_api_response>` — объект ответа, "
"содержащий ``InputFlags``"
msgstr ""
"Documentation for :ref:`Response <root_api_response>` — response object "
"containing ``InputFlags``"
#: ../../root/api/command/input_flags.rst:16
msgid ""
":ref:`Общая информация <root_flags>` о флагах и их использовании в "
"приложении ``Argenta``"
msgstr ""
":ref:`General information <root_flags>` about flags and their usage in "
"the ``Argenta`` application"
#: ../../root/api/command/input_flags.rst:21
msgid "Инициализация"
msgstr "Initialization"
#: ../../root/api/command/input_flags.rst:28
msgid "Создаёт новую коллекцию введённых флагов."
msgstr "Creates a new collection of entered flags."
#: ../../root/api/command/input_flags.rst:30
msgid ""
"``flags``: Необязательный список флагов типа ``InputFlag`` для "
"инициализации коллекции. Если не указан, создаётся пустая коллекция."
msgstr ""
"``flags``: Optional list of flags of type ``InputFlag`` for initializing the collection. "
"If not specified, an empty collection is created."
#: ../../root/api/command/input_flags.rst:33
msgid ""
"Экземпляры этого класса обычно не создаются напрямую. Они автоматически "
"формируются системой при обработке пользовательского ввода и доступны "
"через атрибут ``input_flags`` объекта ``Response``."
msgstr ""
"Instances of this class are usually not created directly. They are automatically "
"formed by the system when processing user input and are accessible through the "
"``input_flags`` attribute of the ``Response`` object."
#: ../../root/api/command/input_flags.rst:35
msgid "**Атрибуты:**"
msgstr "**Attributes:**"
#: ../../root/api/command/input_flags.rst:40
msgid ""
"Список всех введённых флагов типа ``InputFlag``. Пуст, если флаги не были"
" переданы при инициализации или пользователь не ввёл их с командой."
msgstr ""
"List of all entered flags of type ``InputFlag``. Empty if flags were not passed "
"during initialization or the user did not enter them with the command."
#: ../../root/api/command/input_flags.rst:42
#: ../../root/api/command/input_flags.rst:68
#: ../../root/api/command/input_flags.rst:94
#: ../../root/api/command/input_flags.rst:117
#: ../../root/api/command/input_flags.rst:131
msgid "**Пример использования:**"
msgstr "**Usage example:**"
#: ../../root/api/command/input_flags.rst:51
msgid "Методы"
msgstr "Methods"
#: ../../root/api/command/input_flags.rst:54
msgid "get_flag_by_name"
msgstr ""
#: ../../root/api/command/input_flags.rst:61
msgid "Возвращает флаг по имени."
msgstr "Returns a flag by name."
#: ../../root/api/command/input_flags.rst
msgid "param name"
msgstr "param name"
#: ../../root/api/command/input_flags.rst:63
msgid "Имя искомого флага (без префикса)."
msgstr "Name of the flag to search for (without prefix)."
#: ../../root/api/command/input_flags.rst
msgid "return"
msgstr "return"
#: ../../root/api/command/input_flags.rst:64
msgid "Объект ``InputFlag`` или ``None``, если флаг не найден."
msgstr "``InputFlag`` object or ``None`` if the flag is not found."
#: ../../root/api/command/input_flags.rst:66
msgid ""
"Метод возвращает первый флаг с соответствующим именем (без учёта "
"префикса)."
msgstr ""
"The method returns the first flag with the corresponding name (ignoring the prefix)."
#: ../../root/api/command/input_flags.rst:77
msgid "add_flag"
msgstr ""
#: ../../root/api/command/input_flags.rst:84
msgid "Добавляет введённый флаг в коллекцию."
msgstr "Adds an entered flag to the collection."
#: ../../root/api/command/input_flags.rst
msgid "param flag"
msgstr "param flag"
#: ../../root/api/command/input_flags.rst:86
msgid "Флаг типа ``InputFlag`` для добавления."
msgstr "Flag of type ``InputFlag`` to add."
#: ../../root/api/command/input_flags.rst:87
#: ../../root/api/command/input_flags.rst:113
msgid "None."
msgstr "None."
#: ../../root/api/command/input_flags.rst:89
msgid ""
"Метод добавляет флаг в конец списка ``flags``. Используется для "
"динамического расширения коллекции."
msgstr ""
"The method adds a flag to the end of the ``flags`` list. Used for dynamically extending the collection."
#: ../../root/api/command/input_flags.rst:92
msgid ""
"Этот метод используется редко, так как `InputFlags` обычно создаётся "
"автоматически. Однако он может быть полезен для тестирования или ручного "
"создания коллекций."
msgstr ""
"This method is rarely used, as `InputFlags` is usually created automatically. "
"However, it can be useful for testing or manual collection creation."
#: ../../root/api/command/input_flags.rst:103
msgid "add_flags"
msgstr ""
#: ../../root/api/command/input_flags.rst:110
msgid "Добавляет в коллекцию список введённых флагов."
msgstr "Adds a list of entered flags to the collection."
#: ../../root/api/command/input_flags.rst
msgid "param flags"
msgstr "param flags"
#: ../../root/api/command/input_flags.rst:112
msgid "Список флагов типа ``InputFlag`` для добавления."
msgstr "List of flags of type ``InputFlag`` to add."
#: ../../root/api/command/input_flags.rst:115
msgid ""
"Метод расширяет коллекцию, добавляя в неё все флаги из переданного "
"списка. Эффективен для пакетного добавления."
msgstr ""
"The method extends the collection by adding all flags from the provided list. "
"Efficient for batch addition."
#: ../../root/api/command/input_flags.rst:126
msgid "Практические примеры"
msgstr "Practical Examples"
#: ../../root/api/command/input_flags.rst:129
msgid "Обработка всех флагов с проверкой статусов"
msgstr "Processing All Flags with Status Checking"

Some files were not shown because too many files have changed in this diff Show More