qontract-reconcile 0.10.2.dev280__py3-none-any.whl → 0.10.2.dev282__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.
Files changed (72) hide show
  1. {qontract_reconcile-0.10.2.dev280.dist-info → qontract_reconcile-0.10.2.dev282.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.2.dev280.dist-info → qontract_reconcile-0.10.2.dev282.dist-info}/RECORD +72 -72
  3. reconcile/acs_policies.py +7 -7
  4. reconcile/aus/base.py +1 -1
  5. reconcile/aus/models.py +4 -5
  6. reconcile/aus/version_gate_approver.py +4 -1
  7. reconcile/aws_account_manager/merge_request_manager.py +5 -3
  8. reconcile/aws_ami_cleanup/integration.py +5 -8
  9. reconcile/aws_cloudwatch_log_retention/integration.py +6 -6
  10. reconcile/database_access_manager.py +1 -1
  11. reconcile/deadmanssnitch.py +1 -1
  12. reconcile/dynatrace_token_provider/ocm.py +10 -11
  13. reconcile/fleet_labeler/dependencies.py +7 -3
  14. reconcile/fleet_labeler/ocm.py +6 -4
  15. reconcile/gitlab_housekeeping.py +2 -2
  16. reconcile/gitlab_permissions.py +1 -1
  17. reconcile/jenkins_webhooks.py +8 -4
  18. reconcile/jenkins_worker_fleets.py +2 -2
  19. reconcile/ocm_internal_notifications/integration.py +6 -4
  20. reconcile/ocm_labels/integration.py +7 -7
  21. reconcile/ocm_upgrade_scheduler_org_updater.py +2 -4
  22. reconcile/openshift_cluster_bots.py +1 -1
  23. reconcile/resource_scraper.py +1 -1
  24. reconcile/saas_auto_promotions_manager/integration.py +7 -3
  25. reconcile/saas_auto_promotions_manager/s3_exporter.py +6 -3
  26. reconcile/saas_file_validator.py +1 -2
  27. reconcile/skupper_network/models.py +4 -2
  28. reconcile/statuspage/atlassian.py +1 -1
  29. reconcile/statuspage/page.py +1 -1
  30. reconcile/terraform_cloudflare_resources.py +1 -1
  31. reconcile/terraform_resources.py +1 -1
  32. reconcile/terraform_tgw_attachments.py +3 -3
  33. reconcile/terraform_users.py +1 -1
  34. reconcile/utils/aws_api.py +12 -30
  35. reconcile/utils/aws_api_typed/account.py +4 -4
  36. reconcile/utils/aws_api_typed/api.py +4 -2
  37. reconcile/utils/aws_api_typed/dynamodb.py +2 -2
  38. reconcile/utils/aws_api_typed/iam.py +2 -2
  39. reconcile/utils/aws_api_typed/organization.py +10 -7
  40. reconcile/utils/aws_api_typed/s3.py +2 -3
  41. reconcile/utils/aws_api_typed/service_quotas.py +4 -1
  42. reconcile/utils/aws_api_typed/sts.py +2 -2
  43. reconcile/utils/aws_api_typed/support.py +2 -2
  44. reconcile/utils/dynatrace/client.py +4 -1
  45. reconcile/utils/expiration.py +1 -1
  46. reconcile/utils/external_resource_spec.py +4 -2
  47. reconcile/utils/gitlab_api.py +4 -4
  48. reconcile/utils/glitchtip/models.py +4 -2
  49. reconcile/utils/jira_client.py +4 -4
  50. reconcile/utils/mr/base.py +1 -1
  51. reconcile/utils/oc_connection_parameters.py +4 -1
  52. reconcile/utils/ocm/base.py +4 -1
  53. reconcile/utils/ocm/ocm.py +6 -5
  54. reconcile/utils/ocm/products.py +7 -4
  55. reconcile/utils/saasherder/interfaces.py +5 -2
  56. reconcile/utils/slack_api.py +4 -5
  57. reconcile/utils/state.py +9 -9
  58. reconcile/utils/terraform_client.py +1 -1
  59. reconcile/utils/terrascript_aws_client.py +3 -3
  60. reconcile/utils/vaultsecretref.py +1 -1
  61. reconcile/utils/vcs.py +14 -10
  62. reconcile/vault_replication.py +1 -1
  63. reconcile/vpc_peerings_validator.py +2 -4
  64. tools/app_interface_reporter.py +1 -2
  65. tools/cli_commands/erv2.py +7 -4
  66. tools/cli_commands/gpg_encrypt.py +4 -1
  67. tools/qontract_cli.py +10 -8
  68. tools/saas_metrics_exporter/commit_distance/channel.py +6 -3
  69. tools/saas_metrics_exporter/main.py +4 -1
  70. tools/saas_promotion_state/saas_promotion_state.py +4 -1
  71. {qontract_reconcile-0.10.2.dev280.dist-info → qontract_reconcile-0.10.2.dev282.dist-info}/WHEEL +0 -0
  72. {qontract_reconcile-0.10.2.dev280.dist-info → qontract_reconcile-0.10.2.dev282.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  from pydantic import BaseModel, Field
@@ -6,7 +8,8 @@ if TYPE_CHECKING:
6
8
  from mypy_boto3_service_quotas import ServiceQuotasClient
7
9
  from mypy_boto3_service_quotas.literals import RequestStatusType
8
10
  else:
9
- ServiceQuotasClient = RequestStatusType = object
11
+ # pydantic needs these types to be defined during runtime
12
+ RequestStatusType = str
10
13
 
11
14
 
12
15
  class AWSRequestedServiceQuotaChange(BaseModel):
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from datetime import datetime
2
4
  from typing import TYPE_CHECKING
3
5
 
@@ -5,8 +7,6 @@ from pydantic import BaseModel, Field
5
7
 
6
8
  if TYPE_CHECKING:
7
9
  from mypy_boto3_sts import STSClient
8
- else:
9
- STSClient = object
10
10
 
11
11
 
12
12
  class AWSCredentials(BaseModel):
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from enum import Enum
2
4
  from typing import TYPE_CHECKING, Literal
3
5
 
@@ -5,8 +7,6 @@ from pydantic import BaseModel, Field
5
7
 
6
8
  if TYPE_CHECKING:
7
9
  from mypy_boto3_support import SupportClient
8
- else:
9
- SupportClient = object
10
10
 
11
11
 
12
12
  class AWSCase(BaseModel):
@@ -1,11 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from dynatrace import Dynatrace
6
6
  from dynatrace.environment_v2.tokens_api import ApiTokenUpdate
7
7
  from pydantic import BaseModel
8
8
 
9
+ if TYPE_CHECKING:
10
+ from collections.abc import Iterable
11
+
9
12
 
10
13
  class DynatraceTokenCreationError(Exception):
11
14
  pass
@@ -41,4 +41,4 @@ def filter(roles: DictsOrRoles | None) -> DictsOrRoles:
41
41
  f"{key} field is not formatted as YYYY-MM-DD, currently set as {expiration_date}"
42
42
  ) from None
43
43
 
44
- return cast(DictsOrRoles, filtered)
44
+ return cast("DictsOrRoles", filtered)
@@ -60,7 +60,7 @@ class GenericSecretOutputFormatConfig(OutputFormatProcessor):
60
60
  rendered_data = process_jinja2_template(self.data, dict(vars))
61
61
  parsed_data = yaml.safe_load(rendered_data)
62
62
  self.validate_k8s_secret_data(parsed_data)
63
- return cast(dict[str, str], parsed_data)
63
+ return cast("dict[str, str]", parsed_data)
64
64
  return dict(vars)
65
65
 
66
66
 
@@ -176,7 +176,9 @@ class ExternalResourceSpec:
176
176
 
177
177
  def _output_format(self) -> OutputFormat:
178
178
  if self.resource.get("output_format") is not None:
179
- return OutputFormat(**cast(dict[str, Any], self.resource["output_format"]))
179
+ return OutputFormat(
180
+ **cast("dict[str, Any]", self.resource["output_format"])
181
+ )
180
182
  return OutputFormat(provider="generic-secret")
181
183
 
182
184
 
@@ -425,7 +425,7 @@ class GitLabApi:
425
425
  merge_request: ProjectMergeRequest,
426
426
  ) -> list[str]:
427
427
  result = merge_request.changes()
428
- changes = cast(dict, result)["changes"]
428
+ changes = cast("dict", result)["changes"]
429
429
  changed_paths = set()
430
430
  for change in changes:
431
431
  old_path = change["old_path"]
@@ -562,9 +562,9 @@ class GitLabApi:
562
562
  manager: ProjectMergeRequestManager | ProjectIssueManager
563
563
  match item:
564
564
  case ProjectMergeRequest():
565
- manager = cast(ProjectMergeRequestManager, item.manager)
565
+ manager = cast("ProjectMergeRequestManager", item.manager)
566
566
  case ProjectIssue():
567
- manager = cast(ProjectIssueManager, item.manager)
567
+ manager = cast("ProjectIssueManager", item.manager)
568
568
  case _:
569
569
  raise ValueError("item must be a ProjectMergeRequest or ProjectIssue")
570
570
  item_id = item.get_id()
@@ -668,7 +668,7 @@ class GitLabApi:
668
668
  :return: list of tree objects
669
669
  """
670
670
  return cast(
671
- list[dict],
671
+ "list[dict]",
672
672
  self.project.repository_tree(
673
673
  ref=ref,
674
674
  recursive=recursive,
@@ -1,10 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
- from collections.abc import MutableMapping
5
4
  from datetime import datetime
6
5
  from enum import Enum
7
- from typing import Any
6
+ from typing import TYPE_CHECKING, Any
8
7
 
9
8
  from pydantic import (
10
9
  BaseModel,
@@ -13,6 +12,9 @@ from pydantic import (
13
12
  validator,
14
13
  )
15
14
 
15
+ if TYPE_CHECKING:
16
+ from collections.abc import MutableMapping
17
+
16
18
 
17
19
  def slugify(value: str) -> str:
18
20
  """Convert value into a slug.
@@ -2,11 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import functools
4
4
  import logging
5
- from collections.abc import (
6
- Iterable,
7
- Mapping,
8
- )
9
5
  from typing import (
6
+ TYPE_CHECKING,
10
7
  Any,
11
8
  Protocol,
12
9
  )
@@ -22,6 +19,9 @@ from pydantic import BaseModel
22
19
 
23
20
  from reconcile.utils.secret_reader import SecretReader
24
21
 
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Iterable, Mapping
24
+
25
25
 
26
26
  class JiraWatcherSettings(Protocol):
27
27
  read_timeout: int
@@ -225,7 +225,7 @@ class MergeRequestBase(ABC):
225
225
 
226
226
  def diffs(self, gitlab_cli: GitLabApi) -> Any:
227
227
  return cast(
228
- dict,
228
+ "dict",
229
229
  gitlab_cli.project.repository_compare(
230
230
  from_=gitlab_cli.main_branch, to=self.branch
231
231
  ),
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from collections.abc import Iterable
5
4
  from dataclasses import dataclass
6
5
  from typing import (
6
+ TYPE_CHECKING,
7
7
  Protocol,
8
8
  runtime_checkable,
9
9
  )
@@ -16,6 +16,9 @@ from reconcile.utils.secret_reader import (
16
16
  SecretReaderBase,
17
17
  )
18
18
 
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Iterable
21
+
19
22
 
20
23
  class OCConnectionError(Exception):
21
24
  pass
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
4
3
  from datetime import datetime
5
4
  from enum import Enum, StrEnum
6
5
  from typing import (
6
+ TYPE_CHECKING,
7
7
  TypeVar,
8
8
  )
9
9
 
@@ -15,6 +15,9 @@ from pydantic import (
15
15
  from reconcile.utils.aws_helper import get_account_uid_from_arn, get_role_name_from_arn
16
16
  from reconcile.utils.semver_helper import parse_semver
17
17
 
18
+ if TYPE_CHECKING:
19
+ from collections.abc import Iterable
20
+
18
21
  LabelSetTypeVar = TypeVar("LabelSetTypeVar", bound=BaseModel)
19
22
  ACTIVE_SUBSCRIPTION_STATES = {"Active", "Reserved"}
20
23
  CAPABILITY_MANAGE_CLUSTER_ADMIN = "capability.cluster.manage_cluster_admin"
@@ -1,16 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import functools
4
- from collections.abc import Mapping
5
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
6
5
 
7
6
  from sretoolbox.utils import retry
8
7
 
9
8
  import reconcile.utils.aws_helper as awsh
10
9
  from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
11
- from reconcile.ocm.types import (
12
- OCMSpec,
13
- )
14
10
  from reconcile.utils.ocm.clusters import get_node_pools
15
11
  from reconcile.utils.ocm.products import (
16
12
  OCMProduct,
@@ -24,6 +20,11 @@ from reconcile.utils.ocm_base_client import (
24
20
  )
25
21
  from reconcile.utils.secret_reader import SecretReader
26
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Mapping
25
+
26
+ from reconcile.ocm.types import OCMSpec
27
+
27
28
  STATUS_READY = "ready"
28
29
  STATUS_FAILED = "failed"
29
30
  STATUS_DELETING = "deleting"
@@ -4,8 +4,7 @@ import logging
4
4
  import random
5
5
  import string
6
6
  from abc import abstractmethod
7
- from collections.abc import Mapping
8
- from typing import Any
7
+ from typing import TYPE_CHECKING, Any
9
8
 
10
9
  from pydantic import BaseModel
11
10
 
@@ -22,9 +21,13 @@ from reconcile.ocm.types import (
22
21
  )
23
22
  from reconcile.utils.exceptions import ParameterError
24
23
  from reconcile.utils.ocm.clusters import get_provisioning_shard_id
25
- from reconcile.utils.ocm_base_client import OCMBaseClient
26
24
  from reconcile.utils.rosa.rosa_cli import RosaCliError
27
- from reconcile.utils.rosa.session import RosaSessionBuilder
25
+
26
+ if TYPE_CHECKING:
27
+ from collections.abc import Mapping
28
+
29
+ from reconcile.utils.ocm_base_client import OCMBaseClient
30
+ from reconcile.utils.rosa.session import RosaSessionBuilder
28
31
 
29
32
  CS_API_BASE = "/api/clusters_mgmt"
30
33
 
@@ -3,14 +3,17 @@ from __future__ import annotations
3
3
 
4
4
  from collections.abc import Mapping, Sequence, Set
5
5
  from typing import (
6
+ TYPE_CHECKING,
6
7
  Any,
7
8
  Protocol,
8
9
  runtime_checkable,
9
10
  )
10
11
 
11
- from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
12
12
  from reconcile.utils import oc_connection_parameters
13
- from reconcile.utils.secret_reader import HasSecret
13
+
14
+ if TYPE_CHECKING:
15
+ from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
16
+ from reconcile.utils.secret_reader import HasSecret
14
17
 
15
18
 
16
19
  @runtime_checkable
@@ -2,12 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import logging
5
- from collections.abc import (
6
- Iterable,
7
- Mapping,
8
- Sequence,
9
- )
10
5
  from typing import (
6
+ TYPE_CHECKING,
11
7
  Any,
12
8
  Protocol,
13
9
  )
@@ -24,6 +20,9 @@ from slack_sdk.http_retry import (
24
20
 
25
21
  from reconcile.utils.metrics import slack_request
26
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Iterable, Mapping, Sequence
25
+
27
26
  MAX_RETRIES = 5
28
27
  TIMEOUT = 30
29
28
 
reconcile/utils/state.py CHANGED
@@ -1,9 +1,10 @@
1
+ from __future__ import annotations
2
+
1
3
  import contextlib
2
4
  import json
3
5
  import logging
4
6
  import os
5
7
  from abc import abstractmethod
6
- from collections.abc import Callable, Generator, Mapping
7
8
  from dataclasses import dataclass, field
8
9
  from typing import (
9
10
  TYPE_CHECKING,
@@ -13,12 +14,6 @@ from typing import (
13
14
 
14
15
  import boto3
15
16
  from botocore.errorfactory import ClientError
16
-
17
- if TYPE_CHECKING:
18
- from mypy_boto3_s3 import S3Client
19
- else:
20
- S3Client = object
21
-
22
17
  from pydantic import BaseModel
23
18
 
24
19
  from reconcile.gql_definitions.common.app_interface_state_settings import (
@@ -38,6 +33,11 @@ from reconcile.utils.secret_reader import (
38
33
  create_secret_reader,
39
34
  )
40
35
 
36
+ if TYPE_CHECKING:
37
+ from collections.abc import Callable, Generator, Mapping
38
+
39
+ from mypy_boto3_s3 import S3Client
40
+
41
41
 
42
42
  class StateInaccessibleError(Exception):
43
43
  pass
@@ -46,7 +46,7 @@ class StateInaccessibleError(Exception):
46
46
  def init_state(
47
47
  integration: str,
48
48
  secret_reader: SecretReaderBase | None = None,
49
- ) -> "State":
49
+ ) -> State:
50
50
  if not secret_reader:
51
51
  vault_settings = get_app_interface_vault_settings()
52
52
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
@@ -418,7 +418,7 @@ class State:
418
418
  @contextlib.contextmanager
419
419
  def transaction(
420
420
  self, key: str, value: Any = None
421
- ) -> Generator["TransactionStateObj", None, None]:
421
+ ) -> Generator[TransactionStateObj, None, None]:
422
422
  """Get a context manager to set the key in the state if no exception occurs.
423
423
 
424
424
  You can set the value either via the value parameter or by setting the value attribute of the returned object.
@@ -744,7 +744,7 @@ class TerraformClient:
744
744
  value = allowed_modifications.get(argument)
745
745
  if (
746
746
  value in pending_modified_values
747
- and cast(dict[str, str], pending_modified_values)[value]
747
+ and cast("dict[str, str]", pending_modified_values)[value]
748
748
  == after[argument]
749
749
  ):
750
750
  changed_values.append(argument)
@@ -1092,7 +1092,7 @@ class TerrascriptClient:
1092
1092
  )
1093
1093
  if records_from_vault:
1094
1094
  allowed_vault_secret_paths = (
1095
- cast(set[str], zone.get("allowed_vault_secret_paths")) or set()
1095
+ cast("set[str]", zone.get("allowed_vault_secret_paths")) or set()
1096
1096
  )
1097
1097
  vault_values: list[str] = []
1098
1098
  for rec in records_from_vault:
@@ -5754,7 +5754,7 @@ class TerrascriptClient:
5754
5754
  tags.update(json.loads(extra_tags))
5755
5755
  # common_values is untyped, so casting is necessary
5756
5756
  region = cast(
5757
- str, common_values.get("region") or self.default_regions.get(account)
5757
+ "str", common_values.get("region") or self.default_regions.get(account)
5758
5758
  )
5759
5759
 
5760
5760
  template_values = {
@@ -5770,7 +5770,7 @@ class TerrascriptClient:
5770
5770
  }
5771
5771
 
5772
5772
  # common_values is untyped, so casting is necessary
5773
- image = cast(list[dict[str, Any]], common_values.get("image"))
5773
+ image = cast("list[dict[str, Any]]", common_values.get("image"))
5774
5774
  image_id = self.get_asg_image_id(filters=image, account=account, region=region)
5775
5775
  if not image_id:
5776
5776
  if self._use_previous_image_id(image):
@@ -27,7 +27,7 @@ class VaultSecretRef:
27
27
  return secret_content.get(self.field, default)
28
28
 
29
29
  def _resolve_secret(self) -> dict[str, str]:
30
- vault_client = cast(_VaultClient, VaultClient())
30
+ vault_client = cast("_VaultClient", VaultClient())
31
31
  if self.field == VaultSecretRef._ALL_FIELDS:
32
32
  return vault_client.read_all(self.__dict__)
33
33
  field_value = vault_client.read(self.__dict__)
reconcile/utils/vcs.py CHANGED
@@ -2,28 +2,32 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  import re
5
- from collections.abc import Iterable
6
5
  from dataclasses import dataclass
7
6
  from datetime import datetime
8
7
  from enum import Enum
9
- from typing import Literal
8
+ from typing import TYPE_CHECKING, Literal
10
9
  from urllib.parse import urlparse
11
10
 
12
11
  from gitlab.const import PipelineStatus
13
- from gitlab.v4.objects import ProjectMergeRequest
14
12
 
15
- from reconcile.typed_queries.github_orgs import GithubOrgV1
16
- from reconcile.typed_queries.gitlab_instances import GitlabInstanceV1
17
13
  from reconcile.utils.github_api import GithubRepositoryApi
18
14
  from reconcile.utils.gitlab_api import (
19
15
  GitLabApi,
20
16
  MRState,
21
17
  )
22
- from reconcile.utils.mr.base import MergeRequestBase
23
- from reconcile.utils.secret_reader import (
24
- HasSecret,
25
- SecretReaderBase,
26
- )
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Iterable
21
+
22
+ from gitlab.v4.objects import ProjectMergeRequest
23
+
24
+ from reconcile.typed_queries.github_orgs import GithubOrgV1
25
+ from reconcile.typed_queries.gitlab_instances import GitlabInstanceV1
26
+ from reconcile.utils.mr.base import MergeRequestBase
27
+ from reconcile.utils.secret_reader import (
28
+ HasSecret,
29
+ SecretReaderBase,
30
+ )
27
31
 
28
32
  GITHUB_BASE_URL = "https://github.com/"
29
33
 
@@ -294,7 +294,7 @@ def get_vault_credentials(
294
294
  """Returns a dictionary with the credentials used to authenticate with Vault,
295
295
  retrieved from the values present on AppInterface and comming from Vault itself."""
296
296
  vault_creds = {}
297
- vault = cast(_VaultClient, VaultClient())
297
+ vault = cast("_VaultClient", VaultClient())
298
298
 
299
299
  if not isinstance(
300
300
  vault_auth,
@@ -112,8 +112,7 @@ def validate_no_internal_to_public_peerings(
112
112
  }:
113
113
  continue
114
114
  connection = cast(
115
- ClusterPeeringConnectionClusterAccepterV1
116
- | ClusterPeeringConnectionClusterRequesterV1,
115
+ "ClusterPeeringConnectionClusterAccepterV1 | ClusterPeeringConnectionClusterRequesterV1",
117
116
  connection,
118
117
  )
119
118
  peer = connection.cluster
@@ -153,8 +152,7 @@ def validate_no_public_to_public_peerings(
153
152
  }:
154
153
  continue
155
154
  connection = cast(
156
- ClusterPeeringConnectionClusterAccepterV1
157
- | ClusterPeeringConnectionClusterRequesterV1,
155
+ "ClusterPeeringConnectionClusterAccepterV1 | ClusterPeeringConnectionClusterRequesterV1",
158
156
  connection,
159
157
  )
160
158
  peer = connection.cluster
@@ -29,7 +29,6 @@ from reconcile.cli import (
29
29
  )
30
30
  from reconcile.jenkins_job_builder import init_jjb
31
31
  from reconcile.utils.constants import DEFAULT_THREAD_POOL_SIZE
32
- from reconcile.utils.jjb_client import JJB
33
32
  from reconcile.utils.mr import CreateAppInterfaceReporter
34
33
  from reconcile.utils.runtime.environment import init_env
35
34
  from reconcile.utils.secret_reader import SecretReader
@@ -188,7 +187,7 @@ def get_apps_data(
188
187
  secret_reader = SecretReader(settings)
189
188
 
190
189
  apps = queries.get_apps()
191
- jjb: JJB = init_jjb(secret_reader)
190
+ jjb = init_jjb(secret_reader)
192
191
  jenkins_map = jenkins_base.get_jenkins_map()
193
192
  time_limit = date - relativedelta(months=month_delta)
194
193
  timestamp_limit = int(time_limit.replace(tzinfo=UTC).timestamp())
@@ -3,13 +3,11 @@ from __future__ import annotations
3
3
  import json
4
4
  import os
5
5
  import sys
6
- from collections.abc import Iterator
7
6
  from contextlib import contextmanager, suppress
8
7
  from difflib import get_close_matches
9
8
  from enum import Enum
10
- from pathlib import Path
11
9
  from subprocess import CalledProcessError, run
12
- from typing import Any, Protocol
10
+ from typing import TYPE_CHECKING, Any, Protocol
13
11
 
14
12
  from pydantic import BaseModel
15
13
  from rich import print as rich_print
@@ -37,7 +35,12 @@ from reconcile.typed_queries.external_resources import (
37
35
  )
38
36
  from reconcile.utils import gql
39
37
  from reconcile.utils.exceptions import FetchResourceError
40
- from reconcile.utils.secret_reader import SecretReaderBase
38
+
39
+ if TYPE_CHECKING:
40
+ from collections.abc import Iterator
41
+ from pathlib import Path
42
+
43
+ from reconcile.utils.secret_reader import SecretReaderBase
41
44
 
42
45
  UP = "\x1b[1A"
43
46
  CLEAR = "\x1b[2K"
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import json
4
- from collections.abc import Mapping
5
4
  from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  from reconcile import queries
8
8
  from reconcile.utils import (
@@ -12,6 +12,9 @@ from reconcile.utils import (
12
12
  from reconcile.utils.oc import OC_Map
13
13
  from reconcile.utils.secret_reader import SecretReader
14
14
 
15
+ if TYPE_CHECKING:
16
+ from collections.abc import Mapping
17
+
15
18
 
16
19
  @dataclass
17
20
  class GPGEncryptCommandData:
tools/qontract_cli.py CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
  # ruff: noqa: PLC0415 - `import` should be at the top-level of a file
3
3
 
4
+ from __future__ import annotations
5
+
4
6
  import base64
5
7
  import json
6
8
  import logging
@@ -10,7 +12,6 @@ import sys
10
12
  import tempfile
11
13
  import textwrap
12
14
  from collections import defaultdict
13
- from collections.abc import Callable, Iterable, Mapping
14
15
  from datetime import (
15
16
  UTC,
16
17
  datetime,
@@ -83,7 +84,6 @@ from reconcile.gql_definitions.common.app_interface_vault_settings import (
83
84
  AppInterfaceSettingsV1,
84
85
  )
85
86
  from reconcile.gql_definitions.common.clusters import ClusterSpecROSAV1
86
- from reconcile.gql_definitions.fragments.aus_organization import AUSOCMOrganization
87
87
  from reconcile.gql_definitions.glitchtip.glitchtip_instance import (
88
88
  query as glitchtip_instance_query,
89
89
  )
@@ -129,7 +129,6 @@ from reconcile.utils.early_exit_cache import (
129
129
  EarlyExitCache,
130
130
  )
131
131
  from reconcile.utils.environ import environ
132
- from reconcile.utils.external_resource_spec import ExternalResourceSpec
133
132
  from reconcile.utils.external_resources import (
134
133
  PROVIDER_AWS,
135
134
  get_external_resource_specs,
@@ -141,9 +140,7 @@ from reconcile.utils.gitlab_api import (
141
140
  MRStatus,
142
141
  )
143
142
  from reconcile.utils.glitchtip.client import GlitchtipClient
144
- from reconcile.utils.glitchtip.models import Project, ProjectStatistics
145
143
  from reconcile.utils.gql import GqlApiSingleton
146
- from reconcile.utils.jjb_client import JJB
147
144
  from reconcile.utils.keycloak import (
148
145
  KeycloakAPI,
149
146
  SSOClient,
@@ -197,9 +194,14 @@ from tools.sre_checkpoints import (
197
194
  )
198
195
 
199
196
  if TYPE_CHECKING:
197
+ from collections.abc import Callable, Iterable, Mapping
198
+
200
199
  from mypy_boto3_s3.type_defs import CopySourceTypeDef
201
- else:
202
- CopySourceTypeDef = object
200
+
201
+ from reconcile.gql_definitions.fragments.aus_organization import AUSOCMOrganization
202
+ from reconcile.utils.external_resource_spec import ExternalResourceSpec
203
+ from reconcile.utils.glitchtip.models import Project, ProjectStatistics
204
+ from reconcile.utils.jjb_client import JJB
203
205
 
204
206
 
205
207
  def output(function: Callable) -> Callable:
@@ -1489,7 +1491,7 @@ def copy_tfstate(
1489
1491
  session = aws.get_session(account["name"])
1490
1492
  s3_client = aws.get_session_client(session, "s3", region)
1491
1493
  copy_source = cast(
1492
- CopySourceTypeDef,
1494
+ "CopySourceTypeDef",
1493
1495
  {
1494
1496
  "Bucket": source_bucket,
1495
1497
  "Key": source_object_path,
@@ -1,10 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
4
3
  from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING
5
5
 
6
- from reconcile.typed_queries.saas_files import SaasFile
7
- from reconcile.utils.secret_reader import HasSecret
6
+ if TYPE_CHECKING:
7
+ from collections.abc import Iterable
8
+
9
+ from reconcile.typed_queries.saas_files import SaasFile
10
+ from reconcile.utils.secret_reader import HasSecret
8
11
 
9
12
 
10
13
  @dataclass
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Callable
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  import click
6
6
 
@@ -25,6 +25,9 @@ from tools.saas_metrics_exporter.commit_distance.commit_distance import (
25
25
  CommitDistanceFetcher,
26
26
  )
27
27
 
28
+ if TYPE_CHECKING:
29
+ from collections.abc import Callable
30
+
28
31
 
29
32
  class SaasMetricsExporter:
30
33
  """