diff --git a/.github/workflows/code-check.yml b/.github/workflows/code-check.yml index 499575b..a309e50 100644 --- a/.github/workflows/code-check.yml +++ b/.github/workflows/code-check.yml @@ -23,4 +23,4 @@ jobs: python-version: '3.11' - run: pip install --upgrade pip - run: make install - - run: make test-cov + - run: make test diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0163b77 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,15 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-toml + - id: check-added-large-files + + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: 'v0.0.287' + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] diff --git a/Makefile b/Makefile index 33f3bb9..5ea9c1b 100644 --- a/Makefile +++ b/Makefile @@ -30,13 +30,16 @@ test: ##@Testing Test application with pytest $(TEST) test-cov: ##@Testing Test application with pytest and create coverage report - $(TEST) --cov=$(APPLICATION_NAME) --cov-report html --cov-fail-under=85 + $(TEST) --cov=$(APPLICATION_NAME) --cov-report html --cov-fail-under=85 --cov-config pyproject.toml -lint: ##@Code Check code with pylint +lint: ##@Code Check code with ruff poetry run python3 -m ruff $(CODE) tests -format: ##@Code Reformat code with ruff and black +format: ##@Code Reformat code with ruff poetry run python3 -m ruff $(CODE) tests --fix +precommit: # Code Check code with pre-commit hooks + pre-commit run --all-files + clean: ##@Code Clean directory from garbage files rm -fr *.egg-info dist diff --git a/README.md b/README.md index c151295..a4d98cb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ -# ya_tracker_client -Async Yandex Tracker Client +# Yandex Tracker Client (or Yet Another Tracker Client) + +Async Yandex Tracker Client based on aiohttp and pydantic (v2) + +# Current library capabilities + +- Working with queues +- Getting information about issues, priorities and transitions +- Working with issue relationships +- Getting user information + +# TBD + +## Issues + +- [ ] Перенести задачу в другую очередь +- [ ] Узнать количество задач +- [ ] Найти задачи +- [ ] Освободить ресурсы просмотра прокрутки +- [ ] Выполнить переход в статус +- [ ] Получить историю изменений задачи + +## Queues - automation + +- [ ] Создать автодействие +- [ ] Получить параметры автодействия +- [ ] Создать триггер +- [ ] Получить параметры триггера + +# TBD in a long run + +- Checklists +- Projects +- Comments +- Macros +- Internal links +- Attachments +- Tables of tasks +- Components +- Import +- Package operations +- Time scoring +- Issues fields +- Users diff --git a/examples/get_issue.py b/examples/get_issue.py index bfd32d6..1c13ff3 100644 --- a/examples/get_issue.py +++ b/examples/get_issue.py @@ -8,9 +8,9 @@ load_dotenv() # from registered application at Yandex OAuth - https://oauth.yandex.ru/ -API_TOKEN = os.getenv('API_TOKEN') +API_TOKEN = os.getenv("API_TOKEN") # from admin panel at Yandex Tracker - https://tracker.yandex.ru/admin/orgs -API_ORGANISATION_ID = os.getenv('API_ORGANISATION_ID') +API_ORGANISATION_ID = os.getenv("API_ORGANISATION_ID") async def main() -> None: @@ -18,10 +18,18 @@ async def main() -> None: organisation_id=API_ORGANISATION_ID, oauth_token=API_TOKEN, ) - issue = await client.get_issue('TRACKER-1') - print(issue) + + me = await client.get_myself() + print(me) + + me = await client.get_user(me.login, me.uid) + print(me) + + all_me = await client.get_users() + print(all_me) + await client.stop() -if __name__ == '__main__': +if __name__ == "__main__": run(main()) diff --git a/poetry.lock b/poetry.lock index 0048643..eee45e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -203,6 +203,103 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "charset-normalizer" version = "3.2.0" @@ -377,6 +474,22 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "distlib" +version = "0.3.7" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "faker" version = "19.6.1" @@ -396,6 +509,27 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "filelock" +version = "3.12.4" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, + {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] +typing = ["typing-extensions (>=4.7.1)"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "frozenlist" version = "1.4.0" @@ -471,81 +605,142 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "gevent" +version = "23.9.1" +description = "Coroutine-based network library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "gevent-23.9.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:a3c5e9b1f766a7a64833334a18539a362fb563f6c4682f9634dea72cbe24f771"}, + {file = "gevent-23.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b101086f109168b23fa3586fccd1133494bdb97f86920a24dc0b23984dc30b69"}, + {file = "gevent-23.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36a549d632c14684bcbbd3014a6ce2666c5f2a500f34d58d32df6c9ea38b6535"}, + {file = "gevent-23.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:272cffdf535978d59c38ed837916dfd2b5d193be1e9e5dcc60a5f4d5025dd98a"}, + {file = "gevent-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcb8612787a7f4626aa881ff15ff25439561a429f5b303048f0fca8a1c781c39"}, + {file = "gevent-23.9.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:d57737860bfc332b9b5aa438963986afe90f49645f6e053140cfa0fa1bdae1ae"}, + {file = "gevent-23.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5f3c781c84794926d853d6fb58554dc0dcc800ba25c41d42f6959c344b4db5a6"}, + {file = "gevent-23.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dbb22a9bbd6a13e925815ce70b940d1578dbe5d4013f20d23e8a11eddf8d14a7"}, + {file = "gevent-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:707904027d7130ff3e59ea387dddceedb133cc742b00b3ffe696d567147a9c9e"}, + {file = "gevent-23.9.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:45792c45d60f6ce3d19651d7fde0bc13e01b56bb4db60d3f32ab7d9ec467374c"}, + {file = "gevent-23.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e24c2af9638d6c989caffc691a039d7c7022a31c0363da367c0d32ceb4a0648"}, + {file = "gevent-23.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1ead6863e596a8cc2a03e26a7a0981f84b6b3e956101135ff6d02df4d9a6b07"}, + {file = "gevent-23.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65883ac026731ac112184680d1f0f1e39fa6f4389fd1fc0bf46cc1388e2599f9"}, + {file = "gevent-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7af500da05363e66f122896012acb6e101a552682f2352b618e541c941a011"}, + {file = "gevent-23.9.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c3e5d2fa532e4d3450595244de8ccf51f5721a05088813c1abd93ad274fe15e7"}, + {file = "gevent-23.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c84d34256c243b0a53d4335ef0bc76c735873986d478c53073861a92566a8d71"}, + {file = "gevent-23.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ada07076b380918829250201df1d016bdafb3acf352f35e5693b59dceee8dd2e"}, + {file = "gevent-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:921dda1c0b84e3d3b1778efa362d61ed29e2b215b90f81d498eb4d8eafcd0b7a"}, + {file = "gevent-23.9.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:ed7a048d3e526a5c1d55c44cb3bc06cfdc1947d06d45006cc4cf60dedc628904"}, + {file = "gevent-23.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c1abc6f25f475adc33e5fc2dbcc26a732608ac5375d0d306228738a9ae14d3b"}, + {file = "gevent-23.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4368f341a5f51611411ec3fc62426f52ac3d6d42eaee9ed0f9eebe715c80184e"}, + {file = "gevent-23.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52b4abf28e837f1865a9bdeef58ff6afd07d1d888b70b6804557e7908032e599"}, + {file = "gevent-23.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52e9f12cd1cda96603ce6b113d934f1aafb873e2c13182cf8e86d2c5c41982ea"}, + {file = "gevent-23.9.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:de350fde10efa87ea60d742901e1053eb2127ebd8b59a7d3b90597eb4e586599"}, + {file = "gevent-23.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fde6402c5432b835fbb7698f1c7f2809c8d6b2bd9d047ac1f5a7c1d5aa569303"}, + {file = "gevent-23.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:dd6c32ab977ecf7c7b8c2611ed95fa4aaebd69b74bf08f4b4960ad516861517d"}, + {file = "gevent-23.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:455e5ee8103f722b503fa45dedb04f3ffdec978c1524647f8ba72b4f08490af1"}, + {file = "gevent-23.9.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7ccf0fd378257cb77d91c116e15c99e533374a8153632c48a3ecae7f7f4f09fe"}, + {file = "gevent-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d163d59f1be5a4c4efcdd13c2177baaf24aadf721fdf2e1af9ee54a998d160f5"}, + {file = "gevent-23.9.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7532c17bc6c1cbac265e751b95000961715adef35a25d2b0b1813aa7263fb397"}, + {file = "gevent-23.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:78eebaf5e73ff91d34df48f4e35581ab4c84e22dd5338ef32714264063c57507"}, + {file = "gevent-23.9.1-cp38-cp38-win32.whl", hash = "sha256:f632487c87866094546a74eefbca2c74c1d03638b715b6feb12e80120960185a"}, + {file = "gevent-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:62d121344f7465e3739989ad6b91f53a6ca9110518231553fe5846dbe1b4518f"}, + {file = "gevent-23.9.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:bf456bd6b992eb0e1e869e2fd0caf817f0253e55ca7977fd0e72d0336a8c1c6a"}, + {file = "gevent-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43daf68496c03a35287b8b617f9f91e0e7c0d042aebcc060cadc3f049aadd653"}, + {file = "gevent-23.9.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7c28e38dcde327c217fdafb9d5d17d3e772f636f35df15ffae2d933a5587addd"}, + {file = "gevent-23.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fae8d5b5b8fa2a8f63b39f5447168b02db10c888a3e387ed7af2bd1b8612e543"}, + {file = "gevent-23.9.1-cp39-cp39-win32.whl", hash = "sha256:2c7b5c9912378e5f5ccf180d1fdb1e83f42b71823483066eddbe10ef1a2fcaa2"}, + {file = "gevent-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:a2898b7048771917d85a1d548fd378e8a7b2ca963db8e17c6d90c76b495e0e2b"}, + {file = "gevent-23.9.1.tar.gz", hash = "sha256:72c002235390d46f94938a96920d8856d4ffd9ddf62a303a0d7c118894097e34"}, +] + +[package.dependencies] +cffi = {version = ">=1.12.2", markers = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\""} +greenlet = {version = ">=3.0rc3", markers = "platform_python_implementation == \"CPython\" and python_version >= \"3.11\""} +"zope.event" = "*" +"zope.interface" = "*" + +[package.extras] +dnspython = ["dnspython (>=1.16.0,<2.0)", "idna"] +docs = ["furo", "repoze.sphinx.autointerface", "sphinx", "sphinxcontrib-programoutput", "zope.schema"] +monitor = ["psutil (>=5.7.0)"] +recommended = ["cffi (>=1.12.2)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)"] +test = ["cffi (>=1.12.2)", "coverage (>=5.0)", "dnspython (>=1.16.0,<2.0)", "idna", "objgraph", "psutil (>=5.7.0)", "requests", "setuptools"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "greenlet" -version = "2.0.2" +version = "3.0.0rc3" description = "Lightweight in-process concurrent programming" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +python-versions = ">=3.7" files = [ - {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, - {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, - {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, - {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, - {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, - {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, - {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, - {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, - {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, - {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, - {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, - {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, - {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, - {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, - {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, - {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, - {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, - {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, - {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, - {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, - {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, - {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a2affddff9b2f846f40799673e41b29f0500582415c860fca8f146858e9de1a"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd00046dfd00767fce18f9933658d126652a500caf7af9dbfbd43818e4b484c2"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e787b00002cef3b98c7cf700fb85c2c01b0d202b1c6731706e5baa4b3325aa1e"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ffc7538bc66766a8b551888903d415773481c4bd13560a4fb24887222e3cc9"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dde5deb355b34bbf44b15789e27c56862f51f417207be49eedc58fce34681fe6"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1fb703a102a02361a0cc6a3d9a7958e1584fdeb536bd37ca9aca529d3356bedd"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f8661d14d3e07f2ceeb850e4cbcc7114bdf90a8dc82d63d37b08a50bb6955a77"}, + {file = "greenlet-3.0.0rc3-cp310-cp310-win_amd64.whl", hash = "sha256:997456b74efee91ceeb39d63818909da5dbb712a07f7742f4378986ac3473463"}, + {file = "greenlet-3.0.0rc3-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:d3cd3957af8cec1fcfd87d92ca71b7d434d798036e14ae878f9ab1e07d99da0d"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:895b689fc52a5bc402f8d624705110df5c265b1410ffe8e0769a66db9d2e7851"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a84a88422b5a0360fae57ad6b3b20fc17c9462880929810b0a26ee43aa05982e"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d79cf299ba1996d8a4f133b317e709a0a3ce87181308280e40664e12cb512c54"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9789aea735004eba559c7919a73a3b475d0c28e2c1e9de464c6bc761bf69f4"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66790e1537382e53bce64de3a695d1b12a04b00104df45f7ef472a10561936c2"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:68349987bf2ce274953f9f9b28458869bd8770a0c5461e1ef91d8107b1bae361"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30ffaa6c020a615c8f4be3abfc6029982fda026a3bf9a6dc7205afb033251506"}, + {file = "greenlet-3.0.0rc3-cp311-cp311-win_amd64.whl", hash = "sha256:864619b058f573058cd77f6944cf63d7f42157fe30be494798721bd8ac256d7b"}, + {file = "greenlet-3.0.0rc3-cp311-universal2-macosx_10_9_universal2.whl", hash = "sha256:7c887ecb55374d585d71ff8f9d07c137637694e88fa2b5d5b1450a05ece62ae9"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:686821157368c1c4ef53aa68e6801280010da92ab0e4265dad37003341fca6a1"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:242d56d2d5f6859f0f086ce62555a2c692c8053c89721d41fead5e1e8dffdb36"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81d653ae6c64b85ce4c7bccbea7b630de8799da751b73e55b4c68875b6eb19d6"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beeb5cfbd8f3792c37db4e3c5665aa750d78bbdabe758161a34e7dfe27075e69"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30daee988fc83078b016fa95a7a1f78a7c86534a44238748b9748675814eb1dc"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:977898b8c24159467c66ed1a8f62aacd33f3d85f852cf413d0d2e2a87a6b3091"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:097a2f75c79c3fa76fea2e5d48a637233722fe72a5ebb1213c55f0a0898f481c"}, + {file = "greenlet-3.0.0rc3-cp312-cp312-win_amd64.whl", hash = "sha256:5770d43b08dfa10f4460c1bd51f8c80e6f2c47611054e9fb80d4d7976d07e560"}, + {file = "greenlet-3.0.0rc3-cp312-universal2-macosx_10_9_universal2.whl", hash = "sha256:f33e7ff85775cb0ec6abb0950ffc631960bae5a203da38166fc3dfde826e0d0a"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07f6d1ce31a1db5102a42b4afa609af330edfd8a81d10faba3e47ae33a07cbdf"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86e651fa59263f7ff1d4657b086c48cfe7e26db2a36e2d74069f3b5aeab478e6"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef7c6e49a9a020d56349c6a769352709bfbe35d3ee7f98bd5efcac6cedbdc162"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5585bf8d1d2d3712010ee74988c2ed85c54b127b97f2778fbdcc5b3ea8e801a2"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c706041cd92e1b9d2b602eaa31e94aad14453bdbf186ce77530f25167c173a0e"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:37213e72058d2e6231d18417adc63c698c040fbb47dc59a3fd633973214ab1ab"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:95bc6ec8dd73f8f36e9dfc61a7fa5a2819d1cd52d0bfdb70a43434d6b2aeb239"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-win32.whl", hash = "sha256:e83c4c7a0814dcfd7e2fe4b74a371f3ce489b62ff02e81d0c5cacc8ba4750395"}, + {file = "greenlet-3.0.0rc3-cp37-cp37m-win_amd64.whl", hash = "sha256:4c35608918f331256be199d3712552fa8a1d12f87ac171a86a31488c60d298f5"}, + {file = "greenlet-3.0.0rc3-cp37-universal2-macosx_11_0_x86_64.whl", hash = "sha256:215bdb33e85fd89fe55f9984dc6f0a96b5774bace663e1a6d051e65d66170ef8"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69db00f775ed9d233f53ef67c66ea40a7add0c0929eb528f633982e27595dd37"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fcc7162944c2fedfb2253ca2171267e016a3b065c73369d0d4a27f601e7f162"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c0082d7b83312c59127811367089f812f8f1386fad7e8cf321fd732b4a6ace6"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66f1131c17dba115ea7cb3b257b6751b3c4cfd324f2121447e2483f57abbbf3c"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0c5508582339090b99e2863a157fc2708ab9c8b5cd21619bdcb04edcdc6c28d"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f1c9ad8d6500f7b142a94054281d9628bc8652a14b0923d02e0dfd87392fbc74"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bd586284bbf18ca3068e1fcc67ef54538e1bb74cb605ebdac9e62048237839f5"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-win32.whl", hash = "sha256:1c16f1bbaf9c75dfac3e52bb778d2fd6099fd5aa59fafa678eca5853eedd99ec"}, + {file = "greenlet-3.0.0rc3-cp38-cp38-win_amd64.whl", hash = "sha256:e388ceb55b8f3f388afea4d4a17a64b619040f0e8e9fa3e17e7c34f4d0fbe103"}, + {file = "greenlet-3.0.0rc3-cp38-universal2-macosx_11_0_x86_64.whl", hash = "sha256:68bd35ad9f99df0ef18836fd0fb34278dca6b3350bdcf1e8809822fc4f57a82e"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:256b748fc1e6c97012f217e0a403116cb0dd369bf1cff51c07a9c52899d4a8a8"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4936e6e051932848c4b237a874da8dbb47bfbb5ae5104497fb78c4f4cf184989"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a31b3a4bd10c540a7eb7d4b43d16779813ca4c79b615ed6d4ebf0e5a782d9fa0"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6f8253fdb00e74b928ab5d04f88ddbc8beb0cc26aa978bb4a12c1513166d481"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a7831d04a0f8a14645c010e3fb3fa36b8d2df304dd837948427ccfec2524ddf"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ae84d2f2658990f29df4ea753061b25c337bd70f805128af328098e5b8afc454"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cd51cc2528a2985f3bc0564c1b1ce5b2e6fa4ee9924503010428256fa95b0e3c"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-win32.whl", hash = "sha256:e8698f341e78dd0f149511929e92d1507cc26647f047db13987169d244db10fb"}, + {file = "greenlet-3.0.0rc3-cp39-cp39-win_amd64.whl", hash = "sha256:f059457db4e2ae4a4fdae455453c5e5765aa08efcb804e2a106c69c31bd438ba"}, + {file = "greenlet-3.0.0rc3-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:c80cac2776df3dd08f27b7338f467a62ee6cb29668a8f4f408b8da1f981aae9e"}, + {file = "greenlet-3.0.0rc3.tar.gz", hash = "sha256:0df5c2ad154f457fd372e39723493b3df519330a4c1bff3ca901be66130f379b"}, ] [package.extras] -docs = ["Sphinx", "docutils (<0.18)"] +docs = ["Sphinx"] test = ["objgraph", "psutil"] [package.source] @@ -553,6 +748,25 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "identify" +version = "2.5.29" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.5.29-py2.py3-none-any.whl", hash = "sha256:24437fbf6f4d3fe6efd0eb9d67e24dd9106db99af5ceb27996a5f7895f24bf1b"}, + {file = "identify-2.5.29.tar.gz", hash = "sha256:d43d52b86b15918c137e3a74fff5224f60385cd0e9c38e99d07c257f02f151a5"}, +] + +[package.extras] +license = ["ukkonen"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "idna" version = "3.4" @@ -673,6 +887,25 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "nodeenv" +version = "1.8.0" +description = "Node.js virtual environment builder" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] + +[package.dependencies] +setuptools = "*" + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "packaging" version = "23.1" @@ -689,6 +922,26 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "platformdirs" +version = "3.10.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "pluggy" version = "1.3.0" @@ -711,13 +964,13 @@ reference = "default-pypi" [[package]] name = "polyfactory" -version = "2.8.2" +version = "2.9.0" description = "Mock data generation factories" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "polyfactory-2.8.2-py3-none-any.whl", hash = "sha256:82f0a7662eedb713260508a82587a4e37dc290a22e8715862d806a6a40c74388"}, - {file = "polyfactory-2.8.2.tar.gz", hash = "sha256:1f2571b143172f22f9ad1f85dec8b79e83a0620ea5844f1a1f67d275df6cc465"}, + {file = "polyfactory-2.9.0-py3-none-any.whl", hash = "sha256:7513347be6327739174dbd4ca6ddd96981fb697437283acb5362a604cf6d7f58"}, + {file = "polyfactory-2.9.0.tar.gz", hash = "sha256:af61fc5b03d0c5bb343a2289bdce457f27bbf8aefba69c592dca0841f905e7a5"}, ] [package.dependencies] @@ -727,10 +980,50 @@ typing-extensions = "*" [package.extras] attrs = ["attrs (>=22.2.0)"] beanie = ["beanie", "pydantic[email]"] -full = ["attrs (>=22.2.0)", "beanie", "msgspec", "odmantic", "pydantic[email]"] +full = ["attrs (>=22.2.0)", "beanie", "msgspec", "odmantic", "pydantic[email]", "sqlalchemy (>=2)"] msgspec = ["msgspec"] odmantic = ["odmantic", "pydantic[email]"] pydantic = ["pydantic[email]"] +sqlalchemy = ["sqlalchemy (>=2)"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + +[[package]] +name = "pre-commit" +version = "3.4.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pre_commit-3.4.0-py2.py3-none-any.whl", hash = "sha256:96d529a951f8b677f730a7212442027e8ba53f9b04d217c4c67dc56c393ad945"}, + {file = "pre_commit-3.4.0.tar.gz", hash = "sha256:6bbd5129a64cad4c0dfaeeb12cd8f7ea7e15b77028d985341478c8af3c759522"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] [package.source] type = "legacy" @@ -993,6 +1286,70 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "ruff" version = "0.0.287" @@ -1024,6 +1381,27 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "setuptools" +version = "68.2.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [[package]] name = "six" version = "1.16.0" @@ -1042,15 +1420,40 @@ reference = "default-pypi" [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + +[[package]] +name = "virtualenv" +version = "20.24.5" +description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"}, + {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"}, ] +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<4" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [package.source] type = "legacy" url = "https://pypi.org/simple" @@ -1148,7 +1551,82 @@ type = "legacy" url = "https://pypi.org/simple" reference = "default-pypi" +[[package]] +name = "zope-event" +version = "5.0" +description = "Very basic event publishing system" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26"}, + {file = "zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +docs = ["Sphinx"] +test = ["zope.testrunner"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + +[[package]] +name = "zope-interface" +version = "6.0" +description = "Interfaces for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zope.interface-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990"}, + {file = "zope.interface-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f"}, + {file = "zope.interface-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410"}, + {file = "zope.interface-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28"}, + {file = "zope.interface-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518"}, + {file = "zope.interface-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb"}, + {file = "zope.interface-6.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc"}, + {file = "zope.interface-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373"}, + {file = "zope.interface-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f"}, + {file = "zope.interface-6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f"}, + {file = "zope.interface-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8"}, + {file = "zope.interface-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2"}, + {file = "zope.interface-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2"}, + {file = "zope.interface-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5"}, + {file = "zope.interface-6.0.tar.gz", hash = "sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +docs = ["Sphinx", "repoze.sphinx.autointerface"] +test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] +testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "default-pypi" + [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "9a022933e963a9c550aa1f40f5e1289f3c4a32f125f2df1a2f7b0fcc396e9cd9" +content-hash = "5742240cf43cd84ec572a4a57e69e78cd4e2127043ec939e76601ead5514f96c" diff --git a/pyproject.toml b/pyproject.toml index d86886b..b3b318b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,8 +29,9 @@ coverage = "^7.3.1" pytest-asyncio = "^0.21.1" pytest-cov = "^4.1.0" ruff = "^0.0.287" -greenlet = "^2.0.2" polyfactory = "^2.8.2" +gevent = "^23.9.1" +pre-commit = "^3.4.0" [tool.poetry.group.examples.dependencies] python-dotenv = "^1.0.0" @@ -63,7 +64,7 @@ directory = "pytest-cov-report" [tool.coverage.run] branch = true -concurrency = ['thread', 'greenlet'] +concurrency = ['gevent'] [tool.pytest.ini_options] asyncio_mode = "auto" @@ -83,4 +84,4 @@ max-complexity = 10 [tool.ruff.isort] known-local-folder = ["ya_tacker_client"] -lines-after-imports = 2 \ No newline at end of file +lines-after-imports = 2 diff --git a/ya_tracker_client/domain/client/base.py b/ya_tracker_client/domain/client/base.py index c8adffb..ac19adf 100644 --- a/ya_tracker_client/domain/client/base.py +++ b/ya_tracker_client/domain/client/base.py @@ -1,8 +1,11 @@ from abc import ABC, abstractmethod from http import HTTPStatus +from json import dumps from logging import getLogger from typing import Any +from aiohttp import BytesPayload + from ya_tracker_client.domain.client.errors import ( ClientAuthError, ClientError, @@ -55,11 +58,17 @@ async def request( payload: dict[str, Any] | None = None, ) -> bytes: uri = f"{self._base_url}/{self._api_version}{uri}" + + bytes_payload = BytesPayload( + value=bytes(dumps(payload), encoding="utf-8"), + content_type="application/json", + ) + status, body = await self._make_request( method=method, url=uri, params=params, - data=payload, + data=bytes_payload, ) self._check_status(status, body) return body @@ -70,7 +79,7 @@ async def _make_request( method: str, url: str, params: dict[str, Any] | None = None, - data: bytes | None = None, + data: bytes | BytesPayload | None = None, ) -> tuple[int, bytes]: """ Get raw response from via http-client. diff --git a/ya_tracker_client/domain/entities/issue.py b/ya_tracker_client/domain/entities/issue.py index 70cb26e..7f314be 100644 --- a/ya_tracker_client/domain/entities/issue.py +++ b/ya_tracker_client/domain/entities/issue.py @@ -3,11 +3,12 @@ from pydantic import AliasChoices, Field from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.issue_type import IssueType from ya_tracker_client.domain.entities.priority import Priority -from ya_tracker_client.domain.entities.queue import Queue +from ya_tracker_client.domain.entities.queue import QueueIdentifier, QueueShort from ya_tracker_client.domain.entities.sprint import Sprint from ya_tracker_client.domain.entities.status import Status -from ya_tracker_client.domain.entities.user import User +from ya_tracker_client.domain.entities.user import UserShort class IssueShort(AbstractEntity): @@ -17,13 +18,6 @@ class IssueShort(AbstractEntity): display: str -class IssueType(AbstractEntity): - url: str = Field(validation_alias=AliasChoices("self", "url")) - id: str - key: str - display: str - - class Issue(AbstractEntity): url: str = Field(validation_alias=AliasChoices("self", "url")) id: str @@ -36,19 +30,46 @@ class Issue(AbstractEntity): sprint: list[Sprint] | None = None type: IssueType priority: Priority - followers: list[User] | None = None - queue: Queue - previous_queue: Queue | None = None + followers: list[UserShort] | None = None + queue: QueueShort + previous_queue: QueueShort | None = None favorite: bool - assignee: User | None = None + assignee: UserShort | None = None last_comment_update_at: datetime | None = None aliases: list[str] | None = None - updated_by: User | None = None + updated_by: UserShort | None = None created_at: datetime = Field(validation_alias=AliasChoices("createdAt", "created_at")) - created_by: User = Field(validation_alias=AliasChoices("createdBy", "created_by")) + created_by: UserShort = Field(validation_alias=AliasChoices("createdBy", "created_by")) votes: int updated_at: datetime | None = None status: Status previous_status: Status | None = None direction: str | None = None + + +class IssueCreate(AbstractEntity): + summary: str + queue: QueueIdentifier | str | int + parent: IssueShort | str | None = None + description: str | None = None + sprint: list[Sprint | str] | None = None + type: IssueType | None = None + priority: Priority | None = None + followers: list[UserShort | str] | None = None + assignee: list[UserShort | str] | None = None + unique: str | None = None + attachment_ids: list[str] | None = Field( + default=None, + validation_alias=AliasChoices("attachmentIds", "attachment_ids"), + ) + + +class IssueEdit(AbstractEntity): + summary: str | None = None + parent: IssueShort | str | None = None + description: str | None = None + sprint: list[Sprint | str] | None = None + type: IssueType | None = None + priority: Priority | None = None + followers: list[UserShort | str] | None = None diff --git a/ya_tracker_client/domain/entities/issue_relationship.py b/ya_tracker_client/domain/entities/issue_relationship.py new file mode 100644 index 0000000..57c126c --- /dev/null +++ b/ya_tracker_client/domain/entities/issue_relationship.py @@ -0,0 +1,47 @@ +from datetime import datetime +from enum import Enum + +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.issue import IssueShort +from ya_tracker_client.domain.entities.issue_status import IssueStatus +from ya_tracker_client.domain.entities.user import UserShort + + +class IssueRelationshipTypeEnum(str, Enum): + RELATES = "relates" + IS_DEPENDENT_BY = "is dependent by" + DEPENDS_ON = "depends on" + IS_SUBTASK_FOR = "is subtask for" + IS_PARENT_TASK_FOR = "is parent task for" + DUPLICATES = "duplicates" + IS_DUPLICATED_BY = "is duplicated by" + IS_EPIC_OF = "is epic of" + HAS_EPIC = "has epic" + + +class IssueRelationshipType(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + inward: str + outward: str + + +class IssueRelationship(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: int + type: IssueRelationshipType + direction: str + object: IssueShort + created_at: datetime = Field(validation_alias=AliasChoices("createdAt", "created_at")) + updated_at: datetime = Field(validation_alias=AliasChoices("updatedAt", "updated_at")) + created_by: UserShort = Field(validation_alias=AliasChoices("createdBy", "created_by")) + updated_by: UserShort = Field(validation_alias=AliasChoices("updatedBy", "updated_by")) + assignee: UserShort | None = None + status: IssueStatus + + +class IssueRelationshipCreate(AbstractEntity): + issue: str + relationship: IssueRelationshipTypeEnum diff --git a/ya_tracker_client/domain/entities/issue_status.py b/ya_tracker_client/domain/entities/issue_status.py new file mode 100644 index 0000000..a11c981 --- /dev/null +++ b/ya_tracker_client/domain/entities/issue_status.py @@ -0,0 +1,10 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class IssueStatus(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + key: str + display: str diff --git a/ya_tracker_client/domain/entities/issue_type.py b/ya_tracker_client/domain/entities/issue_type.py new file mode 100644 index 0000000..9158600 --- /dev/null +++ b/ya_tracker_client/domain/entities/issue_type.py @@ -0,0 +1,10 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class IssueType(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + key: str + display: str diff --git a/ya_tracker_client/domain/entities/issue_type_config.py b/ya_tracker_client/domain/entities/issue_type_config.py new file mode 100644 index 0000000..e502371 --- /dev/null +++ b/ya_tracker_client/domain/entities/issue_type_config.py @@ -0,0 +1,12 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.issue_type import IssueType +from ya_tracker_client.domain.entities.resolution import ResolutionShort +from ya_tracker_client.domain.entities.workflow import WorkflowShort + + +class IssueTypeConfig(AbstractEntity): + issue_type: IssueType = Field(validation_alias=AliasChoices("issueType", "issue_type")) + workflow: WorkflowShort + resolutions: list[ResolutionShort] diff --git a/ya_tracker_client/domain/entities/priority.py b/ya_tracker_client/domain/entities/priority.py index 4bf9b15..41457b9 100644 --- a/ya_tracker_client/domain/entities/priority.py +++ b/ya_tracker_client/domain/entities/priority.py @@ -5,7 +5,7 @@ class Priority(AbstractEntity): url: str = Field(validation_alias=AliasChoices("self", "url")) - id: str + id: int key: str display: str | None = None version: int | None = None diff --git a/ya_tracker_client/domain/entities/queue.py b/ya_tracker_client/domain/entities/queue.py index 9436f42..2885193 100644 --- a/ya_tracker_client/domain/entities/queue.py +++ b/ya_tracker_client/domain/entities/queue.py @@ -1,10 +1,79 @@ from pydantic import AliasChoices, Field from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.issue_type import IssueType +from ya_tracker_client.domain.entities.issue_type_config import IssueTypeConfig +from ya_tracker_client.domain.entities.priority import Priority +from ya_tracker_client.domain.entities.user import UserShort +from ya_tracker_client.domain.entities.workflow import WorkflowShort -class Queue(AbstractEntity): +class QueueIdentifier(AbstractEntity): + id: str + key: str + + +class QueueShort(AbstractEntity): url: str = Field(validation_alias=AliasChoices("self", "url")) id: str key: str display: str + + +class QueueVersion(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + display: str + + +class Queue(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: int + key: str + version: int + name: str + description: str | None = None # TODO: string in documentation, but may be missing in response - TB145879 + lead: UserShort + assign_auto: bool = Field(validation_alias=AliasChoices("assignAuto", "assign_auto")) + default_type: IssueType = Field(validation_alias=AliasChoices("defaultType", "default_type")) + default_priority: Priority = Field(validation_alias=AliasChoices("defaultPriority", "default_priority")) + team_users: list[UserShort] = Field(default=list, validation_alias=AliasChoices("teamUsers", "team_users")) + issue_types: list[IssueType] = Field(default=list, validation_alias=AliasChoices("issueTypes", "issue_types")) + versions: list[QueueVersion] = Field(default=list) + workflows: list[WorkflowShort] = Field(default=list) + deny_voting: bool = Field(validation_alias=AliasChoices("denyVoting", "deny_voting")) + issue_types_config: list[IssueTypeConfig] = Field( + default=list, + validation_alias=AliasChoices("issueTypesConfig", "issue_types_config"), + ) + + # TODO: documentation does not contain this fields - TB145879 + deny_conductor_autolink: bool = Field( + validation_alias=AliasChoices("denyConductorAutolink", "deny_conductor_autolink"), + ) + deny_tracker_auto_link: bool = Field( + validation_alias=AliasChoices("denyTrackerAutolink", "deny_tracker_auto_link"), + ) + use_component_permissions_intersection: bool = Field( + validation_alias=AliasChoices("useComponentPermissionsIntersection", "use_component_permissions_intersection"), + ) + workflow_actions_style: str = Field( + validation_alias=AliasChoices("workflowActionsStyle", "workflow_actions_style"), + ) + use_last_signature: bool = Field( + validation_alias=AliasChoices("useLastSignature", "use_last_signature"), + ) + + +class QueueCreate(AbstractEntity): + key: str + name: str + lead: str + default_type: str + default_priority: str = Field( + validation_alias=AliasChoices("defaultPriority", "default_priority"), + ) + issue_types_config: list[IssueTypeConfig] = Field( + default=list, + validation_alias=AliasChoices("issueTypesConfig", "issue_types_config"), + ) diff --git a/ya_tracker_client/domain/entities/queue_field.py b/ya_tracker_client/domain/entities/queue_field.py new file mode 100644 index 0000000..c851924 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field.py @@ -0,0 +1,35 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.queue_field_category import QueueFieldCategory +from ya_tracker_client.domain.entities.queue_field_options_provider import QueueFieldOptionsProvider +from ya_tracker_client.domain.entities.queue_field_query_provider import QueueFieldQueryProvider +from ya_tracker_client.domain.entities.queue_field_schema import QueueFieldSchema +from ya_tracker_client.domain.entities.queue_field_suggest_provider import QueueFieldSuggestProvider + + +class QueueField(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + name: str + version: int + field_schema: QueueFieldSchema = Field( + validation_alias=AliasChoices("schema"), + ) + readonly: bool + options: bool + suggest: bool + options_provider: QueueFieldOptionsProvider | None = Field( # TODO: not required in response - not documented + default=None, validation_alias=AliasChoices("optionsProvider", "options_provider"), + ) + query_provider: QueueFieldQueryProvider | None = Field( + default=None, validation_alias=AliasChoices("queryProvider", "query_provider"), + ) + order: int + + # TODO: documentation does not contain this fields + suggest_provider: QueueFieldSuggestProvider | None = Field( + default=None, validation_alias=AliasChoices("suggestProvider", "suggest_provider"), + ) + type: str + category: QueueFieldCategory diff --git a/ya_tracker_client/domain/entities/queue_field_category.py b/ya_tracker_client/domain/entities/queue_field_category.py new file mode 100644 index 0000000..554f9a9 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field_category.py @@ -0,0 +1,9 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class QueueFieldCategory(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + display: str diff --git a/ya_tracker_client/domain/entities/queue_field_options_provider.py b/ya_tracker_client/domain/entities/queue_field_options_provider.py new file mode 100644 index 0000000..076e447 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field_options_provider.py @@ -0,0 +1,9 @@ +from pydantic import Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class QueueFieldOptionsProvider(AbstractEntity): + type: str + values: list = Field(default=list) + defaults: list = Field(default=list) diff --git a/ya_tracker_client/domain/entities/queue_field_query_provider.py b/ya_tracker_client/domain/entities/queue_field_query_provider.py new file mode 100644 index 0000000..0de0412 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field_query_provider.py @@ -0,0 +1,5 @@ +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class QueueFieldQueryProvider(AbstractEntity): + type: str diff --git a/ya_tracker_client/domain/entities/queue_field_schema.py b/ya_tracker_client/domain/entities/queue_field_schema.py new file mode 100644 index 0000000..f2d3e49 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field_schema.py @@ -0,0 +1,9 @@ +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class QueueFieldSchema(AbstractEntity): + type: str # TODO: "float" or "string" values - maybe better to replace with enum + required: bool | None = None # TODO: bool in documentation, but may be missing in response + + # TODO: documentation does not contain this fields + items: str | None = None diff --git a/ya_tracker_client/domain/entities/queue_field_suggest_provider.py b/ya_tracker_client/domain/entities/queue_field_suggest_provider.py new file mode 100644 index 0000000..644c77b --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_field_suggest_provider.py @@ -0,0 +1,5 @@ +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class QueueFieldSuggestProvider(AbstractEntity): + type: str diff --git a/ya_tracker_client/domain/entities/queue_version.py b/ya_tracker_client/domain/entities/queue_version.py new file mode 100644 index 0000000..b191003 --- /dev/null +++ b/ya_tracker_client/domain/entities/queue_version.py @@ -0,0 +1,19 @@ +from datetime import date + +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.queue import QueueShort + + +class QueueVersion(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: int + version: int + queue: QueueShort + name: str + description: str | None = None # TODO: string in documentation, but may be missing in response - TB145879 + start_date: date | None = Field(default=None, validation_alias=AliasChoices("startDate", "start_date")) + due_date: date | None = Field(default=None, validation_alias=AliasChoices("dueDate", "due_date")) + released: bool + archived: bool diff --git a/ya_tracker_client/domain/entities/resolution.py b/ya_tracker_client/domain/entities/resolution.py new file mode 100644 index 0000000..4855cac --- /dev/null +++ b/ya_tracker_client/domain/entities/resolution.py @@ -0,0 +1,10 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class ResolutionShort(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + key: str + display: str diff --git a/ya_tracker_client/domain/entities/transition.py b/ya_tracker_client/domain/entities/transition.py new file mode 100644 index 0000000..43b3519 --- /dev/null +++ b/ya_tracker_client/domain/entities/transition.py @@ -0,0 +1,11 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.issue_status import IssueStatus + + +class Transition(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + to: IssueStatus + display: str diff --git a/ya_tracker_client/domain/entities/user.py b/ya_tracker_client/domain/entities/user.py index 326ea36..8e1c1f7 100644 --- a/ya_tracker_client/domain/entities/user.py +++ b/ya_tracker_client/domain/entities/user.py @@ -1,9 +1,50 @@ +from datetime import datetime + from pydantic import AliasChoices, Field from ya_tracker_client.domain.entities.base import AbstractEntity -class User(AbstractEntity): +class UserShort(AbstractEntity): url: str = Field(validation_alias=AliasChoices("self", "url")) id: str display: str + + +class User(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + uid: int + login: str + tracker_uid: int = Field(validation_alias=AliasChoices("trackerUid", "tracker_uid")) + passport_uid: int = Field(validation_alias=AliasChoices("passportUid", "passport_uid")) + cloud_uid: str | None = Field( + default=None, + validation_alias=AliasChoices("cloudUid", "cloud_uid"), + ) + first_name: str = Field(validation_alias=AliasChoices("firstName", "first_name")) + last_name: str = Field(validation_alias=AliasChoices("lastName", "last_name")) + display: str + email: str + external: bool + has_licence: bool | None = Field( + default=None, + validation_alias=AliasChoices("hasLicence", "has_licence"), + ) + dismissed: bool + user_new_filters: bool | None = Field( + default=None, + validation_alias=AliasChoices("userNewFilters", "user_new_filters"), + ) + disable_notifications: bool = Field(validation_alias=AliasChoices("disableNotifications", "disable_notifications")) + first_login_date: datetime | None = Field( + default=None, + validation_alias=AliasChoices("firstLoginDate", "first_login_date"), + ) + last_login_date: datetime | None = Field( + default=None, + validation_alias=AliasChoices("lastLoginDate", "last_login_date"), + ) + welcome_mail_sent: bool | None = Field( + default=None, + validation_alias=AliasChoices("welcomeMailSent", "welcome_mail_sent"), + ) diff --git a/ya_tracker_client/domain/entities/workflow.py b/ya_tracker_client/domain/entities/workflow.py new file mode 100644 index 0000000..88ac0c9 --- /dev/null +++ b/ya_tracker_client/domain/entities/workflow.py @@ -0,0 +1,10 @@ +from pydantic import AliasChoices, Field + +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class WorkflowShort(AbstractEntity): + url: str = Field(validation_alias=AliasChoices("self", "url")) + id: str + key: str + display: str diff --git a/ya_tracker_client/domain/repositories/base.py b/ya_tracker_client/domain/repositories/base.py index bcc8d9f..2cce275 100644 --- a/ya_tracker_client/domain/repositories/base.py +++ b/ya_tracker_client/domain/repositories/base.py @@ -8,4 +8,3 @@ def __init__(self, client: BaseClient) -> None: async def stop(self) -> None: await self._client.stop() - diff --git a/ya_tracker_client/domain/repositories/issue.py b/ya_tracker_client/domain/repositories/issue.py index d124eaf..fc30095 100644 --- a/ya_tracker_client/domain/repositories/issue.py +++ b/ya_tracker_client/domain/repositories/issue.py @@ -1,6 +1,12 @@ from json import loads -from ya_tracker_client.domain.entities.issue import Issue +from ya_tracker_client.domain.entities.issue import Issue, IssueCreate, IssueEdit, IssueShort +from ya_tracker_client.domain.entities.issue_type import IssueType +from ya_tracker_client.domain.entities.priority import Priority +from ya_tracker_client.domain.entities.queue import QueueIdentifier +from ya_tracker_client.domain.entities.sprint import Sprint +from ya_tracker_client.domain.entities.transition import Transition +from ya_tracker_client.domain.entities.user import UserShort from ya_tracker_client.domain.repositories.base import EntityRepository @@ -8,12 +14,89 @@ class IssueRepository(EntityRepository): async def get_issue(self, issue_id: str) -> Issue: """ Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/get-issue - - :param issue_id: identifier of the issue. - :return: issue DTO. """ raw_response = await self._client.request( method="GET", uri=f"/issues/{issue_id}", ) return Issue(**loads(raw_response)) + + async def create_issue( + self, + summary: str, + queue: QueueIdentifier | str | int, + parent: IssueShort | str | None = None, + description: str | None = None, + sprint: list[Sprint | str] | None = None, + issue_type: IssueType | None = None, + priority: Priority | None = None, + followers: list[UserShort | str] | None = None, + assignee: list[UserShort | str] | None = None, + unique: str | None = None, + attachment_ids: list[str] | None = None, + ) -> Issue: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/create-issue#queue + """ + raw_response = await self._client.request( + method="POST", + uri="/issues/", + payload=IssueCreate( + summary=summary, + queue=queue, + parent=parent, + description=description, + sprint=sprint, + type=issue_type, + priority=priority, + followers=followers, + assignee=assignee, + unique=unique, + attachment_ids=attachment_ids, + ).model_dump(exclude_none=True, by_alias=True), + ) + return Issue(**loads(raw_response)) + + async def edit_issue( + self, + issue_id: str, + version: int | None = None, + **kwargs, + ) -> Issue: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/patch-issue + """ + raw_response = await self._client.request( + method="PATCH", + uri=f"/issues/{issue_id}", + params={"version": version} if version is not None else None, + payload=IssueEdit(**kwargs).model_dump(exclude_unset=True), + ) + return Issue(**loads(raw_response)) + + async def get_priorities( + self, + localized: bool = True, + ) -> list[Priority]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/get-priorities + """ + raw_response = await self._client.request( + method="GET", + uri="/priorities/", + params={"localized": str(localized)}, + ) + return [Priority(**raw_issue_priority) for raw_issue_priority in loads(raw_response)] + + async def get_issue_transitions( + self, + issue_id: str, + ) -> list[Transition]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/get-transitions + """ + raw_response = await self._client.request( + method="GET", + uri=f"/issues/{issue_id}/transitions/", + ) + return [Transition(**raw_issue_transition) for raw_issue_transition in loads(raw_response)] diff --git a/ya_tracker_client/domain/repositories/issue_relationship.py b/ya_tracker_client/domain/repositories/issue_relationship.py new file mode 100644 index 0000000..3459822 --- /dev/null +++ b/ya_tracker_client/domain/repositories/issue_relationship.py @@ -0,0 +1,55 @@ +from json import loads + +from ya_tracker_client.domain.entities.issue_relationship import ( + IssueRelationship, + IssueRelationshipCreate, + IssueRelationshipTypeEnum, +) +from ya_tracker_client.domain.repositories.base import EntityRepository + + +class IssueRelationshipRepository(EntityRepository): + async def create_issue_relationship( + self, + issue_from: str, + issue_to: str, + relationship: IssueRelationshipTypeEnum, + ) -> IssueRelationship: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/link-issue + """ + raw_response = await self._client.request( + method="POST", + uri=f"/issues/{issue_from}/links", + payload=IssueRelationshipCreate( + issue=issue_to, + relationship=relationship, + ).model_dump(exclude_none=True, by_alias=True), + ) + return IssueRelationship(**loads(raw_response)) + + async def get_issue_relationships( + self, + issue_id: str, + ) -> list[IssueRelationship]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/get-links + """ + raw_response = await self._client.request( + method="GET", + uri=f"/issues/{issue_id}/links", + ) + return [IssueRelationship(**raw_issue_relationship) for raw_issue_relationship in loads(raw_response)] + + async def delete_issue_relationships( + self, + issue_id: str, + link_id: int, + ) -> None: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/delete-link-issue + """ + await self._client.request( + method="DELETE", + uri=f"/issues/{issue_id}/links/{link_id}", + ) diff --git a/ya_tracker_client/domain/repositories/queue.py b/ya_tracker_client/domain/repositories/queue.py new file mode 100644 index 0000000..d00efd9 --- /dev/null +++ b/ya_tracker_client/domain/repositories/queue.py @@ -0,0 +1,109 @@ +from json import loads + +from ya_tracker_client.domain.entities.issue_type_config import IssueTypeConfig +from ya_tracker_client.domain.entities.queue import Queue, QueueCreate +from ya_tracker_client.domain.entities.queue_field import QueueField +from ya_tracker_client.domain.entities.queue_version import QueueVersion +from ya_tracker_client.domain.repositories.base import EntityRepository + + +class QueueRepository(EntityRepository): + async def create_queue( + self, + key: str, + name: str, + lead: str, + default_type: str, + default_priority: str, + issue_types_config: list[IssueTypeConfig], + ) -> Queue: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/create-queue + """ + raw_response = await self._client.request( + method="POST", + uri="/queues/", + payload=QueueCreate( + key=key, + name=name, + lead=lead, + default_type=default_type, + default_priority=default_priority, + issue_types_config=issue_types_config, + ).model_dump(exclude_none=True, by_alias=True), + ) + return Queue(**loads(raw_response)) + + async def get_queue(self, queue_id: str | int) -> Queue: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/get-queue + """ + raw_response = await self._client.request( + method="GET", + uri=f"/queues/{queue_id}", + ) + return Queue(**loads(raw_response)) + + async def get_queues(self) -> list[Queue]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/get-queues + """ + raw_response = await self._client.request( + method="GET", + uri="/queues/", + ) + return [Queue(**raw_queue) for raw_queue in loads(raw_response)] + + async def get_queue_versions(self, queue_id: str | int) -> list[QueueVersion]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/get-versions + """ + raw_response = await self._client.request( + method="GET", + uri=f"/queues/{queue_id}/versions", + ) + return [QueueVersion(**raw_queue_version) for raw_queue_version in loads(raw_response)] + + async def get_queue_fields(self, queue_id: str | int) -> list[QueueField]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/get-fields + """ + raw_response = await self._client.request( + method="GET", + uri=f"/queues/{queue_id}/fields", + ) + for raw_queue_field in loads(raw_response): + print(*raw_queue_field.items(), sep="\n") + print() + QueueField(**raw_queue_field) + + return [QueueField(**raw_queue_field) for raw_queue_field in loads(raw_response)] + + async def delete_queue(self, queue_id: str | int) -> None: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/delete-queue + """ + await self._client.request( + method="DELETE", + uri=f"/queues/{queue_id}", + ) + + async def restore_queue(self, queue_id: str | int) -> Queue: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/restore-queue + """ + raw_response = await self._client.request( + method="POST", + uri=f"/queues/{queue_id}/_restore", + ) + return Queue(**loads(raw_response)) + + async def delete_tag_in_queue(self, queue_id: str | int, tag_name: str) -> None: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/queues/delete-tag + """ + await self._client.request( + method="DELETE", + uri=f"/queues/{queue_id}/tags/_remove", + payload={"tag": tag_name}, + ) diff --git a/ya_tracker_client/domain/repositories/user.py b/ya_tracker_client/domain/repositories/user.py new file mode 100644 index 0000000..93add34 --- /dev/null +++ b/ya_tracker_client/domain/repositories/user.py @@ -0,0 +1,52 @@ +from json import loads +from logging import getLogger + +from ya_tracker_client.domain.client.errors import ClientError +from ya_tracker_client.domain.entities.user import User +from ya_tracker_client.domain.repositories.base import EntityRepository + + +logger = getLogger(__name__) + + +class UserRepository(EntityRepository): + async def get_myself(self) -> User: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/get-user-info + """ + raw_response = await self._client.request( + method="GET", + uri="/myself/", + ) + return User(**loads(raw_response)) + + async def get_user( + self, + login: str | None = None, + uid: int | None = None, + ) -> User: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/get-user + """ + if (login is None) and (uid is None): + raise ClientError("Please provide login or uid for this request") + elif (login is not None) and (uid is not None): + logger.warning( + "Login will be used for this request. Please provide only login or only uid for this request, not both", + ) + + raw_response = await self._client.request( + method="GET", + uri=f"/users/{login or uid}", + ) + return User(**loads(raw_response)) + + async def get_users(self) -> list[User]: + """ + Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/get-users + """ + raw_response = await self._client.request( + method="GET", + uri="/users/", + ) + return [User(**raw_user) for raw_user in loads(raw_response)] diff --git a/ya_tracker_client/infrastructure/client.py b/ya_tracker_client/infrastructure/client.py index 1f47ba0..3233028 100644 --- a/ya_tracker_client/infrastructure/client.py +++ b/ya_tracker_client/infrastructure/client.py @@ -2,7 +2,7 @@ from ssl import create_default_context from typing import Any -from aiohttp import ClientSession, ClientTimeout, TCPConnector +from aiohttp import BytesPayload, ClientSession, ClientTimeout, TCPConnector from certifi import where from ya_tracker_client.domain.client import BaseClient @@ -51,7 +51,7 @@ async def _make_request( method: str, url: str, params: dict[str, Any] | None = None, - data: bytes | None = None, + data: bytes | BytesPayload | None = None, ) -> tuple[int, bytes]: session = self._get_session() async with session.request(method, url, params=params, data=data) as response: diff --git a/ya_tracker_client/service/api.py b/ya_tracker_client/service/api.py index b03028d..0a7c21c 100644 --- a/ya_tracker_client/service/api.py +++ b/ya_tracker_client/service/api.py @@ -1,8 +1,16 @@ from ya_tracker_client.domain.repositories.issue import IssueRepository +from ya_tracker_client.domain.repositories.issue_relationship import IssueRelationshipRepository +from ya_tracker_client.domain.repositories.queue import QueueRepository +from ya_tracker_client.domain.repositories.user import UserRepository from ya_tracker_client.infrastructure.client import AiohttpClient -class YaTrackerClient(IssueRepository): +class YaTrackerClient( + IssueRelationshipRepository, + IssueRepository, + QueueRepository, + UserRepository, +): def __init__( self, organisation_id: str | int,