airbyte-internal-ops 0.9.1__py3-none-any.whl → 0.10.1__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.
@@ -1432,3 +1432,409 @@ def set_organization_connector_version_override(
1432
1432
  )
1433
1433
 
1434
1434
  return True
1435
+
1436
+
1437
+ def start_connector_rollout(
1438
+ docker_repository: str,
1439
+ docker_image_tag: str,
1440
+ actor_definition_id: str,
1441
+ updated_by: str,
1442
+ rollout_strategy: Literal["manual", "automated", "overridden"],
1443
+ config_api_root: str,
1444
+ initial_rollout_pct: int | None = None,
1445
+ final_target_rollout_pct: int | None = None,
1446
+ client_id: str | None = None,
1447
+ client_secret: str | None = None,
1448
+ bearer_token: str | None = None,
1449
+ ) -> dict[str, Any]:
1450
+ """Start a connector rollout workflow.
1451
+
1452
+ This function calls the platform API to start a connector rollout workflow,
1453
+ transitioning the rollout from INITIALIZED to WORKFLOW_STARTED state.
1454
+
1455
+ Args:
1456
+ docker_repository: The docker repository (e.g., "airbyte/source-github")
1457
+ docker_image_tag: The docker image tag (e.g., "1.2.0-rc.2")
1458
+ actor_definition_id: The actor definition ID (UUID)
1459
+ updated_by: The user ID performing the operation (UUID)
1460
+ rollout_strategy: The rollout strategy - "manual", "automated", or "overridden"
1461
+ config_api_root: The Config API root URL (e.g., CLOUD_CONFIG_API_ROOT)
1462
+ initial_rollout_pct: Initial/step percentage for rollout progression (0-100).
1463
+ For automated rollouts, this is the percentage increment per step.
1464
+ Default is 25% if not specified.
1465
+ final_target_rollout_pct: Maximum percentage of actors to pin (0-100).
1466
+ The rollout will not exceed this percentage. Default is 50% if not specified.
1467
+ client_id: The Airbyte Cloud client ID (required if no bearer_token)
1468
+ client_secret: The Airbyte Cloud client secret (required if no bearer_token)
1469
+ bearer_token: Pre-existing bearer token (takes precedence over client credentials)
1470
+
1471
+ Returns:
1472
+ Dictionary containing the API response with the updated rollout data
1473
+
1474
+ Raises:
1475
+ PyAirbyteInputError: If the API request fails
1476
+ """
1477
+ access_token = _get_access_token(client_id, client_secret, bearer_token)
1478
+
1479
+ endpoint = f"{config_api_root}/connector_rollout/manual_start"
1480
+ payload: dict[str, Any] = {
1481
+ "docker_repository": docker_repository,
1482
+ "docker_image_tag": docker_image_tag,
1483
+ "actor_definition_id": actor_definition_id,
1484
+ "updated_by": updated_by,
1485
+ "rollout_strategy": rollout_strategy,
1486
+ }
1487
+
1488
+ if initial_rollout_pct is not None:
1489
+ payload["initial_rollout_pct"] = initial_rollout_pct
1490
+ if final_target_rollout_pct is not None:
1491
+ payload["final_target_rollout_pct"] = final_target_rollout_pct
1492
+
1493
+ response = requests.post(
1494
+ endpoint,
1495
+ json=payload,
1496
+ headers={
1497
+ "Authorization": f"Bearer {access_token}",
1498
+ "User-Agent": ops_constants.USER_AGENT,
1499
+ "Content-Type": "application/json",
1500
+ },
1501
+ timeout=60,
1502
+ )
1503
+
1504
+ if response.status_code == 404:
1505
+ raise PyAirbyteInputError(
1506
+ message=f"Rollout not found for {docker_repository}:{docker_image_tag}",
1507
+ context={
1508
+ "docker_repository": docker_repository,
1509
+ "docker_image_tag": docker_image_tag,
1510
+ "actor_definition_id": actor_definition_id,
1511
+ "endpoint": endpoint,
1512
+ "status_code": response.status_code,
1513
+ "response": response.text,
1514
+ },
1515
+ )
1516
+
1517
+ if response.status_code == 422:
1518
+ raise PyAirbyteInputError(
1519
+ message=f"Invalid input for starting rollout: {response.text}",
1520
+ context={
1521
+ "docker_repository": docker_repository,
1522
+ "docker_image_tag": docker_image_tag,
1523
+ "actor_definition_id": actor_definition_id,
1524
+ "rollout_strategy": rollout_strategy,
1525
+ "endpoint": endpoint,
1526
+ "status_code": response.status_code,
1527
+ "response": response.text,
1528
+ },
1529
+ )
1530
+
1531
+ if response.status_code != 200:
1532
+ raise PyAirbyteInputError(
1533
+ message=f"Failed to start connector rollout: {response.status_code} {response.text}",
1534
+ context={
1535
+ "docker_repository": docker_repository,
1536
+ "docker_image_tag": docker_image_tag,
1537
+ "actor_definition_id": actor_definition_id,
1538
+ "rollout_strategy": rollout_strategy,
1539
+ "endpoint": endpoint,
1540
+ "status_code": response.status_code,
1541
+ "response": response.text,
1542
+ },
1543
+ )
1544
+
1545
+ return response.json()
1546
+
1547
+
1548
+ def progress_connector_rollout(
1549
+ docker_repository: str,
1550
+ docker_image_tag: str,
1551
+ actor_definition_id: str,
1552
+ rollout_id: str,
1553
+ updated_by: str,
1554
+ config_api_root: str,
1555
+ target_percentage: int | None = None,
1556
+ actor_ids: list[str] | None = None,
1557
+ client_id: str | None = None,
1558
+ client_secret: str | None = None,
1559
+ bearer_token: str | None = None,
1560
+ ) -> dict[str, Any]:
1561
+ """Progress a connector rollout by pinning actors to the RC version.
1562
+
1563
+ This function calls the platform API to progress a connector rollout,
1564
+ either by specifying a target percentage or specific actor IDs to pin.
1565
+
1566
+ Args:
1567
+ docker_repository: The docker repository (e.g., "airbyte/source-github")
1568
+ docker_image_tag: The docker image tag (e.g., "1.2.0-rc.2")
1569
+ actor_definition_id: The actor definition ID (UUID)
1570
+ rollout_id: The rollout ID (UUID)
1571
+ updated_by: The user ID performing the operation (UUID)
1572
+ config_api_root: The Config API root URL (e.g., CLOUD_CONFIG_API_ROOT)
1573
+ target_percentage: Target percentage of actors to pin (1-100)
1574
+ actor_ids: Specific actor IDs to pin (alternative to target_percentage)
1575
+ client_id: The Airbyte Cloud client ID (required if no bearer_token)
1576
+ client_secret: The Airbyte Cloud client secret (required if no bearer_token)
1577
+ bearer_token: Pre-existing bearer token (takes precedence over client credentials)
1578
+
1579
+ Returns:
1580
+ Dictionary containing the API response with the updated rollout data
1581
+
1582
+ Raises:
1583
+ PyAirbyteInputError: If the API request fails
1584
+ """
1585
+ access_token = _get_access_token(client_id, client_secret, bearer_token)
1586
+
1587
+ endpoint = f"{config_api_root}/connector_rollout/manual_rollout"
1588
+ payload: dict[str, Any] = {
1589
+ "docker_repository": docker_repository,
1590
+ "docker_image_tag": docker_image_tag,
1591
+ "actor_definition_id": actor_definition_id,
1592
+ "id": rollout_id,
1593
+ "updated_by": updated_by,
1594
+ }
1595
+
1596
+ if target_percentage is not None:
1597
+ payload["target_percentage"] = target_percentage
1598
+ if actor_ids is not None:
1599
+ payload["actor_ids"] = actor_ids
1600
+
1601
+ response = requests.post(
1602
+ endpoint,
1603
+ json=payload,
1604
+ headers={
1605
+ "Authorization": f"Bearer {access_token}",
1606
+ "User-Agent": ops_constants.USER_AGENT,
1607
+ "Content-Type": "application/json",
1608
+ },
1609
+ timeout=60,
1610
+ )
1611
+
1612
+ if response.status_code == 404:
1613
+ raise PyAirbyteInputError(
1614
+ message=f"Rollout not found: {rollout_id}",
1615
+ context={
1616
+ "rollout_id": rollout_id,
1617
+ "docker_repository": docker_repository,
1618
+ "docker_image_tag": docker_image_tag,
1619
+ "endpoint": endpoint,
1620
+ "status_code": response.status_code,
1621
+ "response": response.text,
1622
+ },
1623
+ )
1624
+
1625
+ if response.status_code == 422:
1626
+ raise PyAirbyteInputError(
1627
+ message=f"Invalid input for rollout progression: {response.text}",
1628
+ context={
1629
+ "rollout_id": rollout_id,
1630
+ "docker_repository": docker_repository,
1631
+ "docker_image_tag": docker_image_tag,
1632
+ "target_percentage": target_percentage,
1633
+ "actor_ids": actor_ids,
1634
+ "endpoint": endpoint,
1635
+ "status_code": response.status_code,
1636
+ "response": response.text,
1637
+ },
1638
+ )
1639
+
1640
+ if response.status_code != 200:
1641
+ raise PyAirbyteInputError(
1642
+ message=f"Failed to progress connector rollout: {response.status_code} {response.text}",
1643
+ context={
1644
+ "rollout_id": rollout_id,
1645
+ "docker_repository": docker_repository,
1646
+ "docker_image_tag": docker_image_tag,
1647
+ "target_percentage": target_percentage,
1648
+ "actor_ids": actor_ids,
1649
+ "endpoint": endpoint,
1650
+ "status_code": response.status_code,
1651
+ "response": response.text,
1652
+ },
1653
+ )
1654
+
1655
+ return response.json()
1656
+
1657
+
1658
+ def finalize_connector_rollout(
1659
+ docker_repository: str,
1660
+ docker_image_tag: str,
1661
+ actor_definition_id: str,
1662
+ rollout_id: str,
1663
+ updated_by: str,
1664
+ state: Literal["succeeded", "failed_rolled_back", "canceled"],
1665
+ config_api_root: str,
1666
+ client_id: str | None = None,
1667
+ client_secret: str | None = None,
1668
+ bearer_token: str | None = None,
1669
+ error_msg: str | None = None,
1670
+ failed_reason: str | None = None,
1671
+ retain_pins_on_cancellation: bool | None = None,
1672
+ ) -> dict[str, Any]:
1673
+ """Finalize a connector rollout by promoting, rolling back, or canceling.
1674
+
1675
+ This function calls the platform API to finalize a connector rollout.
1676
+
1677
+ Args:
1678
+ docker_repository: The docker repository (e.g., "airbyte/source-github")
1679
+ docker_image_tag: The docker image tag (e.g., "1.2.0-rc.2")
1680
+ actor_definition_id: The actor definition ID (UUID)
1681
+ rollout_id: The rollout ID (UUID)
1682
+ updated_by: The user ID performing the operation (UUID)
1683
+ state: The final state - "succeeded" (promote), "failed_rolled_back" (rollback),
1684
+ or "canceled" (cancel)
1685
+ config_api_root: The Config API root URL (e.g., CLOUD_CONFIG_API_ROOT)
1686
+ client_id: The Airbyte Cloud client ID (required if no bearer_token)
1687
+ client_secret: The Airbyte Cloud client secret (required if no bearer_token)
1688
+ bearer_token: Pre-existing bearer token (takes precedence over client credentials)
1689
+ error_msg: Optional error message (for failed/canceled states)
1690
+ failed_reason: Optional failure reason (for failed/canceled states)
1691
+ retain_pins_on_cancellation: If True, retain version pins when canceling
1692
+
1693
+ Returns:
1694
+ Dictionary containing the API response with status field
1695
+
1696
+ Raises:
1697
+ PyAirbyteInputError: If the API request fails
1698
+ """
1699
+ access_token = _get_access_token(client_id, client_secret, bearer_token)
1700
+
1701
+ endpoint = f"{config_api_root}/connector_rollout/manual_finalize"
1702
+ payload: dict[str, Any] = {
1703
+ "docker_repository": docker_repository,
1704
+ "docker_image_tag": docker_image_tag,
1705
+ "actor_definition_id": actor_definition_id,
1706
+ "id": rollout_id,
1707
+ "updated_by": updated_by,
1708
+ "state": state,
1709
+ }
1710
+
1711
+ if error_msg:
1712
+ payload["error_msg"] = error_msg
1713
+ if failed_reason:
1714
+ payload["failed_reason"] = failed_reason
1715
+ if retain_pins_on_cancellation is not None:
1716
+ payload["retain_pins_on_cancellation"] = retain_pins_on_cancellation
1717
+
1718
+ response = requests.post(
1719
+ endpoint,
1720
+ json=payload,
1721
+ headers={
1722
+ "Authorization": f"Bearer {access_token}",
1723
+ "User-Agent": ops_constants.USER_AGENT,
1724
+ "Content-Type": "application/json",
1725
+ },
1726
+ timeout=60,
1727
+ )
1728
+
1729
+ if response.status_code == 404:
1730
+ raise PyAirbyteInputError(
1731
+ message=f"Rollout not found: {rollout_id}",
1732
+ context={
1733
+ "rollout_id": rollout_id,
1734
+ "docker_repository": docker_repository,
1735
+ "docker_image_tag": docker_image_tag,
1736
+ "endpoint": endpoint,
1737
+ "status_code": response.status_code,
1738
+ "response": response.text,
1739
+ },
1740
+ )
1741
+
1742
+ if response.status_code == 422:
1743
+ raise PyAirbyteInputError(
1744
+ message=f"Invalid input for rollout finalization: {response.text}",
1745
+ context={
1746
+ "rollout_id": rollout_id,
1747
+ "docker_repository": docker_repository,
1748
+ "docker_image_tag": docker_image_tag,
1749
+ "state": state,
1750
+ "endpoint": endpoint,
1751
+ "status_code": response.status_code,
1752
+ "response": response.text,
1753
+ },
1754
+ )
1755
+
1756
+ if response.status_code != 200:
1757
+ raise PyAirbyteInputError(
1758
+ message=f"Failed to finalize connector rollout: {response.status_code} {response.text}",
1759
+ context={
1760
+ "rollout_id": rollout_id,
1761
+ "docker_repository": docker_repository,
1762
+ "docker_image_tag": docker_image_tag,
1763
+ "state": state,
1764
+ "endpoint": endpoint,
1765
+ "status_code": response.status_code,
1766
+ "response": response.text,
1767
+ },
1768
+ )
1769
+
1770
+ return response.json()
1771
+
1772
+
1773
+ def get_actor_sync_info(
1774
+ rollout_id: str,
1775
+ config_api_root: str,
1776
+ client_id: str | None = None,
1777
+ client_secret: str | None = None,
1778
+ bearer_token: str | None = None,
1779
+ ) -> dict[str, Any]:
1780
+ """Get actor sync info for a connector rollout.
1781
+
1782
+ This function calls the platform API to get sync statistics for actors
1783
+ participating in a rollout. Unlike the SQL-based approach, this endpoint
1784
+ filters sync stats to only include syncs that actually used the RC version
1785
+ associated with the rollout.
1786
+
1787
+ Args:
1788
+ rollout_id: The rollout ID (UUID)
1789
+ config_api_root: The Config API root URL (e.g., CLOUD_CONFIG_API_ROOT)
1790
+ client_id: The Airbyte Cloud client ID (required if no bearer_token)
1791
+ client_secret: The Airbyte Cloud client secret (required if no bearer_token)
1792
+ bearer_token: Pre-existing bearer token (takes precedence over client credentials)
1793
+
1794
+ Returns:
1795
+ Dictionary containing:
1796
+ - data.actorSelectionInfo: Info about actor selection (numActors, numPinnedToConnectorRollout, etc.)
1797
+ - data.syncs: Dict mapping actor_id to sync stats (numConnections, numSucceeded, numFailed)
1798
+
1799
+ Raises:
1800
+ PyAirbyteInputError: If the API request fails or rollout not found
1801
+ """
1802
+ access_token = _get_access_token(client_id, client_secret, bearer_token)
1803
+
1804
+ endpoint = f"{config_api_root}/connector_rollout/get_actor_sync_info"
1805
+ payload = {"id": rollout_id}
1806
+
1807
+ response = requests.post(
1808
+ endpoint,
1809
+ json=payload,
1810
+ headers={
1811
+ "Authorization": f"Bearer {access_token}",
1812
+ "User-Agent": ops_constants.USER_AGENT,
1813
+ "Content-Type": "application/json",
1814
+ },
1815
+ timeout=60,
1816
+ )
1817
+
1818
+ if response.status_code == 404:
1819
+ raise PyAirbyteInputError(
1820
+ message=f"Rollout not found: {rollout_id}",
1821
+ context={
1822
+ "rollout_id": rollout_id,
1823
+ "endpoint": endpoint,
1824
+ "status_code": response.status_code,
1825
+ "response": response.text,
1826
+ },
1827
+ )
1828
+
1829
+ if response.status_code != 200:
1830
+ raise PyAirbyteInputError(
1831
+ message=f"Failed to get actor sync info: {response.status_code} {response.text}",
1832
+ context={
1833
+ "rollout_id": rollout_id,
1834
+ "endpoint": endpoint,
1835
+ "status_code": response.status_code,
1836
+ "response": response.text,
1837
+ },
1838
+ )
1839
+
1840
+ return response.json()
@@ -127,3 +127,102 @@ class OrganizationVersionOverrideResult(BaseModel):
127
127
  if self.success:
128
128
  return f"✓ {self.message}"
129
129
  return f"✗ {self.message}"
130
+
131
+
132
+ class ConnectorRolloutStartResult(BaseModel):
133
+ """Result of a connector rollout start operation.
134
+
135
+ This model provides detailed information about the outcome of starting
136
+ a connector rollout workflow.
137
+ """
138
+
139
+ success: bool = Field(description="Whether the operation succeeded")
140
+ message: str = Field(description="Human-readable message describing the result")
141
+ docker_repository: str | None = Field(
142
+ default=None,
143
+ description="The docker repository (e.g., 'airbyte/source-github')",
144
+ )
145
+ docker_image_tag: str | None = Field(
146
+ default=None,
147
+ description="The docker image tag (e.g., '1.2.0-rc.2')",
148
+ )
149
+ actor_definition_id: str | None = Field(
150
+ default=None,
151
+ description="The actor definition ID (UUID)",
152
+ )
153
+ rollout_strategy: Literal["manual", "automated", "overridden"] | None = Field(
154
+ default=None,
155
+ description="The rollout strategy used",
156
+ )
157
+
158
+ def __str__(self) -> str:
159
+ """Return a string representation of the operation result."""
160
+ if self.success:
161
+ return f"OK {self.message}"
162
+ return f"FAILED {self.message}"
163
+
164
+
165
+ class ConnectorRolloutProgressResult(BaseModel):
166
+ """Result of a connector rollout progress operation.
167
+
168
+ This model provides detailed information about the outcome of progressing
169
+ a connector rollout (pinning actors to the RC version).
170
+ """
171
+
172
+ success: bool = Field(description="Whether the operation succeeded")
173
+ message: str = Field(description="Human-readable message describing the result")
174
+ rollout_id: str | None = Field(
175
+ default=None,
176
+ description="The rollout ID that was progressed",
177
+ )
178
+ docker_repository: str | None = Field(
179
+ default=None,
180
+ description="The docker repository (e.g., 'airbyte/source-github')",
181
+ )
182
+ docker_image_tag: str | None = Field(
183
+ default=None,
184
+ description="The docker image tag (e.g., '1.2.0-rc.2')",
185
+ )
186
+ target_percentage: int | None = Field(
187
+ default=None,
188
+ description="The target percentage of actors to pin",
189
+ )
190
+
191
+ def __str__(self) -> str:
192
+ """Return a string representation of the operation result."""
193
+ if self.success:
194
+ return f"OK {self.message}"
195
+ return f"FAILED {self.message}"
196
+
197
+
198
+ class ConnectorRolloutFinalizeResult(BaseModel):
199
+ """Result of a connector rollout finalization operation.
200
+
201
+ This model provides detailed information about the outcome of finalizing
202
+ a connector rollout (promote, rollback, or cancel).
203
+ """
204
+
205
+ success: bool = Field(description="Whether the operation succeeded")
206
+ message: str = Field(description="Human-readable message describing the result")
207
+ rollout_id: str | None = Field(
208
+ default=None,
209
+ description="The rollout ID that was finalized",
210
+ )
211
+ docker_repository: str | None = Field(
212
+ default=None,
213
+ description="The docker repository (e.g., 'airbyte/source-github')",
214
+ )
215
+ docker_image_tag: str | None = Field(
216
+ default=None,
217
+ description="The docker image tag (e.g., '1.2.0-rc.2')",
218
+ )
219
+ state: Literal["succeeded", "failed_rolled_back", "canceled"] | None = Field(
220
+ default=None,
221
+ description="The final state of the rollout",
222
+ )
223
+
224
+ def __str__(self) -> str:
225
+ """Return a string representation of the operation result."""
226
+ if self.success:
227
+ return f"OK {self.message}"
228
+ return f"FAILED {self.message}"