sgnl-api 0.2.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/.gitignore +164 -164
  2. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/LICENSE +9 -9
  3. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/PKG-INFO +122 -9
  4. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/README.md +333 -220
  5. sgnl_api-0.4.0/mcp/README.md +158 -0
  6. sgnl_api-0.4.0/mcp/pyproject.toml +47 -0
  7. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/pyproject.toml +51 -38
  8. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/__init__.py +25 -23
  9. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/decorators.py +9 -9
  10. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/docs_api.py +203 -152
  11. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/exceptions.py +50 -38
  12. sgnl_api-0.4.0/sgnl_api/file.py +35 -0
  13. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/__init__.py +111 -81
  14. sgnl_api-0.4.0/sgnl_api/resources/acceptance_certificate.py +49 -0
  15. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/application_user.py +31 -31
  16. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/attribute.py +14 -14
  17. sgnl_api-0.4.0/sgnl_api/resources/attribute_type.py +60 -0
  18. sgnl_api-0.4.0/sgnl_api/resources/attribute_type_list_items.py +33 -0
  19. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/attribute_value.py +38 -38
  20. sgnl_api-0.4.0/sgnl_api/resources/board.py +16 -0
  21. sgnl_api-0.4.0/sgnl_api/resources/booking.py +35 -0
  22. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/cades_signature.py +29 -29
  23. sgnl_api-0.4.0/sgnl_api/resources/card.py +27 -0
  24. sgnl_api-0.4.0/sgnl_api/resources/card_group.py +19 -0
  25. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/card_public_link.py +17 -17
  26. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/company.py +38 -38
  27. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/company_user.py +29 -29
  28. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/company_user_custom_role.py +20 -20
  29. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/documents_transfer.py +68 -45
  30. sgnl_api-0.4.0/sgnl_api/resources/documents_transfer_acceptance.py +34 -0
  31. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/documents_transfer_item.py +49 -37
  32. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/documents_transfer_type.py +14 -14
  33. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/embedded_signature.py +31 -31
  34. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/file.py +84 -75
  35. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/folder.py +99 -99
  36. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/folder_items_naming_pattern.py +17 -17
  37. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/forge.py +29 -29
  38. sgnl_api-0.4.0/sgnl_api/resources/form_field_type.py +14 -0
  39. sgnl_api-0.4.0/sgnl_api/resources/form_type.py +14 -0
  40. sgnl_api-0.4.0/sgnl_api/resources/form_type_group.py +14 -0
  41. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue.py +101 -55
  42. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_accesses.py +14 -14
  43. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_attachment.py +26 -26
  44. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_comment.py +37 -37
  45. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_events.py +25 -25
  46. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_project_settings.py +17 -17
  47. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/issue_type.py +14 -14
  48. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/item.py +251 -207
  49. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/mchd.py +33 -33
  50. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/permissions.py +35 -28
  51. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/project.py +167 -134
  52. sgnl_api-0.4.0/sgnl_api/resources/project_form.py +133 -0
  53. sgnl_api-0.4.0/sgnl_api/resources/project_form_field_type.py +20 -0
  54. sgnl_api-0.4.0/sgnl_api/resources/project_form_type.py +20 -0
  55. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/project_user.py +26 -26
  56. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/project_user_custom_role.py +20 -20
  57. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/review.py +123 -68
  58. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/review_group.py +16 -16
  59. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/review_item.py +38 -20
  60. sgnl_api-0.4.0/sgnl_api/resources/review_process.py +33 -0
  61. sgnl_api-0.4.0/sgnl_api/resources/review_type.py +17 -0
  62. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/share.py +65 -65
  63. sgnl_api-0.4.0/sgnl_api/resources/slot.py +33 -0
  64. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/storage.py +16 -16
  65. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/tangl.py +19 -19
  66. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/user_log.py +14 -14
  67. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/resources/version.py +91 -90
  68. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/scopes.py +18 -18
  69. sgnl_api-0.4.0/sgnl_api/transport.py +218 -0
  70. {sgnl_api-0.2.0 → sgnl_api-0.4.0}/sgnl_api/utils.py +50 -45
  71. sgnl_api-0.2.0/example.py +0 -26
  72. sgnl_api-0.2.0/img/logo.svg +0 -4
  73. sgnl_api-0.2.0/sgnl_api/file.py +0 -18
  74. sgnl_api-0.2.0/sgnl_api/resources/acceptance_certificate.py +0 -18
  75. sgnl_api-0.2.0/sgnl_api/resources/attribute_type.py +0 -14
  76. sgnl_api-0.2.0/sgnl_api/transport.py +0 -129
  77. sgnl_api-0.2.0/uv.lock +0 -175
@@ -1,164 +1,164 @@
1
- # Byte-compiled / optimized / DLL files
2
- __pycache__/
3
- *.py[cod]
4
- *$py.class
5
- .pypirc
6
-
7
- # C extensions
8
- *.so
9
-
10
- # Distribution / packaging
11
- .Python
12
- build/
13
- develop-eggs/
14
- dist/
15
- downloads/
16
- eggs/
17
- .eggs/
18
- lib/
19
- lib64/
20
- parts/
21
- sdist/
22
- var/
23
- wheels/
24
- share/python-wheels/
25
- *.egg-info/
26
- .installed.cfg
27
- *.egg
28
- MANIFEST
29
- *.xlsx
30
-
31
- # PyInstaller
32
- # Usually these files are written by a python script from a template
33
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
- *.manifest
35
- *.spec
36
-
37
- # Installer logs
38
- pip-log.txt
39
- pip-delete-this-directory.txt
40
-
41
- # Unit test / coverage reports
42
- htmlcov/
43
- .tox/
44
- .nox/
45
- .coverage
46
- .coverage.*
47
- .cache
48
- nosetests.xml
49
- coverage.xml
50
- *.cover
51
- *.py,cover
52
- .hypothesis/
53
- .pytest_cache/
54
- cover/
55
- test.py
56
-
57
- # Translations
58
- *.mo
59
- *.pot
60
-
61
- # Django stuff:
62
- *.log
63
- local_settings.py
64
- db.sqlite3
65
- db.sqlite3-journal
66
-
67
- # Flask stuff:
68
- instance/
69
- .webassets-cache
70
-
71
- # Scrapy stuff:
72
- .scrapy
73
-
74
- # Sphinx documentation
75
- docs/_build/
76
-
77
- # PyBuilder
78
- .pybuilder/
79
- target/
80
-
81
- # Jupyter Notebook
82
- .ipynb_checkpoints
83
-
84
- # IPython
85
- profile_default/
86
- ipython_config.py
87
-
88
- # pyenv
89
- # For a library or package, you might want to ignore these files since the code is
90
- # intended to run in multiple environments; otherwise, check them in:
91
- # .python-version
92
-
93
- # pipenv
94
- # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95
- # However, in case of collaboration, if having platform-specific dependencies or dependencies
96
- # having no cross-platform support, pipenv may install dependencies that don't work, or not
97
- # install all needed dependencies.
98
- #Pipfile.lock
99
-
100
- # poetry
101
- # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
102
- # This is especially recommended for binary packages to ensure reproducibility, and is more
103
- # commonly ignored for libraries.
104
- # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
105
- #poetry.lock
106
-
107
- # pdm
108
- # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
109
- #pdm.lock
110
- # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
111
- # in version control.
112
- # https://pdm.fming.dev/#use-with-ide
113
- .pdm.toml
114
-
115
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
116
- __pypackages__/
117
-
118
- # Celery stuff
119
- celerybeat-schedule
120
- celerybeat.pid
121
-
122
- # SageMath parsed files
123
- *.sage.py
124
-
125
- # Environments
126
- .env
127
- .venv
128
- env/
129
- venv/
130
- ENV/
131
- env.bak/
132
- venv.bak/
133
-
134
- # Spyder project settings
135
- .spyderproject
136
- .spyproject
137
-
138
- # Rope project settings
139
- .ropeproject
140
-
141
- # mkdocs documentation
142
- /site
143
-
144
- # mypy
145
- .mypy_cache/
146
- .dmypy.json
147
- dmypy.json
148
-
149
- # Pyre type checker
150
- .pyre/
151
-
152
- # pytype static type analyzer
153
- .pytype/
154
-
155
- # Cython debug symbols
156
- cython_debug/
157
-
158
- # PyCharm
159
- # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
160
- # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
161
- # and can be added to the global gitignore or merged into this file. For a more nuclear
162
- # option (not recommended) you can uncomment the following to ignore the entire idea folder.
163
- .idea/
164
- .vscode/
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .pypirc
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+ *.xlsx
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+ test.py
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+ db.sqlite3
65
+ db.sqlite3-journal
66
+
67
+ # Flask stuff:
68
+ instance/
69
+ .webassets-cache
70
+
71
+ # Scrapy stuff:
72
+ .scrapy
73
+
74
+ # Sphinx documentation
75
+ docs/_build/
76
+
77
+ # PyBuilder
78
+ .pybuilder/
79
+ target/
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+
84
+ # IPython
85
+ profile_default/
86
+ ipython_config.py
87
+
88
+ # pyenv
89
+ # For a library or package, you might want to ignore these files since the code is
90
+ # intended to run in multiple environments; otherwise, check them in:
91
+ # .python-version
92
+
93
+ # pipenv
94
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
96
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
97
+ # install all needed dependencies.
98
+ #Pipfile.lock
99
+
100
+ # poetry
101
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
102
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
103
+ # commonly ignored for libraries.
104
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
105
+ #poetry.lock
106
+
107
+ # pdm
108
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
109
+ #pdm.lock
110
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
111
+ # in version control.
112
+ # https://pdm.fming.dev/#use-with-ide
113
+ .pdm.toml
114
+
115
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
116
+ __pypackages__/
117
+
118
+ # Celery stuff
119
+ celerybeat-schedule
120
+ celerybeat.pid
121
+
122
+ # SageMath parsed files
123
+ *.sage.py
124
+
125
+ # Environments
126
+ .env
127
+ .venv
128
+ env/
129
+ venv/
130
+ ENV/
131
+ env.bak/
132
+ venv.bak/
133
+
134
+ # Spyder project settings
135
+ .spyderproject
136
+ .spyproject
137
+
138
+ # Rope project settings
139
+ .ropeproject
140
+
141
+ # mkdocs documentation
142
+ /site
143
+
144
+ # mypy
145
+ .mypy_cache/
146
+ .dmypy.json
147
+ dmypy.json
148
+
149
+ # Pyre type checker
150
+ .pyre/
151
+
152
+ # pytype static type analyzer
153
+ .pytype/
154
+
155
+ # Cython debug symbols
156
+ cython_debug/
157
+
158
+ # PyCharm
159
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
160
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
161
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
162
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
163
+ .idea/
164
+ .vscode/
@@ -1,10 +1,10 @@
1
- MIT License
2
-
3
- Copyright (c) [2024] [Igor Gritsyuk]
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6
- copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
-
8
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
-
1
+ MIT License
2
+
3
+ Copyright (c) [2024] [Igor Gritsyuk]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
10
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: sgnl-api
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Asynchronous python wrapper over API sgnl.pro
5
5
  Project-URL: GitHub, https://github.com/gritsyuk/sgnl-api
6
6
  Author-email: Igor Gritsyuk <gritsyuk.igor@gmail.com>
@@ -18,8 +18,20 @@ Description-Content-Type: text/markdown
18
18
  # <img src="./img/logo.svg"> SIGNAL API
19
19
 
20
20
  ![PyPI - Version](https://img.shields.io/pypi/v/sgnl-api) [![Telegram chat](https://img.shields.io/badge/Просто_о_BIM-join-blue?logo=telegram)](https://t.me/prostobim)
21
- ## Обертка над API Signal
22
- Официальная документация [https://api.sgnl.pro/openapi/swagger/index.html](https://api.sgnl.pro/openapi/swagger/index.html)
21
+
22
+ Официальная документация API: [swagger](https://api.sgnl.pro/openapi/swagger/index.html), [OpenAPI-схема](https://api.sgnl.pro/openapi/v1/schema.yml).
23
+
24
+ ## Два пакета в одном репозитории
25
+
26
+ | Пакет | Что это | Установка | Каталог |
27
+ |---|---|---|---|
28
+ | `sgnl-api` | Асинхронная Python-обёртка над всем SIGNAL Integration API | `pip install -U sgnl-api` | `sgnl_api/` |
29
+ | `sgnl-mcp` | MCP-сервер: даёт LLM-агенту контролируемый доступ к SIGNAL — чтение без ограничений, запись только с подтверждением, удаление недоступно | `uvx sgnl-mcp` | [`mcp/`](mcp/README.md) |
30
+
31
+ `sgnl-mcp` построен поверх `sgnl-api` и зависит от него; `sgnl-api` ничего не знает про MCP и не тянет его зависимости. Пакеты выпускаются на PyPI независимо. Настройка MCP-сервера и подключение к Claude — в [mcp/README.md](mcp/README.md).
32
+
33
+ # sgnl-api — обёртка над API
34
+
23
35
  ## Установка
24
36
  ```bash
25
37
  pip install -U sgnl-api
@@ -68,7 +80,52 @@ except SgnlApiError as e:
68
80
  print(e.status_code, e.message)
69
81
  ```
70
82
 
71
- Иерархия исключений: `SgnlApiError` (базовое) → `SgnlRequestError` (сетевые ошибки/таймауты), `SgnlAuthenticationError` (401), `SgnlBadRequestError` (400), `SgnlForbiddenError` (403), `SgnlNotFoundError` (404), `SgnlQuotaExceededError` (450), `SgnlServerError` (5xx).
83
+ Иерархия исключений: `SgnlApiError` (базовое) → `SgnlRequestError` (сетевые ошибки/таймауты), `SgnlAuthenticationError` (401), `SgnlBadRequestError` (400), `SgnlForbiddenError` (403), `SgnlNotFoundError` (404), `SgnlQuotaExceededError` (450), `SgnlRateLimitError` (429), `SgnlServerError` (5xx).
84
+
85
+ ## Лимиты запросов (429)
86
+ API ограничивает частоту запросов (около 10 запросов в секунду на `client_id`, 50 с пополнением 4 в секунду на компанию). При ответе 429 клиент сам ждёт интервал из заголовка `Retry-After` (не больше 30 с за раз) и повторяет запрос — по умолчанию до 3 раз. Если лимит не отпустил, бросается `SgnlRateLimitError` с полем `retry_after`.
87
+
88
+ ```python
89
+ api = await DocsApi.create(client_id=..., client_secret=..., max_retries=5) # 0 — отключить повторы
90
+ ```
91
+
92
+ Если токен отозван раньше срока, на ответ 401 клиент один раз получает новый токен и повторяет запрос.
93
+
94
+ ## Загрузка файла
95
+ Документ из локального файла создаётся в три шага. Файл передаётся в хранилище потоком, поэтому большие файлы (API допускает до 5 ГиБ) не загружаются в память целиком.
96
+
97
+ ```python
98
+ uploaded = await docs.file.upload(project_id, "drawings/A-101.pdf") # {"object_id", "mime_type", "size"}
99
+ version_id = await docs.version.create(object_id=uploaded["object_id"], project_id=project_id, name="A-101.pdf")
100
+ item_id = await docs.item.create_file("A-101.pdf", folder_id, version_id) # новый документ
101
+ # или новая версия существующего документа:
102
+ await docs.item.add_version(item_id, version_id)
103
+ ```
104
+
105
+ ## Свой HTTP-клиент
106
+ В `DocsApi.create` можно передать свой `httpx.AsyncClient` — например, с транспортом, который фильтрует или ограничивает запросы (так устроен `sgnl-mcp`). Такой клиент `aclose()` не закрывает: его закрывает владелец.
107
+
108
+ ```python
109
+ async with httpx.AsyncClient(transport=my_transport, timeout=30) as http:
110
+ docs = await DocsApi.create(client_id=..., client_secret=..., http_client=http)
111
+ ```
112
+
113
+ ## Проверка покрытия API
114
+ Скрипт сравнивает [спецификацию](https://api.sgnl.pro/openapi/v1/schema.yml) с методами обёртки и показывает новые, удалённые и изменённые эндпоинты:
115
+ ```bash
116
+ uv run scripts/check_api_coverage.py # скачать спецификацию с api.sgnl.pro
117
+ uv run scripts/check_api_coverage.py openapi/schema.yml # или сохранённую копию из репозитория
118
+ ```
119
+ Код возврата 1 означает, что обёртка вызывает эндпоинт, которого больше нет, или не передаёт обязательное поле. Копия спецификации в `openapi/schema.yml` используется и тестами `sgnl-mcp`: при обновлении API её нужно заменить.
120
+
121
+ ## Разработка
122
+ Репозиторий — uv workspace из двух пакетов (`sgnl-api` в корне и `sgnl-mcp` в `mcp/`):
123
+ ```bash
124
+ uv sync --all-packages # оба пакета и dev-зависимости
125
+ uv run pytest # тесты SDK
126
+ uv run --package sgnl-mcp pytest mcp/tests # тесты MCP-сервера
127
+ uv build --all-packages # sdist и wheel обоих пакетов в dist/
128
+ ```
72
129
 
73
130
  ## Методы
74
131
  Обертка покрывает весь официальный API ([swagger](https://api.sgnl.pro/openapi/swagger/index.html)). Методы сгруппированы по ресурсам ровно как в спецификации (по тегам).
@@ -80,13 +137,14 @@ except SgnlApiError as e:
80
137
  | `item.count` | Количество файлов в директории | `int` |
81
138
  | `item.search` | Поиск вложенных элементов в директории | `list[dict]` |
82
139
  | `item.create_file` | Создает новый файл с версией | `UUID` |
83
- | `item.create_link` | Создает новую ссылку | `UUID` |
140
+ | `item.create_link` | Создает элемент-ссылку на URL | `UUID` |
84
141
  | `item.get_link` | Получает ссылку для загрузки файла | `dict` |
85
142
  | `item.get_item_version` | Возвращает версию элемента по UUID | `dict` |
86
143
  | `item.add_version` | Добавляет новую версию к существующему файлу | `None` |
87
144
  | `item.update` | Обновляет элемент (имя/ссылку) | `None` |
88
145
  | `item.update_version` | Обновляет комментарий версии элемента | `None` |
89
146
  | `item.delete` | Перемещает элемент в корзину | `None` |
147
+ | `item.move` | Перемещает элемент в другую папку | `None` |
90
148
 
91
149
  ### folder
92
150
  | Метод | Описание | Возвращает |
@@ -109,6 +167,7 @@ except SgnlApiError as e:
109
167
  | `project.users` | Список пользователей проекта | `list[dict]` |
110
168
  | `project.roles` | Список ролей проекта | `list[dict]` |
111
169
  | `project.users_permissions` | Права пользователя в проекте | `list[str]` |
170
+ | `project.update` | Обновляет основную информацию проекта | `None` |
112
171
  | `project_user.add` | Добавляет пользователей в проекты | `None` |
113
172
  | `project_user.delete` | Удаляет пользователей из проектов | `None` |
114
173
  | `project_user_custom_role.set` | Назначает кастомные роли пользователю в проекте | `None` |
@@ -136,13 +195,17 @@ except SgnlApiError as e:
136
195
  |-------------------------|-------------------------------------------------------------------|--------------------|
137
196
  | `file.get_object_upload`| Получает тикет на загрузку объекта | `dict` |
138
197
  | `file.commit_uploading` | Завершает загрузку объекта | `None` |
139
- | `file.upload` | Загружает файл целиком (upload + commit) | `dict` или `None` |
198
+ | `file.upload` | Загружает файл потоком (тикет, передача в хранилище, commit) | `dict` (`object_id`, `mime_type`, `size`) |
140
199
 
141
200
  ### attribute / attribute_type / attribute_value
142
201
  | Метод | Описание | Возвращает |
143
202
  |-----------------------------------|--------------------------------------------------------|--------------|
144
203
  | `attribute.get_list` | Список атрибутов по фильтру | `list[dict]` |
145
204
  | `attribute_type.get_list` | Список типов атрибутов по фильтру | `list[dict]` |
205
+ | `attribute_type.create` | Создает тип атрибута | `UUID` |
206
+ | `attribute_type.update` | Обновляет типы атрибутов (до 50) | `None` |
207
+ | `attribute_type_list_items.create` | Добавляет значения в атрибут-список | `None` |
208
+ | `attribute_type_list_items.update` | Обновляет значения атрибута-списка | `None` |
146
209
  | `attribute_value.list_issues` | Значения атрибутов замечаний | `list[dict]` |
147
210
  | `attribute_value.list_items` | Значения атрибутов элементов | `list[dict]` |
148
211
  | `attribute_value.list_folders` | Значения атрибутов папок | `list[dict]` |
@@ -152,6 +215,7 @@ except SgnlApiError as e:
152
215
  | Метод | Описание | Возвращает |
153
216
  |--------------------------------------------|------------------------------------------------------|--------------|
154
217
  | `issue.get_list` | Список замечаний по фильтру | `list[dict]` |
218
+ | `issue.create` | Создает замечание | `UUID` |
155
219
  | `issue.update` | Пакетное обновление замечаний (до 25 шт.) | `None` |
156
220
  | `issue.count` | Количество замечаний по фильтру | `int` |
157
221
  | `issue.item_issues_count` | Количество замечаний по элементам | `list[dict]` |
@@ -166,7 +230,7 @@ except SgnlApiError as e:
166
230
  | `issue_events.count` | Количество событий | `int` |
167
231
  | `issue_project_settings.get` | Настройки замечаний проекта | `dict` |
168
232
 
169
- ### review и связанные (review_group, review_item)
233
+ ### review и связанные (review_group, review_item, review_type, review_process)
170
234
  | Метод | Описание | Возвращает |
171
235
  |------------------------------------------------------------|--------------------------------------------------|--------------|
172
236
  | `review.get_list` | Список согласований проекта | `list[dict]` |
@@ -174,8 +238,15 @@ except SgnlApiError as e:
174
238
  | `review.count` | Количество согласований | `int` |
175
239
  | `review.get_versions` | Версии согласований по id | `list[dict]` |
176
240
  | `review.find_item_version_ids_by_review_version_ids` | Версии элементов по версиям согласования | `dict` |
241
+ | `review.create` | Создает согласование | `UUID` |
242
+ | `review.set_comment` | Устанавливает/очищает комментарий последней версии | `None` |
243
+ | `review.set_type` | Меняет тип согласования | `None` |
244
+ | `review_type.get_names` | Названия типов согласования проекта | `list[dict]` |
245
+ | `review_process.start` | Запускает процесс согласования | `None` |
177
246
  | `review_group.get_list` | Список групп согласований | `list[dict]` |
178
247
  | `review_item.get_statuses` | Статусы согласования для версий элементов | `list[dict]` |
248
+ | `review_item.add` | Добавляет версию элемента в согласование | `None` |
249
+ | `review_item.remove` | Удаляет версию элемента из согласования | `None` |
179
250
 
180
251
  ### share / storage
181
252
  | Метод | Описание | Возвращает |
@@ -199,24 +270,29 @@ except SgnlApiError as e:
199
270
  | `mchd.download` | Тикет на загрузку доверенности | `dict` |
200
271
  | `card_public_link.regenerate` | Перегенерирует публичную ссылку карточки дашборда | `dict` |
201
272
 
202
- ### documents_transfer / documents_transfer_item / documents_transfer_type / acceptance_certificate
273
+ ### documents_transfer / documents_transfer_item / documents_transfer_type / documents_transfer_acceptance / acceptance_certificate
203
274
  | Метод | Описание | Возвращает |
204
275
  |---------------------------------------------------|-----------------------------------------------------|--------------|
205
276
  | `documents_transfer.get_list` | Список передач документов по фильтру | `list[dict]` |
206
277
  | `documents_transfer.get` | Данные передачи документов по id | `dict` |
207
278
  | `documents_transfer.count` | Количество передач по фильтру | `int` |
208
279
  | `documents_transfer.accesses` | Правила доступа для типов передач | `list[dict]` |
280
+ | `documents_transfer.create` | Создает передачу документов | `UUID` |
209
281
  | `documents_transfer_item.get_list` | Список элементов передачи | `list[dict]` |
210
282
  | `documents_transfer_item.count` | Количество элементов передачи | `int` |
211
283
  | `documents_transfer_item.download` | Тикет на загрузку элемента передачи | `dict` |
284
+ | `documents_transfer_item.add` | Добавляет версии элементов в передачу | `None` |
212
285
  | `documents_transfer_type.get_list` | Список типов передач документов | `list[dict]` |
213
286
  | `acceptance_certificate.download` | Тикет на загрузку акта приема-передачи | `dict` |
287
+ | `acceptance_certificate.attach` | Прикрепляет акт приема-передачи к передаче | `UUID` |
288
+ | `documents_transfer_acceptance.send` | Отправляет подготовленную передачу получателю | `None` |
214
289
 
215
290
  ### permissions / application_user
216
291
  | Метод | Описание | Возвращает |
217
292
  |----------------------------------|------------------------------------------------------|--------------|
218
293
  | `permissions.upsert_batch` | Устанавливает права пользователей/ролей на папку | `None` |
219
294
  | `permissions.get_tree` | Дерево папок проекта с правами | `dict` |
295
+ | `permissions.delete` | Удаляет конкретное право | `None` |
220
296
  | `application_user.upsert` | Назначает роли пользователям в приложениях | `None` |
221
297
  | `application_user.delete` | Отзывает доступ пользователей в приложениях | `None` |
222
298
 
@@ -228,6 +304,43 @@ except SgnlApiError as e:
228
304
  | `tangl.convert` | Запускает конвертацию модели через Tangl | `None` |
229
305
  | `folder_items_naming_pattern.find` | Шаблоны именования файлов папки | `dict` |
230
306
 
307
+ ### формы (project_form, project_form_type, project_form_field_type, form_type, form_type_group, form_field_type)
308
+ | Метод | Описание | Возвращает |
309
+ |---|---|---|
310
+ | `project_form.get_list` | Список форм проекта (фильтр + сортировка) | `dict` |
311
+ | `project_form.count` | Количество форм по фильтру | `int` |
312
+ | `project_form.get` | Форма по id | `dict` |
313
+ | `project_form.get_summary` | Сводка по формам | `list[dict]` |
314
+ | `project_form.create_batch` | Создает формы пачкой (до 200) | `list[UUID]` |
315
+ | `project_form.update` | Обновляет поля формы | `None` |
316
+ | `project_form.complete` | Завершает форму | `None` |
317
+ | `project_form.find_form_source` | Формы-источники для поля | `dict` |
318
+ | `project_form.get_values_for_template_item` | Значения для шаблона | `dict` |
319
+ | `project_form.get_download_url_by_template_item` | Ссылка на скачивание по шаблону | `dict` |
320
+ | `project_form_type.get_list` | Типы форм проекта | `list[dict]` |
321
+ | `project_form_field_type.get_list` | Типы полей формы проекта | `dict` |
322
+ | `form_type.get_list` | Типы форм | `list[dict]` |
323
+ | `form_type_group.get_list` | Группы типов форм | `list[dict]` |
324
+ | `form_field_type.get_list` | Типы полей форм | `list[dict]` |
325
+
326
+ ### дашборды (board, card, card_group)
327
+ | Метод | Описание | Возвращает |
328
+ |---|---|---|
329
+ | `board.get_list` | Дашборды проекта | `list[dict]` |
330
+ | `card_group.get_list` | Группы карточек дашборда (тег `Group` в API) | `list[dict]` |
331
+ | `card.get_list` | Карточки дашборда | `list[dict]` |
332
+ | `card.get` | Карточка с содержимым | `dict` |
333
+
334
+ ### бронирования и слоты (booking, slot)
335
+ | Метод | Описание | Возвращает |
336
+ |---|---|---|
337
+ | `booking.get_list` | Бронирования компании (курсорная пагинация) | `list[dict]` |
338
+ | `booking.create_batch` | Создает бронирования пачкой (до 200) | `list[dict]` |
339
+ | `booking.delete_batch` | Удаляет бронирования | `None` |
340
+ | `slot.get_list` | Слоты компании (курсорная пагинация) | `list[dict]` |
341
+ | `slot.create_batch` | Создает слоты пачкой (до 200) | `list[dict]` |
342
+ | `slot.delete_batch` | Удаляет слоты | `None` |
343
+
231
344
  ### user_log
232
345
  | Метод | Описание | Возвращает |
233
346
  |---------------------|--------------------------------------|--------------|