devrev-Python-SDK 3.0.2__py3-none-any.whl → 3.0.4__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.
devrev/client.py CHANGED
@@ -42,6 +42,10 @@ from devrev.services.rev_orgs import AsyncRevOrgsService, RevOrgsService
42
42
  from devrev.services.rev_users import AsyncRevUsersService, RevUsersService
43
43
  from devrev.services.search import AsyncSearchService, SearchService
44
44
  from devrev.services.slas import AsyncSlasService, SlasService
45
+ from devrev.services.survey_responses import (
46
+ AsyncSurveyResponsesService,
47
+ SurveyResponsesService,
48
+ )
45
49
  from devrev.services.tags import AsyncTagsService, TagsService
46
50
  from devrev.services.timeline_entries import (
47
51
  AsyncTimelineEntriesService,
@@ -164,6 +168,7 @@ class DevRevClient:
164
168
  self._rev_orgs = RevOrgsService(self._http)
165
169
  self._rev_users = RevUsersService(self._http)
166
170
  self._slas = SlasService(self._http)
171
+ self._survey_responses = SurveyResponsesService(self._http)
167
172
  self._tags = TagsService(self._http)
168
173
  self._timeline_entries = TimelineEntriesService(self._http)
169
174
  self._webhooks = WebhooksService(self._http)
@@ -259,6 +264,11 @@ class DevRevClient:
259
264
  """Access the SLAs service."""
260
265
  return self._slas
261
266
 
267
+ @property
268
+ def survey_responses(self) -> SurveyResponsesService:
269
+ """Access the Survey Responses service."""
270
+ return self._survey_responses
271
+
262
272
  @property
263
273
  def tags(self) -> TagsService:
264
274
  """Access the Tags service."""
@@ -492,6 +502,7 @@ class AsyncDevRevClient:
492
502
  self._rev_orgs = AsyncRevOrgsService(self._http)
493
503
  self._rev_users = AsyncRevUsersService(self._http)
494
504
  self._slas = AsyncSlasService(self._http)
505
+ self._survey_responses = AsyncSurveyResponsesService(self._http)
495
506
  self._tags = AsyncTagsService(self._http)
496
507
  self._timeline_entries = AsyncTimelineEntriesService(self._http)
497
508
  self._webhooks = AsyncWebhooksService(self._http)
@@ -587,6 +598,11 @@ class AsyncDevRevClient:
587
598
  """Access the SLAs service."""
588
599
  return self._slas
589
600
 
601
+ @property
602
+ def survey_responses(self) -> AsyncSurveyResponsesService:
603
+ """Access the Survey Responses service."""
604
+ return self._survey_responses
605
+
590
606
  @property
591
607
  def tags(self) -> AsyncTagsService:
592
608
  """Access the Tags service."""
devrev/models/__init__.py CHANGED
@@ -328,6 +328,12 @@ from devrev.models.slas import (
328
328
  SlasUpdateResponse,
329
329
  SlaTrackerStatus,
330
330
  )
331
+ from devrev.models.survey_responses import (
332
+ SurveyResponse,
333
+ SurveyResponsesListMode,
334
+ SurveyResponsesListRequest,
335
+ SurveyResponsesListResponse,
336
+ )
331
337
  from devrev.models.sync import (
332
338
  ExternalRef,
333
339
  StagedInfo,
@@ -699,6 +705,11 @@ __all__ = [
699
705
  "QuestionAnswersUpdateRequest",
700
706
  "QuestionAnswersUpdateResponse",
701
707
  "QuestionAnswersDeleteRequest",
708
+ # Survey Responses
709
+ "SurveyResponse",
710
+ "SurveyResponsesListMode",
711
+ "SurveyResponsesListRequest",
712
+ "SurveyResponsesListResponse",
702
713
  # Recommendations
703
714
  "MessageRole",
704
715
  "ChatMessage",
@@ -0,0 +1,77 @@
1
+ """Survey response models for DevRev SDK.
2
+
3
+ This module contains Pydantic models for the ``surveys.responses.list`` API.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from datetime import datetime
9
+ from enum import StrEnum
10
+ from typing import Any
11
+
12
+ from pydantic import ConfigDict, Field
13
+
14
+ from devrev.models.base import DevRevBaseModel, DevRevResponseModel, PaginatedResponse
15
+
16
+
17
+ class SurveyResponsesListMode(StrEnum):
18
+ """Survey response cursor iteration mode."""
19
+
20
+ AFTER = "after"
21
+ BEFORE = "before"
22
+
23
+
24
+ class SurveyResponse(DevRevResponseModel):
25
+ """DevRev survey response model."""
26
+
27
+ model_config = ConfigDict(extra="allow", populate_by_name=True, str_strip_whitespace=True)
28
+
29
+ id: str = Field(..., description="Survey response ID")
30
+ display_id: str | None = Field(default=None, description="Human-readable display ID")
31
+ created_by: dict[str, Any] | None = Field(default=None, description="Creator user summary")
32
+ created_date: datetime | None = Field(default=None, description="Creation timestamp")
33
+ modified_by: dict[str, Any] | None = Field(default=None, description="Modifier user summary")
34
+ modified_date: datetime | None = Field(default=None, description="Last modification timestamp")
35
+ object_version: int | None = Field(default=None, description="Object version")
36
+ dispatch_id: str | None = Field(default=None, description="Dispatched survey ID")
37
+ dispatched_channels: list[dict[str, Any]] | None = Field(
38
+ default=None,
39
+ description="Channels on which the survey was dispatched",
40
+ )
41
+ object: str | None = Field(default=None, description="Object for which the survey was taken")
42
+ recipient: dict[str, Any] | str | None = Field(default=None, description="Survey recipient")
43
+ response: dict[str, Any] | str | int | float | bool | None = Field(
44
+ default=None,
45
+ description="Survey response payload",
46
+ )
47
+ stage: dict[str, Any] | int | str | None = Field(default=None, description="Survey stage")
48
+ survey: dict[str, Any] | str | None = Field(default=None, description="Survey summary or ID")
49
+
50
+
51
+ class SurveyResponsesListRequest(DevRevBaseModel):
52
+ """Request to list survey responses."""
53
+
54
+ created_by: list[str] | None = Field(default=None, description="Creator user filters")
55
+ cursor: str | None = Field(default=None, description="Pagination cursor")
56
+ dispatch_ids: list[str] | None = Field(default=None, description="Survey dispatch IDs")
57
+ limit: int | None = Field(default=None, ge=1, le=100, description="Maximum results")
58
+ mode: SurveyResponsesListMode | None = Field(default=None, description="Cursor iteration mode")
59
+ object_id: str | None = Field(
60
+ default=None,
61
+ alias="object",
62
+ description="Single object ID to filter responses by",
63
+ )
64
+ objects: list[str] | None = Field(default=None, description="Object IDs to filter responses by")
65
+ recipient: list[str] | None = Field(default=None, description="Recipient user filters")
66
+ sort_by: list[str] | None = Field(default=None, description="Sort order entries")
67
+ stages: list[int] | None = Field(default=None, description="Survey response stage filters")
68
+ surveys: list[str] | None = Field(default=None, description="Survey IDs to filter by")
69
+
70
+
71
+ class SurveyResponsesListResponse(PaginatedResponse):
72
+ """Response from listing survey responses."""
73
+
74
+ survey_responses: list[SurveyResponse] = Field(
75
+ default_factory=list,
76
+ description="List of survey responses",
77
+ )
devrev/models/works.py CHANGED
@@ -96,6 +96,48 @@ class Work(DevRevResponseModel):
96
96
  actual_close_date: datetime | None = Field(default=None, description="Actual close date")
97
97
  custom_fields: dict[str, Any] | None = Field(default=None, description="Custom fields")
98
98
  external_ref: str | None = Field(default=None, description="External reference")
99
+ account: dict[str, Any] | str | None = Field(
100
+ default=None,
101
+ description="Account associated with the ticket/work, when returned by the API",
102
+ )
103
+ rev_org: dict[str, Any] | str | None = Field(
104
+ default=None,
105
+ description="Rev organization associated with the ticket/work",
106
+ )
107
+ sentiment: dict[str, Any] | str | None = Field(
108
+ default=None,
109
+ description="Current ticket sentiment, when returned by the API",
110
+ )
111
+ sentiment_summary: dict[str, Any] | str | None = Field(
112
+ default=None,
113
+ description="Structured or textual sentiment summary",
114
+ )
115
+ sentiment_modified_date: datetime | None = Field(
116
+ default=None,
117
+ description="When ticket sentiment was last modified",
118
+ )
119
+ sla_summary: dict[str, Any] | None = Field(default=None, description="Ticket SLA summary")
120
+ needs_response: bool | None = Field(
121
+ default=None,
122
+ description="Whether the ticket needs a customer response",
123
+ )
124
+ channels: list[dict[str, Any] | str] | None = Field(
125
+ default=None,
126
+ description="Channels associated with the ticket",
127
+ )
128
+ source_channel: dict[str, Any] | str | None = Field(
129
+ default=None,
130
+ description="Source channel that created the ticket",
131
+ )
132
+ group: dict[str, Any] | str | None = Field(
133
+ default=None,
134
+ description="Group associated with the work item",
135
+ )
136
+ is_frozen: bool | None = Field(default=None, description="Whether the work item is frozen")
137
+ visibility: dict[str, Any] | str | None = Field(
138
+ default=None,
139
+ description="Work item visibility, when returned by the API",
140
+ )
99
141
 
100
142
 
101
143
  class WorkSummary(DevRevResponseModel):
@@ -38,6 +38,7 @@ from devrev.services.rev_orgs import AsyncRevOrgsService, RevOrgsService
38
38
  from devrev.services.rev_users import AsyncRevUsersService, RevUsersService
39
39
  from devrev.services.search import AsyncSearchService, SearchService
40
40
  from devrev.services.slas import AsyncSlasService, SlasService
41
+ from devrev.services.survey_responses import AsyncSurveyResponsesService, SurveyResponsesService
41
42
  from devrev.services.tags import AsyncTagsService, TagsService
42
43
  from devrev.services.timeline_entries import (
43
44
  AsyncTimelineEntriesService,
@@ -112,6 +113,9 @@ __all__ = [
112
113
  # SLAs
113
114
  "SlasService",
114
115
  "AsyncSlasService",
116
+ # Survey Responses
117
+ "SurveyResponsesService",
118
+ "AsyncSurveyResponsesService",
115
119
  # Tags
116
120
  "TagsService",
117
121
  "AsyncTagsService",
@@ -0,0 +1,122 @@
1
+ """Survey response service for DevRev SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+
7
+ from devrev.models.survey_responses import (
8
+ SurveyResponsesListMode,
9
+ SurveyResponsesListRequest,
10
+ SurveyResponsesListResponse,
11
+ )
12
+ from devrev.services.base import AsyncBaseService, BaseService
13
+
14
+
15
+ def _merge_object_filters(object_id: str | None, objects: Sequence[str] | None) -> list[str] | None:
16
+ """Merge singular and plural object filters without duplicates."""
17
+ merged = list(objects or [])
18
+ if object_id and object_id not in merged:
19
+ merged.insert(0, object_id)
20
+ return merged or None
21
+
22
+
23
+ class SurveyResponsesService(BaseService):
24
+ """Synchronous service for survey/CSAT responses."""
25
+
26
+ def list(
27
+ self,
28
+ *,
29
+ object_id: str | None = None,
30
+ objects: Sequence[str] | None = None,
31
+ created_by: Sequence[str] | None = None,
32
+ cursor: str | None = None,
33
+ dispatch_ids: Sequence[str] | None = None,
34
+ limit: int | None = None,
35
+ mode: SurveyResponsesListMode | None = None,
36
+ recipient: Sequence[str] | None = None,
37
+ sort_by: Sequence[str] | None = None,
38
+ stages: Sequence[int] | None = None,
39
+ surveys: Sequence[str] | None = None,
40
+ ) -> SurveyResponsesListResponse:
41
+ """List survey responses.
42
+
43
+ Args:
44
+ object_id: Convenience filter for a single ticket/work/object ID.
45
+ objects: Object IDs to filter responses by.
46
+ created_by: Creator user filters.
47
+ cursor: Pagination cursor.
48
+ dispatch_ids: Survey dispatch IDs.
49
+ limit: Maximum number of responses to return.
50
+ mode: Cursor iteration mode.
51
+ recipient: Recipient user filters.
52
+ sort_by: Sort order entries.
53
+ stages: Survey response stage filters.
54
+ surveys: Survey IDs to filter by.
55
+
56
+ Returns:
57
+ Paginated survey response list.
58
+ """
59
+ request = SurveyResponsesListRequest(
60
+ created_by=list(created_by) if created_by else None,
61
+ cursor=cursor,
62
+ dispatch_ids=list(dispatch_ids) if dispatch_ids else None,
63
+ limit=limit,
64
+ mode=mode,
65
+ objects=_merge_object_filters(object_id, objects),
66
+ recipient=list(recipient) if recipient else None,
67
+ sort_by=list(sort_by) if sort_by else None,
68
+ stages=list(stages) if stages else None,
69
+ surveys=list(surveys) if surveys else None,
70
+ )
71
+ return self._post("/surveys.responses.list", request, SurveyResponsesListResponse)
72
+
73
+
74
+ class AsyncSurveyResponsesService(AsyncBaseService):
75
+ """Asynchronous service for survey/CSAT responses."""
76
+
77
+ async def list(
78
+ self,
79
+ *,
80
+ object_id: str | None = None,
81
+ objects: Sequence[str] | None = None,
82
+ created_by: Sequence[str] | None = None,
83
+ cursor: str | None = None,
84
+ dispatch_ids: Sequence[str] | None = None,
85
+ limit: int | None = None,
86
+ mode: SurveyResponsesListMode | None = None,
87
+ recipient: Sequence[str] | None = None,
88
+ sort_by: Sequence[str] | None = None,
89
+ stages: Sequence[int] | None = None,
90
+ surveys: Sequence[str] | None = None,
91
+ ) -> SurveyResponsesListResponse:
92
+ """List survey responses.
93
+
94
+ Args:
95
+ object_id: Convenience filter for a single ticket/work/object ID.
96
+ objects: Object IDs to filter responses by.
97
+ created_by: Creator user filters.
98
+ cursor: Pagination cursor.
99
+ dispatch_ids: Survey dispatch IDs.
100
+ limit: Maximum number of responses to return.
101
+ mode: Cursor iteration mode.
102
+ recipient: Recipient user filters.
103
+ sort_by: Sort order entries.
104
+ stages: Survey response stage filters.
105
+ surveys: Survey IDs to filter by.
106
+
107
+ Returns:
108
+ Paginated survey response list.
109
+ """
110
+ request = SurveyResponsesListRequest(
111
+ created_by=list(created_by) if created_by else None,
112
+ cursor=cursor,
113
+ dispatch_ids=list(dispatch_ids) if dispatch_ids else None,
114
+ limit=limit,
115
+ mode=mode,
116
+ objects=_merge_object_filters(object_id, objects),
117
+ recipient=list(recipient) if recipient else None,
118
+ sort_by=list(sort_by) if sort_by else None,
119
+ stages=list(stages) if stages else None,
120
+ surveys=list(surveys) if surveys else None,
121
+ )
122
+ return await self._post("/surveys.responses.list", request, SurveyResponsesListResponse)
devrev/services/works.py CHANGED
@@ -147,6 +147,21 @@ class WorksService(BaseService):
147
147
  response = self._post("/works.get", request, WorksGetResponse)
148
148
  return response.work
149
149
 
150
+ def get_raw(self, id: str) -> dict[str, Any]:
151
+ """Get the raw API payload for a work item.
152
+
153
+ Use this supported escape hatch when the DevRev API returns fields that
154
+ are not yet represented on the typed :class:`Work` model.
155
+
156
+ Args:
157
+ id: Work item ID
158
+
159
+ Returns:
160
+ Raw ``/works.get`` response payload.
161
+ """
162
+ request = WorksGetRequest(id=id)
163
+ return self._post("/works.get", request)
164
+
150
165
  def list(
151
166
  self,
152
167
  *,
@@ -439,6 +454,11 @@ class AsyncWorksService(AsyncBaseService):
439
454
  response = await self._post("/works.get", request, WorksGetResponse)
440
455
  return response.work
441
456
 
457
+ async def get_raw(self, id: str) -> dict[str, Any]:
458
+ """Get the raw API payload for a work item."""
459
+ request = WorksGetRequest(id=id)
460
+ return await self._post("/works.get", request)
461
+
442
462
  async def list(
443
463
  self,
444
464
  *,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devrev-Python-SDK
3
- Version: 3.0.2
3
+ Version: 3.0.4
4
4
  Summary: A modern, type-safe Python SDK for the DevRev API
5
5
  Project-URL: Homepage, https://github.com/mgmonteleone/py-dev-rev
6
6
  Project-URL: Documentation, https://github.com/mgmonteleone/py-dev-rev
@@ -215,6 +215,17 @@ for account in accounts:
215
215
  work = client.works.get(id="don:core:...")
216
216
  print(f"Work: {work.title} - Status: {work.stage.name}")
217
217
 
218
+ # Ticket integrations can read optional account/sentiment/SLA fields
219
+ ticket = client.works.get(id="don:core:dvrv-us-1:devo/1:ticket/123")
220
+ print(ticket.rev_org, ticket.account, ticket.needs_response)
221
+
222
+ # Use a supported raw escape hatch when the API returns newer fields
223
+ raw_ticket = client.works.get_raw(id="don:core:dvrv-us-1:devo/1:ticket/123")
224
+ print(raw_ticket["work"].keys())
225
+
226
+ # List survey/CSAT responses for a ticket without using private _http
227
+ survey_responses = client.survey_responses.list(object_id=ticket.id)
228
+
218
229
  # Create a new ticket
219
230
  ticket = client.works.create(
220
231
  title="Bug: Login page not loading",
@@ -297,6 +308,7 @@ The SDK provides complete coverage of all 209 DevRev public API endpoints, organ
297
308
  |---------|-----------|-------------|
298
309
  | **Articles** | 5 | Knowledge base articles |
299
310
  | **Conversations** | 5 | Customer conversations |
311
+ | **Survey Responses** | 1 | Survey and CSAT response listing |
300
312
  | **Timeline Entries** | 5 | Activity timeline management |
301
313
  | **Tags** | 5 | Tagging and categorization |
302
314
 
@@ -1,9 +1,9 @@
1
1
  devrev/__init__.py,sha256=iBKIRvS10mFWpBgnMjQQiQR04rgb8ZyXVk1-7cYJikI,1555
2
- devrev/client.py,sha256=FXEadZd0NzBUzXXY60e4qnN2Osv5vHE_9rj8nPpVPxI,26458
2
+ devrev/client.py,sha256=-1brQGZzGYceA9pv3moeTQy8riMSHAz3_9eBy6TtYKM,27038
3
3
  devrev/config.py,sha256=BKFhD8lMJvq-I9kpchiA50fYefVFhnNwcK9ReFogh4k,8122
4
4
  devrev/exceptions.py,sha256=Bs0pYgOgG26cyI785rdJeTR72gM-rXHaCEt24HAJzEk,7540
5
5
  devrev/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
- devrev/models/__init__.py,sha256=D9J3kwZrAUJijh4wuLbfvb7WbokL84_dRg93OxtT_k4,24033
6
+ devrev/models/__init__.py,sha256=T0ZSZIo43Qe51XCKs05lYagJDjJMsOIiclzrYL1OtJw,24339
7
7
  devrev/models/accounts.py,sha256=LrXAit2gIr34XyRO1T0fL6EwdXHsfJOyXwcegPnKnaE,6974
8
8
  devrev/models/articles.py,sha256=DgrZC_wtLsXIfilAvHJBoQkhbGDg3Vx5UX7h9MD63xA,16732
9
9
  devrev/models/artifacts.py,sha256=3iA58RyVlX0S0U5iID3Cnoc096Y70QfGqYfKEhxfE9g,4375
@@ -25,6 +25,7 @@ devrev/models/rev_orgs.py,sha256=tVJiPezfBe6MN-jgfQtp0Efh6RkLIJs4LAXutuWbwp8,621
25
25
  devrev/models/rev_users.py,sha256=8psDrbQQQkG2rM7JRfRZYgyxv2FFvhSxXaDMZy0Y8_4,10136
26
26
  devrev/models/search.py,sha256=_5OhgVz1yaqK00-rSJrG3xacp22qByYQq5HSnS1inV8,4650
27
27
  devrev/models/slas.py,sha256=U7nForRREIBV-KpTxrDsPPpyzCNwb7yHeeB94pk7Mfw,3272
28
+ devrev/models/survey_responses.py,sha256=fHJoW4jvGHJM7W2guPzEJ1G-ErgH3gXOYqJfUc4PwdQ,3484
28
29
  devrev/models/sync.py,sha256=_Wef7zgI1aYG9GBWXVTO3_oktY0SIdMuEbwLcGTJTUM,5407
29
30
  devrev/models/tags.py,sha256=5IDRerA3bUxSRVcGjvwCheRzOpgjI4AU8Rh1LYNT6tk,2473
30
31
  devrev/models/tasks.py,sha256=OLffCAEegv-8z0oXDCGXB4KiXuobizrOZ-RjILGs6f4,5055
@@ -34,8 +35,8 @@ devrev/models/track_events.py,sha256=bb9belz1W3XvrUEgp9mGdOKELhRcWL-59wS9cIa1geY
34
35
  devrev/models/uoms.py,sha256=bxjk2YhJ3qrX6C52xuokgLCHD3K4-8DRDeu2QwjnK4E,5700
35
36
  devrev/models/webhooks.py,sha256=DzrLJiW1GYWvfaB-aVPcYCf4XkEGHz3dkyzbBKKdhFI,3655
36
37
  devrev/models/widgets.py,sha256=7WWN17_ySqnu1pjYSIS5B8J5dEaqkoB8X8GWzvI0ZYc,4577
37
- devrev/models/works.py,sha256=sHZ_eJ6eCadWxPkM6HGcmbkiGRDYT2RnH3QZRO4T3tY,11198
38
- devrev/services/__init__.py,sha256=LWy_0xGNH692d6Wc4S4E9v6AoxjgfExFMzFmbrL2NTY,3975
38
+ devrev/models/works.py,sha256=n6iIkUMmhGbT9bXCeDc9QphOlHSNdLK8X4dLLqW0Qec,12870
39
+ devrev/services/__init__.py,sha256=Uhhc3TY15iwPe1DV-QqZoX0H5kKbyBwWVWmwMitbkGc,4160
39
40
  devrev/services/_pagination.py,sha256=J6AXu1P3iNRyC8_nH709Z8nOLhHeSctOLRmY_eYI6QA,2100
40
41
  devrev/services/accounts.py,sha256=X7FgcODex0XKLiV_VvXKDl2Jm8XsNpn9qp40oRjZqME,9704
41
42
  devrev/services/articles.py,sha256=xOpJOG9f29a5W3IFROplL1a9eJdGucbUFkK-MAIIYlc,41637
@@ -58,12 +59,13 @@ devrev/services/rev_orgs.py,sha256=I7oiZZNKJ1PRApUyfjFab2ke-Ox39JBGambzvAMusKY,7
58
59
  devrev/services/rev_users.py,sha256=-QfGNUzz6MQbG4n51F5WzjRxcdIGrrHB_PzjUX7rI38,15472
59
60
  devrev/services/search.py,sha256=qxXtYRgGCxkw35CazNxIkCUWsSuv1NCWxr6nVTyKFvQ,12341
60
61
  devrev/services/slas.py,sha256=9n6mdZ8E9vDrO4CeV4snc6IwyjDdoTQjQpjFw1oT4ag,2786
62
+ devrev/services/survey_responses.py,sha256=vSmlMIQnKQxc10-3GNBM21NMuRZ9wk73s_8yIMKjKu8,4647
61
63
  devrev/services/tags.py,sha256=1Xmq6VFIvL2OTCJ48PeLkTcZm2aa2BJ7OjbZVHd8rbU,2642
62
64
  devrev/services/timeline_entries.py,sha256=6nbVPcWlE3-ohLhvkM421eqYS5ztKtHmGsPek5WoT_Q,3362
63
65
  devrev/services/track_events.py,sha256=lI4wXkWu3uUuXtuRg1MGNkTZ7B0Lc1PjM8Kw-6sUnWc,1439
64
66
  devrev/services/uoms.py,sha256=AA3ymoHj24FIbsZpYC4tg2elSdQ3iINTVOz7MraZcj8,8163
65
67
  devrev/services/webhooks.py,sha256=-TSkcaya1y48WB24_vHd-bqO5xSqxRsCLiilncNzQZU,3917
66
- devrev/services/works.py,sha256=hAK7ZUqLph5Db15p4RDbeRFLZUALAF5tCFOQSYytj_g,20456
68
+ devrev/services/works.py,sha256=kt7B9goqgSJqAwTWDa4tvBZ-OdERMsTow5GHviWxUG4,21127
67
69
  devrev/utils/__init__.py,sha256=NOrbpkjDVLH8n9xf-xpZJiIIa_GVI_6vqTm3E8L3Udw,857
68
70
  devrev/utils/content_converter.py,sha256=emRBLiVoOfDGpPDzrMRnqQr4-QkqN13OdWlYOyU_LCg,28141
69
71
  devrev/utils/deprecation.py,sha256=7qB2Dx531oP7mNi7q2txOYsOKC9YwdHqlKPMFHOW9Ws,1275
@@ -117,7 +119,7 @@ devrev_mcp/utils/don_id.py,sha256=PAVzOSgaiqJQSdo1fwohFHq2x7PDNUZoBTN4LFGYM48,62
117
119
  devrev_mcp/utils/errors.py,sha256=5mRAo76rJvvEVi6b1ZokPxDtX5JKkptaqmiYDLCkwBE,2110
118
120
  devrev_mcp/utils/formatting.py,sha256=6JssG5x1BxjdgSiQ8Ou3H-9Wo3wgWTWmejsrGez4wKc,2431
119
121
  devrev_mcp/utils/pagination.py,sha256=EOUgL-ZdSToM1Q-ydXmjhibsef5K1u1g3CaS9K8I2fY,1286
120
- devrev_python_sdk-3.0.2.dist-info/METADATA,sha256=mtnQHr1M5pFsPQN1YqYQbzVOmGz8QLmphfL6hMKKT84,40906
121
- devrev_python_sdk-3.0.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
122
- devrev_python_sdk-3.0.2.dist-info/entry_points.txt,sha256=XiV4J_yy0yzVZVxg7T66YERVIlqdPNp3O-NHTHkllqQ,63
123
- devrev_python_sdk-3.0.2.dist-info/RECORD,,
122
+ devrev_python_sdk-3.0.4.dist-info/METADATA,sha256=33y0aBX1_t124x48Ng5w-pSBTBc6DNEaT4dXYV3qsKo,41490
123
+ devrev_python_sdk-3.0.4.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
124
+ devrev_python_sdk-3.0.4.dist-info/entry_points.txt,sha256=XiV4J_yy0yzVZVxg7T66YERVIlqdPNp3O-NHTHkllqQ,63
125
+ devrev_python_sdk-3.0.4.dist-info/RECORD,,