vaiz-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vaiz_sdk-0.1.0/PKG-INFO +241 -0
- vaiz_sdk-0.1.0/README.md +213 -0
- vaiz_sdk-0.1.0/pyproject.toml +44 -0
- vaiz_sdk-0.1.0/setup.cfg +4 -0
- vaiz_sdk-0.1.0/tests/test_boards.py +26 -0
- vaiz_sdk-0.1.0/tests/test_client.py +46 -0
- vaiz_sdk-0.1.0/tests/test_config.py +35 -0
- vaiz_sdk-0.1.0/tests/test_profile.py +23 -0
- vaiz_sdk-0.1.0/vaiz/__init__.py +21 -0
- vaiz_sdk-0.1.0/vaiz/api/__init__.py +4 -0
- vaiz_sdk-0.1.0/vaiz/api/base.py +27 -0
- vaiz_sdk-0.1.0/vaiz/api/boards.py +27 -0
- vaiz_sdk-0.1.0/vaiz/api/profile.py +14 -0
- vaiz_sdk-0.1.0/vaiz/api/tasks.py +43 -0
- vaiz_sdk-0.1.0/vaiz/client.py +14 -0
- vaiz_sdk-0.1.0/vaiz/models/__init__.py +19 -0
- vaiz_sdk-0.1.0/vaiz/models/base.py +19 -0
- vaiz_sdk-0.1.0/vaiz/models/boards.py +55 -0
- vaiz_sdk-0.1.0/vaiz/models/profile.py +36 -0
- vaiz_sdk-0.1.0/vaiz/models/tasks.py +94 -0
- vaiz_sdk-0.1.0/vaiz_sdk.egg-info/PKG-INFO +241 -0
- vaiz_sdk-0.1.0/vaiz_sdk.egg-info/SOURCES.txt +24 -0
- vaiz_sdk-0.1.0/vaiz_sdk.egg-info/dependency_links.txt +1 -0
- vaiz_sdk-0.1.0/vaiz_sdk.egg-info/requires.txt +7 -0
- vaiz_sdk-0.1.0/vaiz_sdk.egg-info/top_level.txt +1 -0
vaiz_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vaiz-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official SDK for interacting with the Vaiz API
|
|
5
|
+
Author-email: Vaiz <mail@vaiz.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/vaizcom/vaiz-python-sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/vaizcom/vaiz-python-sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/vaizcom/vaiz-python-sdk/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: requests>=2.31.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0
|
|
24
|
+
Requires-Dist: python-dotenv>=0.9.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
|
|
28
|
+
|
|
29
|
+
# Vaiz SDK for Python
|
|
30
|
+
|
|
31
|
+
Python SDK for accessing the Vaiz platform.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install vaiz-sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Basic Setup
|
|
42
|
+
|
|
43
|
+
First, you need to set up your environment variables. Create a `.env` file in your project root with the following variables:
|
|
44
|
+
|
|
45
|
+
```env
|
|
46
|
+
VAIZ_API_KEY=your_api_key
|
|
47
|
+
VAIZ_SPACE_ID=your_space_id
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Creating a Client
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from vaiz import VaizClient
|
|
54
|
+
|
|
55
|
+
client = VaizClient(
|
|
56
|
+
api_key="your_api_key",
|
|
57
|
+
space_id="your_space_id",
|
|
58
|
+
verify_ssl=False, # Set to True in production
|
|
59
|
+
base_url="https://api.vaiz.local:10000/v4" # Use appropriate base URL for your environment
|
|
60
|
+
)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Working with Boards
|
|
64
|
+
|
|
65
|
+
#### Get All Boards
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
response = client.get_boards()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### Get a Single Board
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
response = client.get_board("board_id")
|
|
75
|
+
board = response.payload["board"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Working with Profile
|
|
79
|
+
|
|
80
|
+
#### Get User Profile
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
response = client.get_profile()
|
|
84
|
+
profile = response.payload["profile"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Working with Tasks
|
|
88
|
+
|
|
89
|
+
#### Create a Task
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from vaiz.models import CreateTaskRequest, TaskPriority
|
|
93
|
+
|
|
94
|
+
task = CreateTaskRequest(
|
|
95
|
+
name="My Task",
|
|
96
|
+
group="group_id",
|
|
97
|
+
board="board_id",
|
|
98
|
+
project="project_id",
|
|
99
|
+
priority=TaskPriority.High,
|
|
100
|
+
completed=False,
|
|
101
|
+
types=["type_id"],
|
|
102
|
+
subtasks=[],
|
|
103
|
+
milestones=[],
|
|
104
|
+
rightConnectors=[],
|
|
105
|
+
leftConnectors=[]
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
response = client.create_task(task)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Edit a Task
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from vaiz.models import EditTaskRequest
|
|
115
|
+
|
|
116
|
+
edit_task = EditTaskRequest(
|
|
117
|
+
taskId="task_id",
|
|
118
|
+
name="Updated Task Name",
|
|
119
|
+
assignees=["assignee_id"]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
response = client.edit_task(edit_task)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### Get Task Information
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
response = client.get_task("task_id")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
### Setting Up Development Environment
|
|
134
|
+
|
|
135
|
+
1. Create and activate a virtual environment:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
python3 -m venv venv
|
|
139
|
+
source venv/bin/activate # On Windows use: venv\Scripts\activate
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. Install the package in development mode:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pip install -e .
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Testing
|
|
149
|
+
|
|
150
|
+
#### Setup
|
|
151
|
+
|
|
152
|
+
1. Install test dependencies:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
pip install pytest pytest-mock python-dotenv
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
2. Create a `.env` file in the project root with your test credentials:
|
|
159
|
+
|
|
160
|
+
```env
|
|
161
|
+
VAIZ_API_KEY=your_test_api_key
|
|
162
|
+
VAIZ_SPACE_ID=your_test_space_id
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The test configuration (`tests/test_config.py`) will automatically load these credentials.
|
|
166
|
+
|
|
167
|
+
#### Running Tests
|
|
168
|
+
|
|
169
|
+
Run all tests:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
PYTHONPATH=. pytest
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Run specific test file:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
PYTHONPATH=. pytest tests/test_client.py
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Run with verbose output:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
PYTHONPATH=. pytest -v
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Note: Setting `PYTHONPATH=.` is required to ensure Python can find the package modules during testing.
|
|
188
|
+
|
|
189
|
+
#### Writing Tests
|
|
190
|
+
|
|
191
|
+
When writing tests for the SDK:
|
|
192
|
+
|
|
193
|
+
1. Use the test configuration from `tests/test_config.py`:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from tests.test_config import get_test_client, TEST_BOARD_ID, TEST_GROUP_ID
|
|
197
|
+
|
|
198
|
+
def test_create_task(mocker):
|
|
199
|
+
client = get_test_client()
|
|
200
|
+
# Your test code here
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
2. Mock external API calls using `pytest-mock`:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
def test_create_task(mocker):
|
|
207
|
+
# Mock the API response
|
|
208
|
+
mock_response = mocker.Mock()
|
|
209
|
+
mock_response.json.return_value = {
|
|
210
|
+
"type": "success",
|
|
211
|
+
"payload": {"task": {"_id": "test_task_id"}}
|
|
212
|
+
}
|
|
213
|
+
mocker.patch('requests.post', return_value=mock_response)
|
|
214
|
+
|
|
215
|
+
# Test implementation
|
|
216
|
+
client = get_test_client()
|
|
217
|
+
# ... rest of the test
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
3. Test both success and error cases
|
|
221
|
+
4. Include proper assertions for response data
|
|
222
|
+
|
|
223
|
+
### Examples
|
|
224
|
+
|
|
225
|
+
The `examples/` directory contains working examples of SDK usage. You can run any example using the following command:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
python -m examples.<example_file_name>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Contributing
|
|
232
|
+
|
|
233
|
+
1. Fork the repository
|
|
234
|
+
2. Create a feature branch
|
|
235
|
+
3. Write tests for your changes
|
|
236
|
+
4. Ensure all tests pass
|
|
237
|
+
5. Submit a pull request
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
vaiz_sdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Vaiz SDK for Python
|
|
2
|
+
|
|
3
|
+
Python SDK for accessing the Vaiz platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install vaiz-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Basic Setup
|
|
14
|
+
|
|
15
|
+
First, you need to set up your environment variables. Create a `.env` file in your project root with the following variables:
|
|
16
|
+
|
|
17
|
+
```env
|
|
18
|
+
VAIZ_API_KEY=your_api_key
|
|
19
|
+
VAIZ_SPACE_ID=your_space_id
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Creating a Client
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from vaiz import VaizClient
|
|
26
|
+
|
|
27
|
+
client = VaizClient(
|
|
28
|
+
api_key="your_api_key",
|
|
29
|
+
space_id="your_space_id",
|
|
30
|
+
verify_ssl=False, # Set to True in production
|
|
31
|
+
base_url="https://api.vaiz.local:10000/v4" # Use appropriate base URL for your environment
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Working with Boards
|
|
36
|
+
|
|
37
|
+
#### Get All Boards
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
response = client.get_boards()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Get a Single Board
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
response = client.get_board("board_id")
|
|
47
|
+
board = response.payload["board"]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Working with Profile
|
|
51
|
+
|
|
52
|
+
#### Get User Profile
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
response = client.get_profile()
|
|
56
|
+
profile = response.payload["profile"]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Working with Tasks
|
|
60
|
+
|
|
61
|
+
#### Create a Task
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from vaiz.models import CreateTaskRequest, TaskPriority
|
|
65
|
+
|
|
66
|
+
task = CreateTaskRequest(
|
|
67
|
+
name="My Task",
|
|
68
|
+
group="group_id",
|
|
69
|
+
board="board_id",
|
|
70
|
+
project="project_id",
|
|
71
|
+
priority=TaskPriority.High,
|
|
72
|
+
completed=False,
|
|
73
|
+
types=["type_id"],
|
|
74
|
+
subtasks=[],
|
|
75
|
+
milestones=[],
|
|
76
|
+
rightConnectors=[],
|
|
77
|
+
leftConnectors=[]
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
response = client.create_task(task)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Edit a Task
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from vaiz.models import EditTaskRequest
|
|
87
|
+
|
|
88
|
+
edit_task = EditTaskRequest(
|
|
89
|
+
taskId="task_id",
|
|
90
|
+
name="Updated Task Name",
|
|
91
|
+
assignees=["assignee_id"]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
response = client.edit_task(edit_task)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Get Task Information
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
response = client.get_task("task_id")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
### Setting Up Development Environment
|
|
106
|
+
|
|
107
|
+
1. Create and activate a virtual environment:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
python3 -m venv venv
|
|
111
|
+
source venv/bin/activate # On Windows use: venv\Scripts\activate
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
2. Install the package in development mode:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pip install -e .
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Testing
|
|
121
|
+
|
|
122
|
+
#### Setup
|
|
123
|
+
|
|
124
|
+
1. Install test dependencies:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pip install pytest pytest-mock python-dotenv
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
2. Create a `.env` file in the project root with your test credentials:
|
|
131
|
+
|
|
132
|
+
```env
|
|
133
|
+
VAIZ_API_KEY=your_test_api_key
|
|
134
|
+
VAIZ_SPACE_ID=your_test_space_id
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The test configuration (`tests/test_config.py`) will automatically load these credentials.
|
|
138
|
+
|
|
139
|
+
#### Running Tests
|
|
140
|
+
|
|
141
|
+
Run all tests:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
PYTHONPATH=. pytest
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Run specific test file:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
PYTHONPATH=. pytest tests/test_client.py
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Run with verbose output:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
PYTHONPATH=. pytest -v
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Note: Setting `PYTHONPATH=.` is required to ensure Python can find the package modules during testing.
|
|
160
|
+
|
|
161
|
+
#### Writing Tests
|
|
162
|
+
|
|
163
|
+
When writing tests for the SDK:
|
|
164
|
+
|
|
165
|
+
1. Use the test configuration from `tests/test_config.py`:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from tests.test_config import get_test_client, TEST_BOARD_ID, TEST_GROUP_ID
|
|
169
|
+
|
|
170
|
+
def test_create_task(mocker):
|
|
171
|
+
client = get_test_client()
|
|
172
|
+
# Your test code here
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
2. Mock external API calls using `pytest-mock`:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
def test_create_task(mocker):
|
|
179
|
+
# Mock the API response
|
|
180
|
+
mock_response = mocker.Mock()
|
|
181
|
+
mock_response.json.return_value = {
|
|
182
|
+
"type": "success",
|
|
183
|
+
"payload": {"task": {"_id": "test_task_id"}}
|
|
184
|
+
}
|
|
185
|
+
mocker.patch('requests.post', return_value=mock_response)
|
|
186
|
+
|
|
187
|
+
# Test implementation
|
|
188
|
+
client = get_test_client()
|
|
189
|
+
# ... rest of the test
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
3. Test both success and error cases
|
|
193
|
+
4. Include proper assertions for response data
|
|
194
|
+
|
|
195
|
+
### Examples
|
|
196
|
+
|
|
197
|
+
The `examples/` directory contains working examples of SDK usage. You can run any example using the following command:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
python -m examples.<example_file_name>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Contributing
|
|
204
|
+
|
|
205
|
+
1. Fork the repository
|
|
206
|
+
2. Create a feature branch
|
|
207
|
+
3. Write tests for your changes
|
|
208
|
+
4. Ensure all tests pass
|
|
209
|
+
5. Submit a pull request
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "vaiz-sdk"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Official SDK for interacting with the Vaiz API"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Vaiz", email = "mail@vaiz.com" }
|
|
7
|
+
]
|
|
8
|
+
license = { text = "MIT" }
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Topic :: Software Development :: Libraries",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.8",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
dependencies = [
|
|
26
|
+
"requests>=2.31.0",
|
|
27
|
+
"pydantic>=2.0",
|
|
28
|
+
"python-dotenv>=0.9.0"
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest>=8.0.0",
|
|
34
|
+
"pytest-mock>=3.12.0"
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/vaizcom/vaiz-python-sdk"
|
|
39
|
+
Repository = "https://github.com/vaizcom/vaiz-python-sdk"
|
|
40
|
+
Issues = "https://github.com/vaizcom/vaiz-python-sdk/issues"
|
|
41
|
+
|
|
42
|
+
[build-system]
|
|
43
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
44
|
+
build-backend = "setuptools.build_meta"
|
vaiz_sdk-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from vaiz.models import BoardsResponse, Board, BoardResponse
|
|
3
|
+
from tests.test_config import get_test_client, TEST_BOARD_ID
|
|
4
|
+
|
|
5
|
+
def test_get_boards():
|
|
6
|
+
client = get_test_client()
|
|
7
|
+
response = client.get_boards()
|
|
8
|
+
assert isinstance(response, BoardsResponse)
|
|
9
|
+
assert hasattr(response.payload, 'boards')
|
|
10
|
+
boards = response.payload.boards
|
|
11
|
+
assert isinstance(boards, list)
|
|
12
|
+
# Проверим хотя бы одну доску, если есть
|
|
13
|
+
if boards:
|
|
14
|
+
board = boards[0]
|
|
15
|
+
assert isinstance(board, Board)
|
|
16
|
+
assert isinstance(board.id, str)
|
|
17
|
+
assert isinstance(board.name, str)
|
|
18
|
+
|
|
19
|
+
def test_get_board():
|
|
20
|
+
client = get_test_client()
|
|
21
|
+
response = client.get_board(TEST_BOARD_ID)
|
|
22
|
+
assert isinstance(response, BoardResponse)
|
|
23
|
+
assert isinstance(response.payload["board"], Board)
|
|
24
|
+
board = response.payload["board"]
|
|
25
|
+
assert board.id == TEST_BOARD_ID
|
|
26
|
+
assert isinstance(board.name, str)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from tests.test_config import get_test_client, TEST_BOARD_ID, TEST_GROUP_ID, TEST_PROJECT_ID, TEST_ASSIGNEE_ID
|
|
3
|
+
from vaiz.models import CreateTaskRequest, EditTaskRequest, TaskPriority
|
|
4
|
+
|
|
5
|
+
@pytest.fixture(scope="module")
|
|
6
|
+
def client():
|
|
7
|
+
return get_test_client()
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="module")
|
|
10
|
+
def task_id(client):
|
|
11
|
+
task = CreateTaskRequest(
|
|
12
|
+
name="Integration Test Task",
|
|
13
|
+
group=TEST_GROUP_ID,
|
|
14
|
+
board=TEST_BOARD_ID,
|
|
15
|
+
project=TEST_PROJECT_ID,
|
|
16
|
+
priority=TaskPriority.High,
|
|
17
|
+
completed=False,
|
|
18
|
+
types=["649bea169d17e4070e0337fa"],
|
|
19
|
+
assignees=[TEST_ASSIGNEE_ID],
|
|
20
|
+
subtasks=[],
|
|
21
|
+
milestones=[],
|
|
22
|
+
rightConnectors=[],
|
|
23
|
+
leftConnectors=[]
|
|
24
|
+
)
|
|
25
|
+
response = client.create_task(task)
|
|
26
|
+
assert response.type == "CreateTask"
|
|
27
|
+
return response.payload["task"]["_id"]
|
|
28
|
+
|
|
29
|
+
def test_create_task(client, task_id):
|
|
30
|
+
assert task_id
|
|
31
|
+
|
|
32
|
+
def test_edit_task(client, task_id):
|
|
33
|
+
edit_task = EditTaskRequest(
|
|
34
|
+
taskId=task_id,
|
|
35
|
+
name="Integration Test Task Updated",
|
|
36
|
+
assignees=[TEST_ASSIGNEE_ID]
|
|
37
|
+
)
|
|
38
|
+
response = client.edit_task(edit_task)
|
|
39
|
+
assert response.type == "EditTask"
|
|
40
|
+
assert response.payload["task"]["name"] == "Integration Test Task Updated"
|
|
41
|
+
|
|
42
|
+
def test_get_task(client, task_id):
|
|
43
|
+
response = client.get_task(task_id)
|
|
44
|
+
assert response.type == "GetTask"
|
|
45
|
+
assert response.payload["task"]["_id"] == task_id
|
|
46
|
+
assert response.payload["task"]["name"] == "Integration Test Task Updated"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test configuration module for Vaiz SDK tests.
|
|
3
|
+
Contains test credentials and helper functions for testing.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
from vaiz import VaizClient
|
|
9
|
+
|
|
10
|
+
# Load environment variables from .env file
|
|
11
|
+
load_dotenv()
|
|
12
|
+
|
|
13
|
+
# Test credentials
|
|
14
|
+
TEST_API_KEY = os.getenv("VAIZ_API_KEY")
|
|
15
|
+
if not TEST_API_KEY:
|
|
16
|
+
raise ValueError("Please set VAIZ_API_KEY environment variable or create a .env file with VAIZ_API_KEY=your_api_key")
|
|
17
|
+
|
|
18
|
+
TEST_SPACE_ID = os.getenv("VAIZ_SPACE_ID")
|
|
19
|
+
if not TEST_SPACE_ID:
|
|
20
|
+
raise ValueError("Please set VAIZ_SPACE_ID environment variable or create a .env file with VAIZ_SPACE_ID=your_space_id")
|
|
21
|
+
|
|
22
|
+
# Test configuration constants
|
|
23
|
+
TEST_BOARD_ID = "68455de3e48da05d905c51e1"
|
|
24
|
+
TEST_GROUP_ID = "68455de3e48da05d905c51e2"
|
|
25
|
+
TEST_PROJECT_ID = "676d6758c6ea65cbc1f06d81"
|
|
26
|
+
TEST_ASSIGNEE_ID = "676d6758c6ea65cbc1f06d70"
|
|
27
|
+
|
|
28
|
+
def get_test_client():
|
|
29
|
+
"""Initialize and return a VaizClient instance for testing."""
|
|
30
|
+
return VaizClient(
|
|
31
|
+
api_key=TEST_API_KEY,
|
|
32
|
+
space_id=TEST_SPACE_ID,
|
|
33
|
+
verify_ssl=False,
|
|
34
|
+
base_url="https://api.vaiz.local:10000/v4"
|
|
35
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from vaiz.models import ProfileResponse, Profile
|
|
3
|
+
from tests.test_config import get_test_client
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_get_profile():
|
|
7
|
+
client = get_test_client()
|
|
8
|
+
response = client.get_profile()
|
|
9
|
+
assert isinstance(response, ProfileResponse)
|
|
10
|
+
assert isinstance(response.payload["profile"], Profile)
|
|
11
|
+
profile = response.payload["profile"]
|
|
12
|
+
assert isinstance(profile.id, str)
|
|
13
|
+
assert isinstance(profile.fullName, str)
|
|
14
|
+
assert isinstance(profile.nickName, str)
|
|
15
|
+
assert isinstance(profile.email, str)
|
|
16
|
+
assert isinstance(profile.emails, list)
|
|
17
|
+
assert len(profile.emails) > 0
|
|
18
|
+
assert isinstance(profile.emails[0].email, str)
|
|
19
|
+
assert isinstance(profile.emails[0].confirmed, bool)
|
|
20
|
+
assert isinstance(profile.emails[0].primary, bool)
|
|
21
|
+
assert isinstance(profile.avatarMode, int)
|
|
22
|
+
assert isinstance(profile.incompleteSteps, list)
|
|
23
|
+
assert isinstance(profile.memberId, str)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .client import VaizClient
|
|
2
|
+
from .models import (
|
|
3
|
+
TaskFollower,
|
|
4
|
+
TaskPriority,
|
|
5
|
+
CustomField,
|
|
6
|
+
CreateTaskRequest,
|
|
7
|
+
EditTaskRequest,
|
|
8
|
+
Task,
|
|
9
|
+
TaskResponse,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
'VaizClient',
|
|
14
|
+
'TaskFollower',
|
|
15
|
+
'TaskPriority',
|
|
16
|
+
'CustomField',
|
|
17
|
+
'CreateTaskRequest',
|
|
18
|
+
'EditTaskRequest',
|
|
19
|
+
'Task',
|
|
20
|
+
'TaskResponse',
|
|
21
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
class BaseAPIClient:
|
|
5
|
+
def __init__(self, api_key: str, space_id: str, base_url: str = "https://api.vaiz.com/v4", verify_ssl: bool = True):
|
|
6
|
+
self.api_key = api_key
|
|
7
|
+
self.space_id = space_id
|
|
8
|
+
self.base_url = base_url
|
|
9
|
+
self.verify_ssl = verify_ssl
|
|
10
|
+
self.session = requests.Session()
|
|
11
|
+
self.session.headers.update({
|
|
12
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
"current-space-id": self.space_id,
|
|
15
|
+
"app-version": "1.68.1",
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
def _make_request(self, endpoint: str, method: str = "POST", json_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
|
19
|
+
url = f"{self.base_url}/{endpoint}"
|
|
20
|
+
print(f"Request payload: {json_data}") # Debug print
|
|
21
|
+
response = self.session.request(method, url, json=json_data, verify=self.verify_ssl)
|
|
22
|
+
if not response.ok:
|
|
23
|
+
print(f"Error response: {response.text}") # Debug print
|
|
24
|
+
response.raise_for_status()
|
|
25
|
+
response_data = response.json()
|
|
26
|
+
print(f"Response data: {response_data}") # Debug print
|
|
27
|
+
return response_data
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from vaiz.api.base import BaseAPIClient
|
|
2
|
+
from vaiz.models import BoardsResponse, BoardResponse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BoardsAPIClient(BaseAPIClient):
|
|
6
|
+
def get_boards(self) -> BoardsResponse:
|
|
7
|
+
"""
|
|
8
|
+
Get all boards in the current space.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
BoardsResponse: The list of boards
|
|
12
|
+
"""
|
|
13
|
+
response_data = self._make_request("getBoards", method="POST", json_data={})
|
|
14
|
+
return BoardsResponse(**response_data)
|
|
15
|
+
|
|
16
|
+
def get_board(self, board_id: str) -> BoardResponse:
|
|
17
|
+
"""
|
|
18
|
+
Get a single board by its ID.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
board_id (str): The ID of the board to retrieve
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
BoardResponse: The board information
|
|
25
|
+
"""
|
|
26
|
+
response_data = self._make_request("getBoard", method="POST", json_data={"boardId": board_id})
|
|
27
|
+
return BoardResponse(**response_data)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from vaiz.api.base import BaseAPIClient
|
|
2
|
+
from vaiz.models import ProfileResponse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ProfileAPIClient(BaseAPIClient):
|
|
6
|
+
def get_profile(self) -> ProfileResponse:
|
|
7
|
+
"""
|
|
8
|
+
Get the current user's profile.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
ProfileResponse: The user's profile information
|
|
12
|
+
"""
|
|
13
|
+
response_data = self._make_request("getProfile", method="POST", json_data={})
|
|
14
|
+
return ProfileResponse(**response_data)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from vaiz.api.base import BaseAPIClient
|
|
2
|
+
from vaiz.models import CreateTaskRequest, TaskResponse, EditTaskRequest
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TasksAPIClient(BaseAPIClient):
|
|
6
|
+
def create_task(self, task: CreateTaskRequest) -> TaskResponse:
|
|
7
|
+
"""
|
|
8
|
+
Create a new task.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
task (CreateTaskRequest): The task creation request containing all necessary task information
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
TaskResponse: The created task information
|
|
15
|
+
"""
|
|
16
|
+
response_data = self._make_request("createTask", json_data=task.model_dump(by_alias=True))
|
|
17
|
+
return TaskResponse(**response_data)
|
|
18
|
+
|
|
19
|
+
def edit_task(self, task: EditTaskRequest) -> TaskResponse:
|
|
20
|
+
"""
|
|
21
|
+
Edit an existing task.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
task (EditTaskRequest): The task edit request containing the updated task information
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
TaskResponse: The updated task information
|
|
28
|
+
"""
|
|
29
|
+
response_data = self._make_request("editTask", json_data=task.model_dump(by_alias=True))
|
|
30
|
+
return TaskResponse(**response_data)
|
|
31
|
+
|
|
32
|
+
def get_task(self, slug: str) -> TaskResponse:
|
|
33
|
+
"""
|
|
34
|
+
Get task information by its slug.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
slug (str): The task slug (e.g. "ABC-123")
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
TaskResponse: The task information
|
|
41
|
+
"""
|
|
42
|
+
response_data = self._make_request("getTask", json_data={"slug": slug})
|
|
43
|
+
return TaskResponse(**response_data)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# vaiz/client.py
|
|
2
|
+
from vaiz.api.tasks import TasksAPIClient
|
|
3
|
+
from vaiz.api.boards import BoardsAPIClient
|
|
4
|
+
from vaiz.api.profile import ProfileAPIClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class VaizClient(TasksAPIClient, BoardsAPIClient, ProfileAPIClient):
|
|
8
|
+
"""
|
|
9
|
+
Main client for interacting with the Vaiz API.
|
|
10
|
+
This class inherits all task-related operations from TasksAPIClient,
|
|
11
|
+
board-related operations from BoardsAPIClient,
|
|
12
|
+
and profile-related operations from ProfileAPIClient.
|
|
13
|
+
"""
|
|
14
|
+
pass
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .base import TaskFollower, TaskPriority, CustomField
|
|
2
|
+
from .tasks import Task, TaskResponse, CreateTaskRequest, EditTaskRequest
|
|
3
|
+
from vaiz.models.boards import Board, BoardsResponse, BoardResponse
|
|
4
|
+
from vaiz.models.profile import Profile, ProfileResponse
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
'TaskFollower',
|
|
8
|
+
'TaskPriority',
|
|
9
|
+
'CustomField',
|
|
10
|
+
'CreateTaskRequest',
|
|
11
|
+
'EditTaskRequest',
|
|
12
|
+
'Task',
|
|
13
|
+
'TaskResponse',
|
|
14
|
+
'Board',
|
|
15
|
+
'BoardsResponse',
|
|
16
|
+
'BoardResponse',
|
|
17
|
+
'Profile',
|
|
18
|
+
'ProfileResponse'
|
|
19
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from pydantic import BaseModel, RootModel, Field
|
|
2
|
+
from typing import List, Optional, Dict, Literal, Any, Union
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TaskFollower(RootModel):
|
|
7
|
+
root: Dict[str, Literal["creator"]]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskPriority(int, Enum):
|
|
11
|
+
Low = 0
|
|
12
|
+
General = 1
|
|
13
|
+
Medium = 2
|
|
14
|
+
High = 3
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CustomField(BaseModel):
|
|
18
|
+
id: str
|
|
19
|
+
value: Union[str, List[str]]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import List, Optional, Dict, Any
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BoardGroup(BaseModel):
|
|
6
|
+
name: str
|
|
7
|
+
id: str = Field(..., alias="_id")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BoardType(BaseModel):
|
|
11
|
+
label: str
|
|
12
|
+
icon: str
|
|
13
|
+
color: str
|
|
14
|
+
id: str = Field(..., alias="_id")
|
|
15
|
+
description: Optional[str] = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BoardCustomField(BaseModel):
|
|
19
|
+
name: str
|
|
20
|
+
type: str
|
|
21
|
+
id: str = Field(..., alias="_id")
|
|
22
|
+
description: Optional[str] = None
|
|
23
|
+
options: Optional[List[Any]] = None
|
|
24
|
+
hidden: Optional[bool] = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Board(BaseModel):
|
|
28
|
+
id: str = Field(..., alias="_id")
|
|
29
|
+
name: str
|
|
30
|
+
project: Optional[str] = None
|
|
31
|
+
creator: Optional[str] = None
|
|
32
|
+
archiver: Optional[str] = None
|
|
33
|
+
archived_at: Optional[str] = Field(None, alias="archivedAt")
|
|
34
|
+
created_at: Optional[str] = Field(None, alias="createdAt")
|
|
35
|
+
deleter: Optional[str] = None
|
|
36
|
+
deleted_at: Optional[str] = Field(None, alias="deletedAt")
|
|
37
|
+
groups: Optional[List[BoardGroup]] = None
|
|
38
|
+
types_list: Optional[List[BoardType]] = Field(None, alias="typesList")
|
|
39
|
+
custom_fields: Optional[List[BoardCustomField]] = Field(None, alias="customFields")
|
|
40
|
+
task_order_by_groups: Optional[Dict[str, List[str]]] = Field(None, alias="taskOrderByGroups")
|
|
41
|
+
updated_at: Optional[str] = Field(None, alias="updatedAt")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class BoardsPayload(BaseModel):
|
|
45
|
+
boards: List[Board]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class BoardsResponse(BaseModel):
|
|
49
|
+
type: str
|
|
50
|
+
payload: BoardsPayload
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class BoardResponse(BaseModel):
|
|
54
|
+
type: str
|
|
55
|
+
payload: Dict[str, Board] = Field(..., alias="payload")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Optional, List, Dict, Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ProfileEmail(BaseModel):
|
|
6
|
+
email: str
|
|
7
|
+
confirmed: bool
|
|
8
|
+
primary: bool
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProfileColor(BaseModel):
|
|
12
|
+
color: Dict[str, Any] = {}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Profile(BaseModel):
|
|
16
|
+
id: str = Field(..., alias="_id")
|
|
17
|
+
fullName: str
|
|
18
|
+
nickName: str
|
|
19
|
+
email: str
|
|
20
|
+
emails: List[ProfileEmail]
|
|
21
|
+
color: ProfileColor = Field(default_factory=ProfileColor)
|
|
22
|
+
avatarMode: int
|
|
23
|
+
incompleteSteps: List[str]
|
|
24
|
+
registeredDate: str
|
|
25
|
+
recoveryCodes: List[str]
|
|
26
|
+
passwordChangedDate: str
|
|
27
|
+
passwordHash: str
|
|
28
|
+
memberId: str
|
|
29
|
+
created_at: str = Field(..., alias="createdAt")
|
|
30
|
+
updated_at: str = Field(..., alias="updatedAt")
|
|
31
|
+
cData: Dict[str, Optional[str]]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ProfileResponse(BaseModel):
|
|
35
|
+
type: str
|
|
36
|
+
payload: Dict[str, Profile] = Field(..., alias="payload")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Dict, Any, List, Optional
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from .base import TaskPriority, CustomField
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TaskCustomField(BaseModel):
|
|
8
|
+
id: str
|
|
9
|
+
value: Any
|
|
10
|
+
_id: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Task(BaseModel):
|
|
14
|
+
_id: str
|
|
15
|
+
name: str
|
|
16
|
+
group: str
|
|
17
|
+
board: str
|
|
18
|
+
project: str
|
|
19
|
+
parentTask: Optional[str] = None
|
|
20
|
+
types: List[str] = []
|
|
21
|
+
priority: int
|
|
22
|
+
hrid: str
|
|
23
|
+
followers: Dict[str, str]
|
|
24
|
+
archiver: Optional[str] = None
|
|
25
|
+
completed: bool
|
|
26
|
+
assignees: List[str] = []
|
|
27
|
+
subtasks: List[str] = []
|
|
28
|
+
milestones: List[str] = []
|
|
29
|
+
dueStart: Optional[str] = None
|
|
30
|
+
dueEnd: Optional[str] = None
|
|
31
|
+
rightConnectors: List[str] = []
|
|
32
|
+
leftConnectors: List[str] = []
|
|
33
|
+
archivedAt: Optional[str] = None
|
|
34
|
+
completedAt: Optional[str] = None
|
|
35
|
+
customFields: List[TaskCustomField] = []
|
|
36
|
+
deleter: Optional[str] = None
|
|
37
|
+
deletedAt: Optional[str] = None
|
|
38
|
+
creator: str
|
|
39
|
+
createdAt: str
|
|
40
|
+
updatedAt: str
|
|
41
|
+
document: str
|
|
42
|
+
editor: Optional[str] = None
|
|
43
|
+
milestone: Optional[str] = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TaskResponse(BaseModel):
|
|
47
|
+
payload: Dict[str, Any]
|
|
48
|
+
type: str
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class CreateTaskRequest(BaseModel):
|
|
52
|
+
name: str
|
|
53
|
+
group: str
|
|
54
|
+
board: str
|
|
55
|
+
project: str
|
|
56
|
+
parentTask: Optional[str] = None
|
|
57
|
+
types: List[str] = []
|
|
58
|
+
priority: TaskPriority = TaskPriority.General
|
|
59
|
+
completed: bool = False
|
|
60
|
+
assignees: List[str] = []
|
|
61
|
+
subtasks: List[str] = []
|
|
62
|
+
milestones: List[str] = []
|
|
63
|
+
dueStart: Optional[str] = None
|
|
64
|
+
dueEnd: Optional[str] = None
|
|
65
|
+
rightConnectors: List[str] = []
|
|
66
|
+
leftConnectors: List[str] = []
|
|
67
|
+
customFields: List[CustomField] = []
|
|
68
|
+
|
|
69
|
+
def model_dump(self, **kwargs):
|
|
70
|
+
# Remove None values from the dict
|
|
71
|
+
data = super().model_dump(**kwargs)
|
|
72
|
+
return {k: v for k, v in data.items() if v is not None}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class EditTaskRequest(BaseModel):
|
|
76
|
+
taskId: str
|
|
77
|
+
name: Optional[str] = None
|
|
78
|
+
parentTask: Optional[str] = None
|
|
79
|
+
types: Optional[List[str]] = None
|
|
80
|
+
priority: Optional[TaskPriority] = None
|
|
81
|
+
completed: Optional[bool] = None
|
|
82
|
+
assignees: Optional[List[str]] = None
|
|
83
|
+
subtasks: Optional[List[str]] = None
|
|
84
|
+
milestones: Optional[List[str]] = None
|
|
85
|
+
dueStart: Optional[str] = None
|
|
86
|
+
dueEnd: Optional[str] = None
|
|
87
|
+
rightConnectors: Optional[List[str]] = None
|
|
88
|
+
leftConnectors: Optional[List[str]] = None
|
|
89
|
+
customFields: Optional[List[CustomField]] = None
|
|
90
|
+
|
|
91
|
+
def model_dump(self, **kwargs):
|
|
92
|
+
# Remove None values from the dict
|
|
93
|
+
data = super().model_dump(**kwargs)
|
|
94
|
+
return {k: v for k, v in data.items() if v is not None}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vaiz-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official SDK for interacting with the Vaiz API
|
|
5
|
+
Author-email: Vaiz <mail@vaiz.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/vaizcom/vaiz-python-sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/vaizcom/vaiz-python-sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/vaizcom/vaiz-python-sdk/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: requests>=2.31.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0
|
|
24
|
+
Requires-Dist: python-dotenv>=0.9.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
|
|
28
|
+
|
|
29
|
+
# Vaiz SDK for Python
|
|
30
|
+
|
|
31
|
+
Python SDK for accessing the Vaiz platform.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install vaiz-sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Basic Setup
|
|
42
|
+
|
|
43
|
+
First, you need to set up your environment variables. Create a `.env` file in your project root with the following variables:
|
|
44
|
+
|
|
45
|
+
```env
|
|
46
|
+
VAIZ_API_KEY=your_api_key
|
|
47
|
+
VAIZ_SPACE_ID=your_space_id
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Creating a Client
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from vaiz import VaizClient
|
|
54
|
+
|
|
55
|
+
client = VaizClient(
|
|
56
|
+
api_key="your_api_key",
|
|
57
|
+
space_id="your_space_id",
|
|
58
|
+
verify_ssl=False, # Set to True in production
|
|
59
|
+
base_url="https://api.vaiz.local:10000/v4" # Use appropriate base URL for your environment
|
|
60
|
+
)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Working with Boards
|
|
64
|
+
|
|
65
|
+
#### Get All Boards
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
response = client.get_boards()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### Get a Single Board
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
response = client.get_board("board_id")
|
|
75
|
+
board = response.payload["board"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Working with Profile
|
|
79
|
+
|
|
80
|
+
#### Get User Profile
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
response = client.get_profile()
|
|
84
|
+
profile = response.payload["profile"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Working with Tasks
|
|
88
|
+
|
|
89
|
+
#### Create a Task
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from vaiz.models import CreateTaskRequest, TaskPriority
|
|
93
|
+
|
|
94
|
+
task = CreateTaskRequest(
|
|
95
|
+
name="My Task",
|
|
96
|
+
group="group_id",
|
|
97
|
+
board="board_id",
|
|
98
|
+
project="project_id",
|
|
99
|
+
priority=TaskPriority.High,
|
|
100
|
+
completed=False,
|
|
101
|
+
types=["type_id"],
|
|
102
|
+
subtasks=[],
|
|
103
|
+
milestones=[],
|
|
104
|
+
rightConnectors=[],
|
|
105
|
+
leftConnectors=[]
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
response = client.create_task(task)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Edit a Task
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from vaiz.models import EditTaskRequest
|
|
115
|
+
|
|
116
|
+
edit_task = EditTaskRequest(
|
|
117
|
+
taskId="task_id",
|
|
118
|
+
name="Updated Task Name",
|
|
119
|
+
assignees=["assignee_id"]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
response = client.edit_task(edit_task)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### Get Task Information
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
response = client.get_task("task_id")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
### Setting Up Development Environment
|
|
134
|
+
|
|
135
|
+
1. Create and activate a virtual environment:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
python3 -m venv venv
|
|
139
|
+
source venv/bin/activate # On Windows use: venv\Scripts\activate
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. Install the package in development mode:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pip install -e .
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Testing
|
|
149
|
+
|
|
150
|
+
#### Setup
|
|
151
|
+
|
|
152
|
+
1. Install test dependencies:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
pip install pytest pytest-mock python-dotenv
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
2. Create a `.env` file in the project root with your test credentials:
|
|
159
|
+
|
|
160
|
+
```env
|
|
161
|
+
VAIZ_API_KEY=your_test_api_key
|
|
162
|
+
VAIZ_SPACE_ID=your_test_space_id
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The test configuration (`tests/test_config.py`) will automatically load these credentials.
|
|
166
|
+
|
|
167
|
+
#### Running Tests
|
|
168
|
+
|
|
169
|
+
Run all tests:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
PYTHONPATH=. pytest
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Run specific test file:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
PYTHONPATH=. pytest tests/test_client.py
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Run with verbose output:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
PYTHONPATH=. pytest -v
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Note: Setting `PYTHONPATH=.` is required to ensure Python can find the package modules during testing.
|
|
188
|
+
|
|
189
|
+
#### Writing Tests
|
|
190
|
+
|
|
191
|
+
When writing tests for the SDK:
|
|
192
|
+
|
|
193
|
+
1. Use the test configuration from `tests/test_config.py`:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from tests.test_config import get_test_client, TEST_BOARD_ID, TEST_GROUP_ID
|
|
197
|
+
|
|
198
|
+
def test_create_task(mocker):
|
|
199
|
+
client = get_test_client()
|
|
200
|
+
# Your test code here
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
2. Mock external API calls using `pytest-mock`:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
def test_create_task(mocker):
|
|
207
|
+
# Mock the API response
|
|
208
|
+
mock_response = mocker.Mock()
|
|
209
|
+
mock_response.json.return_value = {
|
|
210
|
+
"type": "success",
|
|
211
|
+
"payload": {"task": {"_id": "test_task_id"}}
|
|
212
|
+
}
|
|
213
|
+
mocker.patch('requests.post', return_value=mock_response)
|
|
214
|
+
|
|
215
|
+
# Test implementation
|
|
216
|
+
client = get_test_client()
|
|
217
|
+
# ... rest of the test
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
3. Test both success and error cases
|
|
221
|
+
4. Include proper assertions for response data
|
|
222
|
+
|
|
223
|
+
### Examples
|
|
224
|
+
|
|
225
|
+
The `examples/` directory contains working examples of SDK usage. You can run any example using the following command:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
python -m examples.<example_file_name>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Contributing
|
|
232
|
+
|
|
233
|
+
1. Fork the repository
|
|
234
|
+
2. Create a feature branch
|
|
235
|
+
3. Write tests for your changes
|
|
236
|
+
4. Ensure all tests pass
|
|
237
|
+
5. Submit a pull request
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.cfg
|
|
4
|
+
tests/test_boards.py
|
|
5
|
+
tests/test_client.py
|
|
6
|
+
tests/test_config.py
|
|
7
|
+
tests/test_profile.py
|
|
8
|
+
vaiz/__init__.py
|
|
9
|
+
vaiz/client.py
|
|
10
|
+
vaiz/api/__init__.py
|
|
11
|
+
vaiz/api/base.py
|
|
12
|
+
vaiz/api/boards.py
|
|
13
|
+
vaiz/api/profile.py
|
|
14
|
+
vaiz/api/tasks.py
|
|
15
|
+
vaiz/models/__init__.py
|
|
16
|
+
vaiz/models/base.py
|
|
17
|
+
vaiz/models/boards.py
|
|
18
|
+
vaiz/models/profile.py
|
|
19
|
+
vaiz/models/tasks.py
|
|
20
|
+
vaiz_sdk.egg-info/PKG-INFO
|
|
21
|
+
vaiz_sdk.egg-info/SOURCES.txt
|
|
22
|
+
vaiz_sdk.egg-info/dependency_links.txt
|
|
23
|
+
vaiz_sdk.egg-info/requires.txt
|
|
24
|
+
vaiz_sdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
vaiz
|