airbyte-source-github 2.4.0__tar.gz → 2.5.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.
Files changed (46) hide show
  1. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/PKG-INFO +1 -1
  2. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/pyproject.toml +1 -1
  3. airbyte_source_github-2.5.0/source_github/components.py +83 -0
  4. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/manifest.yaml +1179 -0
  5. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/source.py +0 -31
  6. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/streams.py +15 -673
  7. airbyte_source_github-2.4.0/source_github/schemas/commit_comment_reactions.json +0 -4
  8. airbyte_source_github-2.4.0/source_github/schemas/issue_comment_reactions.json +0 -4
  9. airbyte_source_github-2.4.0/source_github/schemas/project_cards.json +0 -64
  10. airbyte_source_github-2.4.0/source_github/schemas/project_columns.json +0 -48
  11. airbyte_source_github-2.4.0/source_github/schemas/pull_request_commits.json +0 -155
  12. airbyte_source_github-2.4.0/source_github/schemas/team_members.json +0 -86
  13. airbyte_source_github-2.4.0/source_github/schemas/team_memberships.json +0 -30
  14. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/.airbyte-pypi-readme.md +0 -0
  15. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/__init__.py +0 -0
  16. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/backoff_strategies.py +0 -0
  17. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/config_migrations.py +0 -0
  18. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/constants.py +0 -0
  19. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/errors_handlers.py +0 -0
  20. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/github_schema.py +0 -0
  21. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/graphql.py +0 -0
  22. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/run.py +0 -0
  23. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/commit_comments.json +0 -0
  24. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/commits.json +0 -0
  25. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/contributor_activity.json +0 -0
  26. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/issue_reactions.json +0 -0
  27. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/issue_timeline_events.json +0 -0
  28. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/projects.json +0 -0
  29. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/projects_v2.json +0 -0
  30. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/pull_request_comment_reactions.json +0 -0
  31. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/pull_request_stats.json +0 -0
  32. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/pull_requests.json +0 -0
  33. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/releases.json +0 -0
  34. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/reviews.json +0 -0
  35. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/events/comment.json +0 -0
  36. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/events/commented.json +0 -0
  37. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/events/committed.json +0 -0
  38. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/events/cross_referenced.json +0 -0
  39. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/events/reviewed.json +0 -0
  40. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/reaction.json +0 -0
  41. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/reactions.json +0 -0
  42. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/user.json +0 -0
  43. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/shared/user_graphql.json +0 -0
  44. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/workflow_jobs.json +0 -0
  45. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/schemas/workflow_runs.json +0 -0
  46. {airbyte_source_github-2.4.0 → airbyte_source_github-2.5.0}/source_github/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-github
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Source implementation for GitHub.
5
5
  Home-page: https://airbyte.com
6
6
  License: ELv2
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
3
3
  build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
- version = "2.4.0"
6
+ version = "2.5.0"
7
7
  name = "airbyte-source-github"
8
8
  description = "Source implementation for GitHub."
9
9
  authors = [ "Airbyte <contact@airbyte.io>",]
@@ -0,0 +1,83 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any, Iterable, List, Mapping, MutableMapping
7
+
8
+ import requests
9
+
10
+ from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor
11
+ from airbyte_cdk.sources.declarative.migrations.state_migration import StateMigration
12
+ from airbyte_cdk.sources.types import Config
13
+
14
+
15
+ @dataclass
16
+ class IssueTimelineEventsExtractor(RecordExtractor):
17
+ """Collapse an issue's timeline page into one record keyed by event type.
18
+
19
+ The legacy `IssueTimelineEvents.parse_response` yielded `{<event type>: <event>, ...}` per page,
20
+ the last event of each type winning, and a bare record when the body was not a list.
21
+ `repository` and `issue_number` are added by the stream's transformations.
22
+ """
23
+
24
+ config: Config
25
+ parameters: Mapping[str, Any]
26
+
27
+ def extract_records(self, response: requests.Response) -> Iterable[Mapping[str, Any]]:
28
+ try:
29
+ body = response.json()
30
+ except ValueError:
31
+ body = None
32
+ record: MutableMapping[str, Any] = {}
33
+ if isinstance(body, list):
34
+ for event in body:
35
+ if isinstance(event, Mapping) and "event" in event:
36
+ record[event["event"]] = event
37
+ yield record
38
+
39
+
40
+ @dataclass
41
+ class NestedLegacyToPerPartitionStateMigration(StateMigration):
42
+ """Migrate the nested state the Python parent-child streams wrote to per-partition state.
43
+
44
+ Legacy shape: `{repository: {<parent id>: {cursor_field: value}}}`, one more level of ids per
45
+ parent (`project_cards` nests `project_id` then `column_id`). `partition_fields` lists those id
46
+ levels, outermost first. Ids were stored as strings; the declarative partitions carry them as
47
+ the integers GitHub returns.
48
+ """
49
+
50
+ config: Config
51
+ parameters: Mapping[str, Any]
52
+ cursor_field: str
53
+ partition_fields: List[str]
54
+
55
+ def should_migrate(self, stream_state: Mapping[str, Any]) -> bool:
56
+ if not stream_state or "states" in stream_state or "state" in stream_state:
57
+ return False
58
+ return all(self._is_legacy_repository_state(value) for value in stream_state.values())
59
+
60
+ def _is_legacy_repository_state(self, node: Any, depth: int = 0) -> bool:
61
+ if not isinstance(node, Mapping) or not node:
62
+ return False
63
+ if depth == len(self.partition_fields):
64
+ return set(node) == {self.cursor_field}
65
+ return all(self._is_legacy_repository_state(child, depth + 1) for child in node.values())
66
+
67
+ def migrate(self, stream_state: Mapping[str, Any]) -> Mapping[str, Any]:
68
+ states = []
69
+ for repository, node in stream_state.items():
70
+ self._collect(node, {"repository": repository}, 0, states)
71
+ return {"states": states}
72
+
73
+ def _collect(self, node: Mapping[str, Any], partition: Mapping[str, Any], depth: int, states: List[Mapping[str, Any]]) -> None:
74
+ if depth == len(self.partition_fields):
75
+ states.append({"partition": partition, "cursor": {self.cursor_field: node[self.cursor_field]}})
76
+ return
77
+ for key, child in node.items():
78
+ child_partition = {self.partition_fields[depth]: self._to_id(key), "parent_slice": partition}
79
+ self._collect(child, child_partition, depth + 1, states)
80
+
81
+ @staticmethod
82
+ def _to_id(key: str) -> Any:
83
+ return int(key) if isinstance(key, str) and key.isdigit() else key