vikunja-python 0.1.0__py3-none-any.whl
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.
- vikunja_python/__init__.py +0 -0
- vikunja_python/cli/__init__.py +0 -0
- vikunja_python/cli/main.py +264 -0
- vikunja_python/core/__init__.py +0 -0
- vikunja_python/core/client.py +106 -0
- vikunja_python/core/models/__init__.py +377 -0
- vikunja_python/core/models/api_token.py +131 -0
- vikunja_python/core/models/auth.py +34 -0
- vikunja_python/core/models/base.py +193 -0
- vikunja_python/core/models/bulk_assignees.py +98 -0
- vikunja_python/core/models/filter.py +134 -0
- vikunja_python/core/models/label.py +230 -0
- vikunja_python/core/models/link_sharing.py +138 -0
- vikunja_python/core/models/migration.py +404 -0
- vikunja_python/core/models/phase6_medium.py +74 -0
- vikunja_python/core/models/project.py +217 -0
- vikunja_python/core/models/relation.py +199 -0
- vikunja_python/core/models/task.py +261 -0
- vikunja_python/core/models/task_expansion.py +252 -0
- vikunja_python/core/models/user.py +838 -0
- vikunja_python/core/models/webhook.py +270 -0
- vikunja_python/mcp/__init__.py +0 -0
- vikunja_python/mcp/server.py +678 -0
- vikunja_python-0.1.0.dist-info/METADATA +16 -0
- vikunja_python-0.1.0.dist-info/RECORD +28 -0
- vikunja_python-0.1.0.dist-info/WHEEL +5 -0
- vikunja_python-0.1.0.dist-info/entry_points.txt +3 -0
- vikunja_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Webhook Models for Vikunja API
|
|
3
|
+
|
|
4
|
+
Covers: models.Webhook - Webhook target management
|
|
5
|
+
|
|
6
|
+
Webhook Workflow:
|
|
7
|
+
1. Create webhook target with POST /projects/{id}/webhooks or POST /user/webhooks
|
|
8
|
+
2. Configure target URL, events, and optional auth (Basic Auth, HMAC secret)
|
|
9
|
+
3. Vikunja sends POST requests to target URL when configured events occur
|
|
10
|
+
4. Manage webhooks via GET/POST/DELETE endpoints
|
|
11
|
+
|
|
12
|
+
Supported Events:
|
|
13
|
+
- task.created
|
|
14
|
+
- task.updated
|
|
15
|
+
- task.deleted
|
|
16
|
+
- task.completed
|
|
17
|
+
- task.uncompleted
|
|
18
|
+
- comment.created
|
|
19
|
+
- comment.updated
|
|
20
|
+
- comment.deleted
|
|
21
|
+
|
|
22
|
+
Usage Examples:
|
|
23
|
+
# Create project webhook for task events
|
|
24
|
+
webhook = WebhookCreateRequest(
|
|
25
|
+
target_url="https://example.com/vikunja-webhook",
|
|
26
|
+
events=["task.created", "task.updated"],
|
|
27
|
+
secret="hmac_secret_key" # For request signing
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# User-level webhook (mutually exclusive with project_id)
|
|
31
|
+
user_webhook = WebhookCreateRequest(
|
|
32
|
+
target_url="https://example.com/user-notifications",
|
|
33
|
+
events=["task.completed"],
|
|
34
|
+
user_id=1
|
|
35
|
+
)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from pydantic import Field, field_validator
|
|
39
|
+
from datetime import datetime
|
|
40
|
+
from typing import Optional, List
|
|
41
|
+
from .base import VikunjaBaseModel
|
|
42
|
+
from .user import User
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ============================================================================
|
|
46
|
+
# Webhook Event Types (Literal)
|
|
47
|
+
# ============================================================================
|
|
48
|
+
|
|
49
|
+
WebhookEvent = str
|
|
50
|
+
"""Webhook event type.
|
|
51
|
+
|
|
52
|
+
API spec: models.Webhook.events (array of strings)
|
|
53
|
+
|
|
54
|
+
Common Events:
|
|
55
|
+
"task.created" - Task created
|
|
56
|
+
"task.updated" - Task updated
|
|
57
|
+
"task.deleted" - Task deleted
|
|
58
|
+
"task.completed" - Task marked as done
|
|
59
|
+
"task.uncompleted" - Task unmarked from done
|
|
60
|
+
"comment.created" - Comment added to task
|
|
61
|
+
"comment.updated" - Comment edited
|
|
62
|
+
"comment.deleted" - Comment removed
|
|
63
|
+
|
|
64
|
+
Usage:
|
|
65
|
+
from models.webhook import WebhookEvent
|
|
66
|
+
|
|
67
|
+
webhook = WebhookCreateRequest(
|
|
68
|
+
target_url="https://example.com/hook",
|
|
69
|
+
events=["task.created", "task.completed"]
|
|
70
|
+
)
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
# Named constants for clarity
|
|
74
|
+
TaskCreated = "task.created"
|
|
75
|
+
TaskUpdated = "task.updated"
|
|
76
|
+
TaskDeleted = "task.deleted"
|
|
77
|
+
TaskCompleted = "task.completed"
|
|
78
|
+
TaskUncompleted = "task.uncompleted"
|
|
79
|
+
CommentCreated = "comment.created"
|
|
80
|
+
CommentUpdated = "comment.updated"
|
|
81
|
+
CommentDeleted = "comment.deleted"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# ============================================================================
|
|
85
|
+
# Webhook Models
|
|
86
|
+
# ============================================================================
|
|
87
|
+
|
|
88
|
+
class Webhook(VikunjaBaseModel):
|
|
89
|
+
"""
|
|
90
|
+
Webhook target configuration.
|
|
91
|
+
|
|
92
|
+
API endpoint: GET /projects/{id}/webhooks, GET /user/webhooks
|
|
93
|
+
|
|
94
|
+
Represents a configured webhook that Vikunja will call when events occur.
|
|
95
|
+
|
|
96
|
+
Fields from API spec (models.Webhook):
|
|
97
|
+
- id: Unique webhook identifier
|
|
98
|
+
- target_url: URL where POST requests are sent
|
|
99
|
+
- project_id: Project this webhook belongs to (mutually exclusive with user_id)
|
|
100
|
+
- user_id: User this webhook belongs to (mutually exclusive with project_id)
|
|
101
|
+
- events: List of events that trigger this webhook
|
|
102
|
+
- basic_auth_user: Optional Basic Auth username
|
|
103
|
+
- basic_auth_password: Optional Basic Auth password
|
|
104
|
+
- secret: HMAC signing secret for request verification
|
|
105
|
+
- created_by: User who created the webhook
|
|
106
|
+
- created/updated: Timestamps
|
|
107
|
+
|
|
108
|
+
Example from API response:
|
|
109
|
+
{
|
|
110
|
+
"id": 1,
|
|
111
|
+
"target_url": "https://example.com/vikunja-webhook",
|
|
112
|
+
"project_id": 5,
|
|
113
|
+
"user_id": null,
|
|
114
|
+
"events": ["task.created", "task.updated"],
|
|
115
|
+
"basic_auth_user": "webhook_user",
|
|
116
|
+
"basic_auth_password": "secret_pass",
|
|
117
|
+
"secret": "hmac_secret_key",
|
|
118
|
+
"created_by": {"id": 1, "username": "alice"},
|
|
119
|
+
"created": "2024-01-15T10:30:00Z",
|
|
120
|
+
"updated": "2024-01-15T10:30:00Z"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
Usage:
|
|
124
|
+
# Get project webhooks
|
|
125
|
+
webhooks = WebhookListResponse.model_validate(api_response)
|
|
126
|
+
|
|
127
|
+
for webhook in webhooks.webhooks:
|
|
128
|
+
print(f"Webhook {webhook.id}: {webhook.target_url}")
|
|
129
|
+
print(f" Events: {', '.join(webhook.events)}")
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
# Core Identification (2 fields)
|
|
133
|
+
id: Optional[int] = Field(None, description="Unique webhook ID")
|
|
134
|
+
target_url: str = Field(..., description="Target URL for POST requests")
|
|
135
|
+
|
|
136
|
+
# Scope (1 field - mutually exclusive with user_id)
|
|
137
|
+
project_id: Optional[int] = Field(
|
|
138
|
+
None,
|
|
139
|
+
description="Project ID (mutually exclusive with user_id)"
|
|
140
|
+
)
|
|
141
|
+
user_id: Optional[int] = Field(
|
|
142
|
+
None,
|
|
143
|
+
description="User ID (mutually exclusive with project_id)"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Configuration (3 fields)
|
|
147
|
+
events: Optional[List[WebhookEvent]] = Field(
|
|
148
|
+
None,
|
|
149
|
+
description="Events that trigger this webhook"
|
|
150
|
+
)
|
|
151
|
+
basic_auth_user: Optional[str] = Field(
|
|
152
|
+
None,
|
|
153
|
+
description="Basic Auth username for webhook requests"
|
|
154
|
+
)
|
|
155
|
+
basic_auth_password: Optional[str] = Field(
|
|
156
|
+
None,
|
|
157
|
+
description="Basic Auth password for webhook requests"
|
|
158
|
+
)
|
|
159
|
+
secret: Optional[str] = Field(
|
|
160
|
+
None,
|
|
161
|
+
description="HMAC signing secret for request verification"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Metadata (3 fields)
|
|
165
|
+
created_by: Optional[User] = Field(None, description="User who created this webhook")
|
|
166
|
+
created: Optional[datetime] = Field(None, description="Webhook creation timestamp")
|
|
167
|
+
updated: Optional[datetime] = Field(None, description="Last update timestamp")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class WebhookCreateRequest(VikunjaBaseModel):
|
|
171
|
+
"""
|
|
172
|
+
Request body for creating a webhook.
|
|
173
|
+
|
|
174
|
+
API endpoint: POST /projects/{id}/webhooks or POST /user/webhooks
|
|
175
|
+
|
|
176
|
+
Required fields: target_url
|
|
177
|
+
Optional fields: events, basic_auth_user, basic_auth_password, secret
|
|
178
|
+
|
|
179
|
+
Note: Either project_id or user_id must be set (handled by API route)
|
|
180
|
+
|
|
181
|
+
Example:
|
|
182
|
+
req = WebhookCreateRequest(
|
|
183
|
+
target_url="https://example.com/vikunja-webhook",
|
|
184
|
+
events=["task.created", "task.updated"],
|
|
185
|
+
secret="hmac_secret_key"
|
|
186
|
+
)
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
# Required (1 field)
|
|
190
|
+
target_url: str = Field(..., description="Target URL for POST requests")
|
|
191
|
+
|
|
192
|
+
# Optional Configuration (4 fields)
|
|
193
|
+
events: Optional[List[WebhookEvent]] = Field(
|
|
194
|
+
None,
|
|
195
|
+
description="Events that trigger this webhook"
|
|
196
|
+
)
|
|
197
|
+
basic_auth_user: Optional[str] = Field(
|
|
198
|
+
None,
|
|
199
|
+
description="Basic Auth username for webhook requests"
|
|
200
|
+
)
|
|
201
|
+
basic_auth_password: Optional[str] = Field(
|
|
202
|
+
None,
|
|
203
|
+
description="Basic Auth password for webhook requests"
|
|
204
|
+
)
|
|
205
|
+
secret: Optional[str] = Field(
|
|
206
|
+
None,
|
|
207
|
+
description="HMAC signing secret for request verification"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
def model_dump_for_api(self) -> dict:
|
|
211
|
+
"""Convert to dict for API submission."""
|
|
212
|
+
return self.model_dump(exclude_none=True)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class WebhookUpdateRequest(VikunjaBaseModel):
|
|
216
|
+
"""
|
|
217
|
+
Request body for updating a webhook.
|
|
218
|
+
|
|
219
|
+
API endpoint: POST /projects/{id}/webhooks/{webhook_id}
|
|
220
|
+
|
|
221
|
+
All fields are optional - only provided fields are updated.
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
req = WebhookUpdateRequest(
|
|
225
|
+
events=["task.created", "task.updated", "task.deleted"],
|
|
226
|
+
secret="new_secret_key"
|
|
227
|
+
)
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
# Optional Configuration (5 fields)
|
|
231
|
+
target_url: Optional[str] = Field(None, description="New target URL")
|
|
232
|
+
events: Optional[List[WebhookEvent]] = Field(None, description="New event list")
|
|
233
|
+
basic_auth_user: Optional[str] = Field(None, description="New Basic Auth username")
|
|
234
|
+
basic_auth_password: Optional[str] = Field(None, description="New Basic Auth password")
|
|
235
|
+
secret: Optional[str] = Field(None, description="New HMAC signing secret")
|
|
236
|
+
|
|
237
|
+
def model_dump_for_api(self) -> dict:
|
|
238
|
+
"""Convert to dict, excluding None values."""
|
|
239
|
+
return self.model_dump(exclude_none=True)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# ============================================================================
|
|
243
|
+
# Response Models
|
|
244
|
+
# ============================================================================
|
|
245
|
+
|
|
246
|
+
class WebhookListResponse(VikunjaBaseModel):
|
|
247
|
+
"""Response for listing webhooks."""
|
|
248
|
+
success: bool = Field(True, description="Request succeeded")
|
|
249
|
+
webhooks: List[Webhook] = Field(default_factory=list, description="List of webhooks")
|
|
250
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class WebhookGetResponse(VikunjaBaseModel):
|
|
254
|
+
"""Response for getting a single webhook."""
|
|
255
|
+
success: bool = Field(True, description="Request succeeded")
|
|
256
|
+
webhook: Optional[Webhook] = Field(None, description="The requested webhook")
|
|
257
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class WebhookCreateResponse(VikunjaBaseModel):
|
|
261
|
+
"""Response for creating a webhook."""
|
|
262
|
+
success: bool = Field(True, description="Request succeeded")
|
|
263
|
+
webhook: Optional[Webhook] = Field(None, description="The created webhook")
|
|
264
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class WebhookDeleteResponse(VikunjaBaseModel):
|
|
268
|
+
"""Response for deleting a webhook."""
|
|
269
|
+
success: bool = Field(True, description="Request succeeded")
|
|
270
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
File without changes
|