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.
@@ -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