Skip to content

Commit e33444a

Browse files
Merge pull request #210 from opsmill/develop
Release 1.4
2 parents 613ed53 + c067262 commit e33444a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1675
-1286
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang
1111

1212
<!-- towncrier release notes start -->
1313

14+
## [1.4.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.4.0) - 2025-01-03
15+
16+
### Changed
17+
18+
- The inclusion of properties for Attribute and Relationships by default has been disabled when querying nodes from Infrahub.
19+
it can be enabled by using the parameter `property` in `client.get|all|filters` method ([#191](https://github.com/opsmill/infrahub-sdk-python/issues/191))
20+
- Fix an issue with python-transform-unit-process failing to run ([#198](https://github.com/opsmill/infrahub-sdk-python/issues/198))
21+
- Add processing of nodes when no variable are passed into the command to run generators ([#176](https://github.com/opsmill/infrahub-sdk-python/issues/176))
22+
1423
## [1.3.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.3.0) - 2024-12-30
1524

1625
### Added

infrahub_sdk/_importer.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import importlib
44
import sys
55
from pathlib import Path
6-
from typing import TYPE_CHECKING, Optional
6+
from typing import TYPE_CHECKING
77

88
from .exceptions import ModuleImportError
99

@@ -13,9 +13,7 @@
1313
module_mtime_cache: dict[str, float] = {}
1414

1515

16-
def import_module(
17-
module_path: Path, import_root: Optional[str] = None, relative_path: Optional[str] = None
18-
) -> ModuleType:
16+
def import_module(module_path: Path, import_root: str | None = None, relative_path: str | None = None) -> ModuleType:
1917
"""Imports a python module.
2018
2119
Args:

infrahub_sdk/analyzer.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from typing import Any, Optional
1+
from __future__ import annotations
2+
3+
from typing import Any
24

35
from graphql import (
46
DocumentNode,
@@ -19,23 +21,23 @@ class GraphQLQueryVariable(BaseModel):
1921
name: str
2022
type: str
2123
required: bool = False
22-
default_value: Optional[Any] = None
24+
default_value: Any | None = None
2325

2426

2527
class GraphQLOperation(BaseModel):
26-
name: Optional[str] = None
28+
name: str | None = None
2729
operation_type: OperationType
2830

2931

3032
class GraphQLQueryAnalyzer:
31-
def __init__(self, query: str, schema: Optional[GraphQLSchema] = None):
33+
def __init__(self, query: str, schema: GraphQLSchema | None = None):
3234
self.query: str = query
33-
self.schema: Optional[GraphQLSchema] = schema
35+
self.schema: GraphQLSchema | None = schema
3436
self.document: DocumentNode = parse(self.query)
35-
self._fields: Optional[dict] = None
37+
self._fields: dict | None = None
3638

3739
@property
38-
def is_valid(self) -> tuple[bool, Optional[list[GraphQLError]]]:
40+
def is_valid(self) -> tuple[bool, list[GraphQLError] | None]:
3941
if self.schema is None:
4042
return False, [GraphQLError("Schema is not provided")]
4143

infrahub_sdk/batch.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
1+
from __future__ import annotations
2+
13
import asyncio
2-
from collections.abc import AsyncGenerator, Awaitable
4+
from collections.abc import AsyncGenerator, Awaitable, Generator
35
from concurrent.futures import ThreadPoolExecutor
46
from dataclasses import dataclass
5-
from typing import Any, Callable, Generator, Optional
7+
from typing import TYPE_CHECKING, Any, Callable
68

7-
from .node import InfrahubNode, InfrahubNodeSync
9+
if TYPE_CHECKING:
10+
from .node import InfrahubNode, InfrahubNodeSync
811

912

1013
@dataclass
1114
class BatchTask:
1215
task: Callable[[Any], Awaitable[Any]]
1316
args: tuple[Any, ...]
1417
kwargs: dict[str, Any]
15-
node: Optional[Any] = None
18+
node: Any | None = None
1619

1720

1821
@dataclass
1922
class BatchTaskSync:
2023
task: Callable[..., Any]
2124
args: tuple[Any, ...]
2225
kwargs: dict[str, Any]
23-
node: Optional[InfrahubNodeSync] = None
26+
node: InfrahubNodeSync | None = None
2427

25-
def execute(self, return_exceptions: bool = False) -> tuple[Optional[InfrahubNodeSync], Any]:
28+
def execute(self, return_exceptions: bool = False) -> tuple[InfrahubNodeSync | None, Any]:
2629
"""Executes the stored task."""
2730
result = None
2831
try:
@@ -37,7 +40,7 @@ def execute(self, return_exceptions: bool = False) -> tuple[Optional[InfrahubNod
3740

3841
async def execute_batch_task_in_pool(
3942
task: BatchTask, semaphore: asyncio.Semaphore, return_exceptions: bool = False
40-
) -> tuple[Optional[InfrahubNode], Any]:
43+
) -> tuple[InfrahubNode | None, Any]:
4144
async with semaphore:
4245
try:
4346
result = await task.task(*task.args, **task.kwargs)
@@ -52,7 +55,7 @@ async def execute_batch_task_in_pool(
5255
class InfrahubBatch:
5356
def __init__(
5457
self,
55-
semaphore: Optional[asyncio.Semaphore] = None,
58+
semaphore: asyncio.Semaphore | None = None,
5659
max_concurrent_execution: int = 5,
5760
return_exceptions: bool = False,
5861
):
@@ -64,7 +67,7 @@ def __init__(
6467
def num_tasks(self) -> int:
6568
return len(self._tasks)
6669

67-
def add(self, *args: Any, task: Callable, node: Optional[Any] = None, **kwargs: Any) -> None:
70+
def add(self, *args: Any, task: Callable, node: Any | None = None, **kwargs: Any) -> None:
6871
self._tasks.append(BatchTask(task=task, node=node, args=args, kwargs=kwargs))
6972

7073
async def execute(self) -> AsyncGenerator:
@@ -96,10 +99,10 @@ def __init__(self, max_concurrent_execution: int = 5, return_exceptions: bool =
9699
def num_tasks(self) -> int:
97100
return len(self._tasks)
98101

99-
def add(self, *args: Any, task: Callable[..., Any], node: Optional[Any] = None, **kwargs: Any) -> None:
102+
def add(self, *args: Any, task: Callable[..., Any], node: Any | None = None, **kwargs: Any) -> None:
100103
self._tasks.append(BatchTaskSync(task=task, node=node, args=args, kwargs=kwargs))
101104

102-
def execute(self) -> Generator[tuple[Optional[InfrahubNodeSync], Any], None, None]:
105+
def execute(self) -> Generator[tuple[InfrahubNodeSync | None, Any], None, None]:
103106
with ThreadPoolExecutor(max_workers=self.max_concurrent_execution) as executor:
104107
futures = [executor.submit(task.execute, return_exceptions=self.return_exceptions) for task in self._tasks]
105108
for future in futures:

infrahub_sdk/branch.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
import warnings
4-
from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
4+
from typing import TYPE_CHECKING, Any, Literal, overload
55
from urllib.parse import urlencode
66

77
from pydantic import BaseModel
@@ -17,11 +17,11 @@
1717
class BranchData(BaseModel):
1818
id: str
1919
name: str
20-
description: Optional[str] = None
20+
description: str | None = None
2121
sync_with_git: bool
2222
is_default: bool
2323
has_schema_changes: bool
24-
origin_branch: Optional[str] = None
24+
origin_branch: str | None = None
2525
branched_from: str
2626

2727

@@ -50,11 +50,11 @@ class InfraHubBranchManagerBase:
5050
@classmethod
5151
def generate_diff_data_url(
5252
cls,
53-
client: Union[InfrahubClient, InfrahubClientSync],
53+
client: InfrahubClient | InfrahubClientSync,
5454
branch_name: str,
5555
branch_only: bool = True,
56-
time_from: Optional[str] = None,
57-
time_to: Optional[str] = None,
56+
time_from: str | None = None,
57+
time_to: str | None = None,
5858
) -> str:
5959
"""Generate the URL for the diff_data function."""
6060
url = f"{client.address}/api/diff/data"
@@ -80,7 +80,7 @@ async def create(
8080
sync_with_git: bool = True,
8181
description: str = "",
8282
wait_until_completion: Literal[True] = True,
83-
background_execution: Optional[bool] = False,
83+
background_execution: bool | None = False,
8484
) -> BranchData: ...
8585

8686
@overload
@@ -90,7 +90,7 @@ async def create(
9090
sync_with_git: bool = True,
9191
description: str = "",
9292
wait_until_completion: Literal[False] = False,
93-
background_execution: Optional[bool] = False,
93+
background_execution: bool | None = False,
9494
) -> str: ...
9595

9696
async def create(
@@ -99,8 +99,8 @@ async def create(
9999
sync_with_git: bool = True,
100100
description: str = "",
101101
wait_until_completion: bool = True,
102-
background_execution: Optional[bool] = False,
103-
) -> Union[BranchData, str]:
102+
background_execution: bool | None = False,
103+
) -> BranchData | str:
104104
if background_execution is not None:
105105
warnings.warn(
106106
"`background_execution` is deprecated, please use `wait_until_completion` instead.",
@@ -206,8 +206,8 @@ async def diff_data(
206206
self,
207207
branch_name: str,
208208
branch_only: bool = True,
209-
time_from: Optional[str] = None,
210-
time_to: Optional[str] = None,
209+
time_from: str | None = None,
210+
time_to: str | None = None,
211211
) -> dict[Any, Any]:
212212
url = self.generate_diff_data_url(
213213
client=self.client,
@@ -251,7 +251,7 @@ def create(
251251
sync_with_git: bool = True,
252252
description: str = "",
253253
wait_until_completion: Literal[True] = True,
254-
background_execution: Optional[bool] = False,
254+
background_execution: bool | None = False,
255255
) -> BranchData: ...
256256

257257
@overload
@@ -261,7 +261,7 @@ def create(
261261
sync_with_git: bool = True,
262262
description: str = "",
263263
wait_until_completion: Literal[False] = False,
264-
background_execution: Optional[bool] = False,
264+
background_execution: bool | None = False,
265265
) -> str: ...
266266

267267
def create(
@@ -270,8 +270,8 @@ def create(
270270
sync_with_git: bool = True,
271271
description: str = "",
272272
wait_until_completion: bool = True,
273-
background_execution: Optional[bool] = False,
274-
) -> Union[BranchData, str]:
273+
background_execution: bool | None = False,
274+
) -> BranchData | str:
275275
if background_execution is not None:
276276
warnings.warn(
277277
"`background_execution` is deprecated, please use `wait_until_completion` instead.",
@@ -313,8 +313,8 @@ def diff_data(
313313
self,
314314
branch_name: str,
315315
branch_only: bool = True,
316-
time_from: Optional[str] = None,
317-
time_to: Optional[str] = None,
316+
time_from: str | None = None,
317+
time_to: str | None = None,
318318
) -> dict[Any, Any]:
319319
url = self.generate_diff_data_url(
320320
client=self.client,

infrahub_sdk/checks.py

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@
55
import os
66
import warnings
77
from abc import abstractmethod
8-
from typing import TYPE_CHECKING, Any, Optional
8+
from typing import TYPE_CHECKING, Any
99

1010
import ujson
1111
from git.repo import Repo
1212
from pydantic import BaseModel, Field
1313

14-
from .exceptions import InfrahubCheckNotFoundError, UninitializedError
14+
from .exceptions import UninitializedError
1515

1616
if TYPE_CHECKING:
17-
from pathlib import Path
18-
1917
from . import InfrahubClient
20-
from .schema.repository import InfrahubCheckDefinitionConfig
2118

2219
INFRAHUB_CHECK_VARIABLE_TO_IMPORT = "INFRAHUB_CHECKS"
2320

@@ -33,20 +30,20 @@ class InfrahubCheckInitializer(BaseModel):
3330

3431

3532
class InfrahubCheck:
36-
name: Optional[str] = None
33+
name: str | None = None
3734
query: str = ""
3835
timeout: int = 10
3936

4037
def __init__(
4138
self,
42-
branch: Optional[str] = None,
39+
branch: str | None = None,
4340
root_directory: str = "",
44-
output: Optional[str] = None,
45-
initializer: Optional[InfrahubCheckInitializer] = None,
46-
params: Optional[dict] = None,
47-
client: Optional[InfrahubClient] = None,
41+
output: str | None = None,
42+
initializer: InfrahubCheckInitializer | None = None,
43+
params: dict | None = None,
44+
client: InfrahubClient | None = None,
4845
):
49-
self.git: Optional[Repo] = None
46+
self.git: Repo | None = None
5047
self.initializer = initializer or InfrahubCheckInitializer()
5148

5249
self.logs: list[dict[str, Any]] = []
@@ -82,7 +79,7 @@ def client(self, value: InfrahubClient) -> None:
8279
self._client = value
8380

8481
@classmethod
85-
async def init(cls, client: Optional[InfrahubClient] = None, *args: Any, **kwargs: Any) -> InfrahubCheck:
82+
async def init(cls, client: InfrahubClient | None = None, *args: Any, **kwargs: Any) -> InfrahubCheck:
8683
"""Async init method, If an existing InfrahubClient client hasn't been provided, one will be created automatically."""
8784
warnings.warn(
8885
"InfrahubCheck.init has been deprecated and will be removed in the version in Infrahub SDK 2.0.0",
@@ -101,7 +98,7 @@ def errors(self) -> list[dict[str, Any]]:
10198
return [log for log in self.logs if log["level"] == "ERROR"]
10299

103100
def _write_log_entry(
104-
self, message: str, level: str, object_id: Optional[str] = None, object_type: Optional[str] = None
101+
self, message: str, level: str, object_id: str | None = None, object_type: str | None = None
105102
) -> None:
106103
log_message = {"level": level, "message": message, "branch": self.branch_name}
107104
if object_id:
@@ -113,10 +110,10 @@ def _write_log_entry(
113110
if self.output == "stdout":
114111
print(ujson.dumps(log_message))
115112

116-
def log_error(self, message: str, object_id: Optional[str] = None, object_type: Optional[str] = None) -> None:
113+
def log_error(self, message: str, object_id: str | None = None, object_type: str | None = None) -> None:
117114
self._write_log_entry(message=message, level="ERROR", object_id=object_id, object_type=object_type)
118115

119-
def log_info(self, message: str, object_id: Optional[str] = None, object_type: Optional[str] = None) -> None:
116+
def log_info(self, message: str, object_id: str | None = None, object_type: str | None = None) -> None:
120117
self._write_log_entry(message=message, level="INFO", object_id=object_id, object_type=object_type)
121118

122119
@property
@@ -155,7 +152,7 @@ async def collect_data(self) -> dict:
155152

156153
return await self.client.query_gql_query(name=self.query, branch_name=self.branch_name, variables=self.params)
157154

158-
async def run(self, data: Optional[dict] = None) -> bool:
155+
async def run(self, data: dict | None = None) -> bool:
159156
"""Execute the check after collecting the data from the GraphQL query.
160157
The result of the check is determined based on the presence or not of ERROR log messages."""
161158

@@ -176,27 +173,3 @@ async def run(self, data: Optional[dict] = None) -> bool:
176173
self.log_info("Check succesfully completed")
177174

178175
return self.passed
179-
180-
181-
def get_check_class_instance(
182-
check_config: InfrahubCheckDefinitionConfig, search_path: Optional[Path] = None
183-
) -> InfrahubCheck:
184-
if check_config.file_path.is_absolute() or search_path is None:
185-
search_location = check_config.file_path
186-
else:
187-
search_location = search_path / check_config.file_path
188-
189-
try:
190-
spec = importlib.util.spec_from_file_location(check_config.class_name, search_location)
191-
module = importlib.util.module_from_spec(spec) # type: ignore[arg-type]
192-
spec.loader.exec_module(module) # type: ignore[union-attr]
193-
194-
# Get the specified class from the module
195-
check_class = getattr(module, check_config.class_name)
196-
197-
# Create an instance of the class
198-
check_instance = check_class()
199-
except (FileNotFoundError, AttributeError) as exc:
200-
raise InfrahubCheckNotFoundError(name=check_config.name) from exc
201-
202-
return check_instance

0 commit comments

Comments
 (0)