ingestr 0.13.75__py3-none-any.whl → 0.14.98__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.

Potentially problematic release.


This version of ingestr might be problematic. Click here for more details.

Files changed (79) hide show
  1. ingestr/main.py +22 -3
  2. ingestr/src/adjust/__init__.py +4 -4
  3. ingestr/src/allium/__init__.py +128 -0
  4. ingestr/src/anthropic/__init__.py +277 -0
  5. ingestr/src/anthropic/helpers.py +525 -0
  6. ingestr/src/appstore/__init__.py +1 -0
  7. ingestr/src/asana_source/__init__.py +1 -1
  8. ingestr/src/buildinfo.py +1 -1
  9. ingestr/src/chess/__init__.py +1 -1
  10. ingestr/src/couchbase_source/__init__.py +118 -0
  11. ingestr/src/couchbase_source/helpers.py +135 -0
  12. ingestr/src/cursor/__init__.py +83 -0
  13. ingestr/src/cursor/helpers.py +188 -0
  14. ingestr/src/destinations.py +169 -1
  15. ingestr/src/docebo/__init__.py +589 -0
  16. ingestr/src/docebo/client.py +435 -0
  17. ingestr/src/docebo/helpers.py +97 -0
  18. ingestr/src/elasticsearch/helpers.py +138 -0
  19. ingestr/src/errors.py +8 -0
  20. ingestr/src/facebook_ads/__init__.py +26 -23
  21. ingestr/src/facebook_ads/helpers.py +47 -1
  22. ingestr/src/factory.py +48 -0
  23. ingestr/src/filesystem/__init__.py +8 -3
  24. ingestr/src/filters.py +9 -0
  25. ingestr/src/fluxx/__init__.py +9906 -0
  26. ingestr/src/fluxx/helpers.py +209 -0
  27. ingestr/src/frankfurter/__init__.py +157 -163
  28. ingestr/src/frankfurter/helpers.py +3 -3
  29. ingestr/src/freshdesk/__init__.py +25 -8
  30. ingestr/src/freshdesk/freshdesk_client.py +40 -5
  31. ingestr/src/fundraiseup/__init__.py +49 -0
  32. ingestr/src/fundraiseup/client.py +81 -0
  33. ingestr/src/github/__init__.py +6 -4
  34. ingestr/src/google_analytics/__init__.py +1 -1
  35. ingestr/src/hostaway/__init__.py +302 -0
  36. ingestr/src/hostaway/client.py +288 -0
  37. ingestr/src/http/__init__.py +35 -0
  38. ingestr/src/http/readers.py +114 -0
  39. ingestr/src/hubspot/__init__.py +6 -12
  40. ingestr/src/influxdb/__init__.py +1 -0
  41. ingestr/src/intercom/__init__.py +142 -0
  42. ingestr/src/intercom/helpers.py +674 -0
  43. ingestr/src/intercom/settings.py +279 -0
  44. ingestr/src/jira_source/__init__.py +340 -0
  45. ingestr/src/jira_source/helpers.py +439 -0
  46. ingestr/src/jira_source/settings.py +170 -0
  47. ingestr/src/klaviyo/__init__.py +5 -5
  48. ingestr/src/linear/__init__.py +553 -116
  49. ingestr/src/linear/helpers.py +77 -38
  50. ingestr/src/mailchimp/__init__.py +126 -0
  51. ingestr/src/mailchimp/helpers.py +226 -0
  52. ingestr/src/mailchimp/settings.py +164 -0
  53. ingestr/src/masking.py +344 -0
  54. ingestr/src/monday/__init__.py +246 -0
  55. ingestr/src/monday/helpers.py +392 -0
  56. ingestr/src/monday/settings.py +328 -0
  57. ingestr/src/mongodb/__init__.py +5 -2
  58. ingestr/src/mongodb/helpers.py +384 -10
  59. ingestr/src/plusvibeai/__init__.py +335 -0
  60. ingestr/src/plusvibeai/helpers.py +544 -0
  61. ingestr/src/plusvibeai/settings.py +252 -0
  62. ingestr/src/revenuecat/__init__.py +83 -0
  63. ingestr/src/revenuecat/helpers.py +237 -0
  64. ingestr/src/salesforce/__init__.py +15 -8
  65. ingestr/src/shopify/__init__.py +1 -1
  66. ingestr/src/smartsheets/__init__.py +33 -5
  67. ingestr/src/socrata_source/__init__.py +83 -0
  68. ingestr/src/socrata_source/helpers.py +85 -0
  69. ingestr/src/socrata_source/settings.py +8 -0
  70. ingestr/src/sources.py +1418 -54
  71. ingestr/src/stripe_analytics/__init__.py +2 -19
  72. ingestr/src/wise/__init__.py +68 -0
  73. ingestr/src/wise/client.py +63 -0
  74. ingestr/tests/unit/test_smartsheets.py +6 -9
  75. {ingestr-0.13.75.dist-info → ingestr-0.14.98.dist-info}/METADATA +24 -12
  76. {ingestr-0.13.75.dist-info → ingestr-0.14.98.dist-info}/RECORD +79 -37
  77. {ingestr-0.13.75.dist-info → ingestr-0.14.98.dist-info}/WHEEL +0 -0
  78. {ingestr-0.13.75.dist-info → ingestr-0.14.98.dist-info}/entry_points.txt +0 -0
  79. {ingestr-0.13.75.dist-info → ingestr-0.14.98.dist-info}/licenses/LICENSE.md +0 -0
@@ -3,7 +3,12 @@ from typing import Any, Dict, Iterable, Iterator
3
3
  import dlt
4
4
  import pendulum
5
5
 
6
- from .helpers import _normalize_issue, _normalize_team, _paginate
6
+ from .helpers import (
7
+ _create_paginated_resource,
8
+ _get_date_range,
9
+ _graphql,
10
+ normalize_dictionaries,
11
+ )
7
12
 
8
13
  ISSUES_QUERY = """
9
14
  query Issues($cursor: String) {
@@ -14,55 +19,407 @@ query Issues($cursor: String) {
14
19
  description
15
20
  createdAt
16
21
  updatedAt
17
- creator { id }
18
- assignee { id}
19
- state { id}
20
- labels { nodes { id } }
21
- cycle { id}
22
- project { id }
23
- subtasks: children { nodes { id title } }
24
- comments(first: 250) { nodes { id body } }
22
+ archivedAt
23
+ addedToCycleAt
24
+ autoArchivedAt
25
+ autoClosedAt
26
+ boardOrder
27
+ branchName
28
+ canceledAt
29
+ completedAt
30
+ customerTicketCount
31
+ descriptionState
32
+ dueDate
33
+ estimate
34
+ identifier
35
+ integrationSourceType
36
+ labelIds
37
+ number
38
+ previousIdentifiers
25
39
  priority
26
- attachments { nodes { id } }
27
- subscribers { nodes { id } }
40
+ priorityLabel
41
+ prioritySortOrder
42
+ reactionData
43
+ slaBreachesAt
44
+ slaHighRiskAt
45
+ slaMediumRiskAt
46
+ slaStartedAt
47
+ slaType
48
+ snoozedUntilAt
49
+ sortOrder
50
+ startedAt
51
+ startedTriageAt
52
+ subIssueSortOrder
53
+ triagedAt
54
+ url
55
+
56
+ creator { id }
57
+ assignee { id }
58
+ botActor { id name type }
59
+ cycle { id }
60
+ delegate { id }
61
+ externalUserCreator { id }
62
+ favorite { id }
63
+ lastAppliedTemplate { id }
64
+ parent { id }
65
+ projectMilestone { id }
66
+ recurringIssueTemplate { id }
67
+ snoozedBy { id }
68
+ sourceComment { id }
69
+ state { id }
70
+
71
+ labels(first: 250) {
72
+ nodes {
73
+ id
74
+ }
75
+ }
28
76
  }
29
77
  pageInfo { hasNextPage endCursor }
30
78
  }
31
79
  }
32
80
  """
33
81
 
34
- PROJECTS_QUERY = """
35
- query Projects($cursor: String) {
36
- projects(first: 50, after: $cursor) {
82
+ ATTACHMENTS_QUERY = """
83
+ query Attachments($cursor: String) {
84
+ attachments(first: 50, after: $cursor) {
37
85
  nodes {
38
86
  id
39
- name
87
+ archivedAt
88
+ bodyData
89
+ createdAt
90
+ groupBySource
91
+ metadata
92
+ sourceType
93
+ subtitle
94
+ title
95
+ updatedAt
96
+ url
97
+
98
+ creator { id }
99
+ externalUserCreator { id }
100
+ issue { id }
101
+ originalIssue { id }
102
+ }
103
+ pageInfo { hasNextPage endCursor }
104
+ }
105
+ }
106
+ """
107
+
108
+ COMMENTS_QUERY = """
109
+ query Comments($cursor: String) {
110
+ comments(first: 50, after: $cursor) {
111
+ nodes {
112
+ id
113
+ archivedAt
114
+ body
115
+ bodyData
116
+ createdAt
117
+ editedAt
118
+ quotedText
119
+ reactionData
120
+ resolvedAt
121
+ threadSummary
122
+ updatedAt
123
+ url
124
+
125
+ botActor { id }
126
+ documentContent { id }
127
+ externalThread { id }
128
+ externalUser { id }
129
+ initiativeUpdate { id }
130
+ issue { id }
131
+ parent { id }
132
+ post { id }
133
+ projectUpdate { id }
134
+ resolvingComment { id }
135
+ resolvingUser { id }
136
+ user { id }
137
+ }
138
+ pageInfo { hasNextPage endCursor }
139
+ }
140
+ }
141
+ """
142
+
143
+ CYCLES_QUERY = """
144
+ query Cycles($cursor: String) {
145
+ cycles(first: 50, after: $cursor) {
146
+ nodes {
147
+ id
148
+ archivedAt
149
+ autoArchivedAt
150
+ completedAt
151
+ completedIssueCountHistory
152
+ completedScopeHistory
153
+ createdAt
40
154
  description
155
+ endsAt
156
+ inProgressScopeHistory
157
+ issueCountHistory
158
+ name
159
+ number
160
+ progress
161
+ scopeHistory
162
+ startsAt
163
+ updatedAt
164
+ }
165
+ pageInfo { hasNextPage endCursor }
166
+ }
167
+ }
168
+ """
169
+
170
+ DOCUMENTS_QUERY = """
171
+ query Documents($cursor: String) {
172
+ documents(first: 50, after: $cursor) {
173
+ nodes {
174
+ id
175
+ archivedAt
176
+ color
41
177
  createdAt
178
+ icon
179
+ slugId
180
+ title
42
181
  updatedAt
182
+
183
+ creator { id }
184
+ updatedBy { id }
185
+ }
186
+ pageInfo { hasNextPage endCursor }
187
+ }
188
+ }
189
+ """
190
+
191
+ EXTERNAL_USERS_QUERY = """
192
+ query ExternalUsers($cursor: String) {
193
+ externalUsers(first: 50, after: $cursor) {
194
+ nodes {
195
+ id
196
+ archivedAt
197
+ avatarUrl
198
+ createdAt
199
+ displayName
200
+ email
201
+ lastSeen
202
+ name
203
+ updatedAt
204
+
205
+ organization { id }
206
+ }
207
+ pageInfo { hasNextPage endCursor }
208
+ }
209
+ }
210
+ """
211
+
212
+ INITIATIVES_QUERY = """
213
+ query Initiatives($cursor: String) {
214
+ initiatives(first: 50, after: $cursor) {
215
+ nodes {
216
+ id
217
+ archivedAt
218
+ color
219
+ completedAt
220
+ content
221
+ createdAt
222
+ description
223
+ frequencyResolution
43
224
  health
44
- priority
225
+ healthUpdatedAt
226
+ icon
227
+ name
228
+ slugId
229
+ sortOrder
230
+ startedAt
231
+ status
45
232
  targetDate
46
- lead { id }
233
+ targetDateResolution
234
+ trashed
235
+ updateReminderFrequency
236
+ updateReminderFrequencyInWeeks
237
+ updateRemindersDay
238
+ updateRemindersHour
239
+ updatedAt
240
+
241
+ creator { id }
242
+ documentContent { id }
243
+ integrationsSettings { id }
244
+ lastUpdate { id }
245
+ organization { id }
246
+ owner { id }
247
+ parentInitiative { id }
47
248
  }
48
249
  pageInfo { hasNextPage endCursor }
49
250
  }
50
251
  }
51
252
  """
52
253
 
53
- TEAMS_QUERY = """
54
- query Teams($cursor: String) {
55
- teams(first: 50, after: $cursor) {
254
+
255
+ INITIATIVE_TO_PROJECTS_QUERY = """
256
+ query InitiativeToProjects($cursor: String) {
257
+ initiativeToProjects(first: 50, after: $cursor) {
56
258
  nodes {
57
259
  id
260
+ archivedAt
261
+ createdAt
262
+ sortOrder
263
+ updatedAt
264
+
265
+ initiative { id }
266
+ }
267
+ pageInfo { hasNextPage endCursor }
268
+ }
269
+ }
270
+ """
271
+
272
+ PROJECT_MILESTONES_QUERY = """
273
+ query ProjectMilestones($cursor: String) {
274
+ projectMilestones(first: 50, after: $cursor) {
275
+ nodes {
276
+ id
277
+ archivedAt
278
+ createdAt
279
+ currentProgress
280
+ description
281
+ descriptionState
58
282
  name
59
- key
283
+ progress
284
+ progressHistory
285
+ sortOrder
286
+ status
287
+ targetDate
288
+ updatedAt
289
+
290
+ documentContent { id }
291
+ }
292
+ pageInfo { hasNextPage endCursor }
293
+ }
294
+ }
295
+ """
296
+
297
+ PROJECT_STATUSES_QUERY = """
298
+ query ProjectStatuses($cursor: String) {
299
+ projectStatuses(first: 50, after: $cursor) {
300
+ nodes {
301
+ id
302
+ archivedAt
303
+ color
304
+ createdAt
305
+ description
306
+ indefinite
307
+ name
308
+ position
309
+ type
310
+ updatedAt
311
+ }
312
+ pageInfo { hasNextPage endCursor }
313
+ }
314
+ }
315
+ """
316
+
317
+ INTEGRATIONS_QUERY = """
318
+ query Integrations($cursor: String) {
319
+ integrations(first: 50, after: $cursor) {
320
+ nodes {
321
+ id
322
+ archivedAt
323
+ createdAt
324
+ service
325
+ updatedAt
326
+
327
+ creator { id }
328
+ organization { id }
329
+ }
330
+ pageInfo { hasNextPage endCursor }
331
+ }
332
+ }
333
+ """
334
+
335
+
336
+ LABELS_QUERY = """
337
+ query IssueLabels($cursor: String) {
338
+ issueLabels(first: 50, after: $cursor) {
339
+ nodes {
340
+ id
341
+ archivedAt
342
+ color
343
+ createdAt
60
344
  description
345
+ name
346
+ updatedAt
347
+
348
+ creator { id }
349
+ organization { id }
350
+ parent { id }
351
+ }
352
+ pageInfo { hasNextPage endCursor }
353
+ }
354
+ }
355
+ """
356
+
357
+
358
+ ORGANIZATION_QUERY = """
359
+ query Organization {
360
+ viewer {
361
+ organization {
362
+ id
363
+ name
364
+ createdAt
61
365
  updatedAt
366
+ archivedAt
367
+ logoUrl
368
+ allowMembersToInvite
369
+ allowedAuthServices
370
+ createdIssueCount
371
+ customerCount
372
+ customersEnabled
373
+ deletionRequestedAt
374
+ gitBranchFormat
375
+ gitLinkbackMessagesEnabled
376
+ gitPublicLinkbackMessagesEnabled
377
+ logoUrl
378
+ periodUploadVolume
379
+ previousUrlKeys
380
+ roadmapEnabled
381
+ samlEnabled
382
+ scimEnabled
383
+ }
384
+ }
385
+ }
386
+ """
387
+
388
+
389
+ PROJECT_UPDATES_QUERY = """
390
+ query ProjectUpdates($cursor: String) {
391
+ projectUpdates(first: 50, after: $cursor) {
392
+ nodes {
393
+ id
394
+ archivedAt
395
+ body
396
+ bodyData
62
397
  createdAt
63
- memberships { nodes { id } }
64
- members { nodes { id } }
65
- projects { nodes { id } }
398
+ diffMarkdown
399
+ health
400
+ updatedAt
401
+ url
402
+
403
+ user { id }
404
+ }
405
+ pageInfo { hasNextPage endCursor }
406
+ }
407
+ }
408
+ """
409
+
410
+
411
+ TEAM_MEMBERSHIPS_QUERY = """
412
+ query TeamMemberships($cursor: String) {
413
+ teamMemberships(first: 50, after: $cursor) {
414
+ nodes {
415
+ id
416
+ archivedAt
417
+ createdAt
418
+ owner
419
+ sortOrder
420
+ updatedAt
421
+
422
+ user { id }
66
423
  }
67
424
  pageInfo { hasNextPage endCursor }
68
425
  }
@@ -74,16 +431,168 @@ query Users($cursor: String) {
74
431
  users(first: 50, after: $cursor) {
75
432
  nodes {
76
433
  id
77
- name
434
+ active
435
+ admin
436
+ archivedAt
437
+ avatarUrl
438
+ calendarHash
439
+ createdAt
440
+ createdIssueCount
441
+ description
442
+ disableReason
78
443
  displayName
79
444
  email
445
+ guest
446
+ inviteHash
447
+ lastSeen
448
+ name
449
+ statusEmoji
450
+ statusLabel
451
+ statusUntilAt
452
+ timezone
453
+ updatedAt
454
+ url
455
+
456
+ organization { id }
457
+ }
458
+ pageInfo { hasNextPage endCursor }
459
+ }
460
+ }
461
+ """
462
+ WORKFLOW_STATES_QUERY = """
463
+ query WorkflowStates($cursor: String) {
464
+ workflowStates(first: 50, after: $cursor) {
465
+ nodes {
466
+ id
467
+ archivedAt
468
+ color
80
469
  createdAt
470
+ description
471
+ name
472
+ position
473
+ type
81
474
  updatedAt
82
475
  }
83
476
  pageInfo { hasNextPage endCursor }
84
477
  }
85
478
  }
86
479
  """
480
+ PROJECTS_QUERY = """
481
+ query Projects($cursor: String) {
482
+ projects(first: 50, after: $cursor) {
483
+ nodes {
484
+ id
485
+ name
486
+ description
487
+ createdAt
488
+ updatedAt
489
+ archivedAt
490
+ completedAt
491
+ canceledAt
492
+ startedAt
493
+
494
+ color
495
+ icon
496
+ slugId
497
+ url
498
+
499
+ health
500
+ priority
501
+ priorityLabel
502
+ state
503
+
504
+ targetDate
505
+ startDate
506
+
507
+ progress
508
+ currentProgress
509
+ scope
510
+
511
+ sortOrder
512
+ trashed
513
+
514
+ creator { id }
515
+ lead { id }
516
+ }
517
+ pageInfo { hasNextPage endCursor }
518
+ }
519
+ }
520
+ """
521
+
522
+ TEAMS_QUERY = """
523
+ query Teams($cursor: String) {
524
+ teams(first: 50, after: $cursor) {
525
+ nodes {
526
+ id
527
+ name
528
+ key
529
+ description
530
+ color
531
+ icon
532
+ private
533
+ archivedAt
534
+ createdAt
535
+ updatedAt
536
+
537
+ organization { id }
538
+ parent { id }
539
+
540
+ cyclesEnabled
541
+ cycleDuration
542
+ cycleStartDay
543
+ cycleCooldownTime
544
+
545
+ issueCount
546
+ issueEstimationType
547
+ issueEstimationAllowZero
548
+ issueEstimationExtended
549
+ issueOrderingNoPriorityFirst
550
+
551
+ autoArchivePeriod
552
+ autoClosePeriod
553
+ autoCloseChildIssues
554
+ autoCloseParentIssues
555
+
556
+ groupIssueHistory
557
+ timezone
558
+ inviteHash
559
+ joinByDefault
560
+
561
+ slackNewIssue
562
+ slackIssueComments
563
+ slackIssueStatuses
564
+
565
+ triageEnabled
566
+ requirePriorityToLeaveTriage
567
+ upcomingCycleCount
568
+ }
569
+ pageInfo { hasNextPage endCursor }
570
+ }
571
+ }
572
+ """
573
+
574
+
575
+ # Paginated resources configuration
576
+ PAGINATED_RESOURCES = [
577
+ ("issues", ISSUES_QUERY, "issues"),
578
+ ("users", USERS_QUERY, "users"),
579
+ ("workflow_states", WORKFLOW_STATES_QUERY, "workflowStates"),
580
+ ("cycles", CYCLES_QUERY, "cycles"),
581
+ ("attachments", ATTACHMENTS_QUERY, "attachments"),
582
+ ("comments", COMMENTS_QUERY, "comments"),
583
+ ("documents", DOCUMENTS_QUERY, "documents"),
584
+ ("external_users", EXTERNAL_USERS_QUERY, "externalUsers"),
585
+ ("initiative", INITIATIVES_QUERY, "initiatives"),
586
+ ("integrations", INTEGRATIONS_QUERY, "integrations"),
587
+ ("labels", LABELS_QUERY, "issueLabels"),
588
+ ("project_updates", PROJECT_UPDATES_QUERY, "projectUpdates"),
589
+ ("team_memberships", TEAM_MEMBERSHIPS_QUERY, "teamMemberships"),
590
+ ("initiative_to_project", INITIATIVE_TO_PROJECTS_QUERY, "initiativeToProjects"),
591
+ ("project_milestone", PROJECT_MILESTONES_QUERY, "projectMilestones"),
592
+ ("project_status", PROJECT_STATUSES_QUERY, "projectStatuses"),
593
+ ("projects", PROJECTS_QUERY, "projects"),
594
+ ("teams", TEAMS_QUERY, "teams"),
595
+ ]
87
596
 
88
597
 
89
598
  @dlt.source(name="linear", max_table_nesting=0)
@@ -92,8 +601,8 @@ def linear_source(
92
601
  start_date: pendulum.DateTime,
93
602
  end_date: pendulum.DateTime | None = None,
94
603
  ) -> Iterable[dlt.sources.DltResource]:
95
- @dlt.resource(name="issues", primary_key="id", write_disposition="merge")
96
- def issues(
604
+ @dlt.resource(name="organization", primary_key="id", write_disposition="merge")
605
+ def organization(
97
606
  updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
98
607
  "updatedAt",
99
608
  initial_value=start_date.isoformat(),
@@ -102,96 +611,24 @@ def linear_source(
102
611
  range_end="closed",
103
612
  ),
104
613
  ) -> Iterator[Dict[str, Any]]:
105
- if updated_at.last_value:
106
- current_start_date = pendulum.parse(updated_at.last_value)
107
- else:
108
- current_start_date = pendulum.parse(start_date)
109
-
110
- if updated_at.end_value:
111
- current_end_date = pendulum.parse(updated_at.end_value)
112
- else:
113
- current_end_date = pendulum.now(tz="UTC")
114
-
115
- for item in _paginate(api_key, ISSUES_QUERY, "issues"):
116
- if pendulum.parse(item["updatedAt"]) >= current_start_date:
117
- if pendulum.parse(item["updatedAt"]) <= current_end_date:
118
- yield _normalize_issue(item)
614
+ current_start_date, current_end_date = _get_date_range(updated_at, start_date)
119
615
 
120
- @dlt.resource(name="projects", primary_key="id", write_disposition="merge")
121
- def projects(
122
- updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
123
- "updatedAt",
124
- initial_value=start_date.isoformat(),
125
- end_value=end_date.isoformat() if end_date else None,
126
- range_start="closed",
127
- range_end="closed",
128
- ),
129
- ) -> Iterator[Dict[str, Any]]:
130
- if updated_at.last_value:
131
- current_start_date = pendulum.parse(updated_at.last_value)
132
- else:
133
- current_start_date = pendulum.parse(start_date)
134
-
135
- if updated_at.end_value:
136
- current_end_date = pendulum.parse(updated_at.end_value)
137
- else:
138
- current_end_date = pendulum.now(tz="UTC")
139
-
140
- for item in _paginate(api_key, PROJECTS_QUERY, "projects"):
141
- if pendulum.parse(item["updatedAt"]) >= current_start_date:
616
+ data = _graphql(api_key, ORGANIZATION_QUERY)
617
+ if "viewer" in data and "organization" in data["viewer"]:
618
+ item = data["viewer"]["organization"]
619
+ if item and pendulum.parse(item["updatedAt"]) >= current_start_date:
142
620
  if pendulum.parse(item["updatedAt"]) <= current_end_date:
143
- yield item
621
+ yield normalize_dictionaries(item)
144
622
 
145
- @dlt.resource(name="teams", primary_key="id", write_disposition="merge")
146
- def teams(
147
- updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
148
- "updatedAt",
149
- initial_value=start_date.isoformat(),
150
- end_value=end_date.isoformat() if end_date else None,
151
- range_start="closed",
152
- range_end="closed",
153
- ),
154
- ) -> Iterator[Dict[str, Any]]:
155
- print(start_date)
156
- if updated_at.last_value:
157
- current_start_date = pendulum.parse(updated_at.last_value)
158
- else:
159
- current_start_date = pendulum.parse(start_date)
160
- print(current_start_date)
161
-
162
- if updated_at.end_value:
163
- current_end_date = pendulum.parse(updated_at.end_value)
164
- else:
165
- current_end_date = pendulum.now(tz="UTC")
166
-
167
- for item in _paginate(api_key, TEAMS_QUERY, "teams"):
168
- if pendulum.parse(item["updatedAt"]) >= current_start_date:
169
- if pendulum.parse(item["updatedAt"]) <= current_end_date:
170
- yield _normalize_team(item)
171
-
172
- @dlt.resource(name="users", primary_key="id", write_disposition="merge")
173
- def users(
174
- updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
175
- "updatedAt",
176
- initial_value=start_date.isoformat(),
177
- end_value=end_date.isoformat() if end_date else None,
178
- range_start="closed",
179
- range_end="closed",
180
- ),
181
- ) -> Iterator[Dict[str, Any]]:
182
- if updated_at.last_value:
183
- current_start_date = pendulum.parse(updated_at.last_value)
184
- else:
185
- current_start_date = pendulum.parse(start_date)
186
-
187
- if updated_at.end_value:
188
- current_end_date = pendulum.parse(updated_at.end_value)
189
- else:
190
- current_end_date = pendulum.now(tz="UTC")
191
-
192
- for item in _paginate(api_key, USERS_QUERY, "users"):
193
- if pendulum.parse(item["updatedAt"]) >= current_start_date:
194
- if pendulum.parse(item["updatedAt"]) <= current_end_date:
195
- yield item
623
+ # Create paginated resources dynamically
624
+ paginated_resources = [
625
+ _create_paginated_resource(
626
+ resource_name, query, query_field, api_key, start_date, end_date
627
+ )
628
+ for resource_name, query, query_field in PAGINATED_RESOURCES
629
+ ]
196
630
 
197
- return issues, projects, teams, users
631
+ return [
632
+ *paginated_resources,
633
+ organization,
634
+ ]