Skip to content

Commit 712079b

Browse files
authored
Merge pull request #195 from opsmill/develop
Release SDK v1.3.0
2 parents 307ed5e + f99a19e commit 712079b

39 files changed

+2223
-1571
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ jobs:
9191
- name: "Check out repository code"
9292
uses: "actions/checkout@v4"
9393
- name: "Linting: markdownlint"
94-
uses: DavidAnson/markdownlint-cli2-action@v18
94+
uses: DavidAnson/markdownlint-cli2-action@v19
9595
with:
9696
config: .markdownlint.yaml
9797
globs: |

CHANGELOG.md

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

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

14+
## [1.3.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.3.0) - 2024-12-30
15+
16+
### Added
17+
18+
#### Testing library (**Alpha**)
19+
20+
A new collection of tools and utilities to help with testing is available under `infrahub_sdk.testing`.
21+
22+
The first component available is a `TestInfrahubDockerClient`, a pytest Class designed to help creating integration tests based on Infrahub. See a simple example below to help you get started.
23+
24+
> the installation of `infrahub-testcontainers` is required
25+
26+
```python
27+
import pytest
28+
29+
from infrahub_sdk import InfrahubClient
30+
from infrahub_sdk.testing.docker import TestInfrahubDockerClient
31+
32+
class TestInfrahubNode(TestInfrahubDockerClient):
33+
34+
@pytest.fixture(scope="class")
35+
def infrahub_version(self) -> str:
36+
"""Required (for now) to define the version of infrahub to use."""
37+
return "1.0.10"
38+
39+
@pytest.fixture(scope="class")
40+
async def test_create_tag(self, default_branch: str, client: InfrahubClient) -> None:
41+
obj = await client.create(kind="BuiltinTag", name="Blue")
42+
await obj.save()
43+
assert obj.id
44+
```
45+
46+
### Changed
47+
48+
- The Pydantic models for the schema have been split into multiple versions to align better with the different phase of the lifecycle of the schema.
49+
- User input: includes only the options available for a user to define (NodeSchema, AttributeSchema, RelationshipSchema, GenericSchema)
50+
- API: Format of the schema as exposed by the API in infrahub with some read only settings (NodeSchemaAPI, AttributeSchemaAPI, RelationshipSchemaAPI, GenericSchemaAPI)
51+
52+
### Fixed
53+
54+
- Fix behaviour of attribute value coming from resource pools for async client ([#66](https://github.com/opsmill/infrahub-sdk-python/issues/66))
55+
- Convert import_root to a string if it was submitted as a Path object to ensure that anything added to sys.path is a string
56+
- Fix relative imports for the pytest plugin, note that the relative imports can't be at the top level of the repository alongside .infrahub.yml. They have to be located within a subfolder. ([#166](https://github.com/opsmill/infrahub-sdk-python/issues/166))
57+
1458
## [1.2.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.2.0) - 2024-12-19
1559

1660
### Added
@@ -60,7 +104,7 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang
60104

61105
### Removed
62106

63-
- Breaking change: Removed all exports from infrahub_sdk/__init__.py except InfrahubClient, InfrahubClientSync and Config. If you previously imported other classes such as InfrahubNode from the root level these need to change to instead be an absolute path.
107+
- Breaking change: Removed all exports from `infrahub_sdk/__init__.py` except InfrahubClient, InfrahubClientSync and Config. If you previously imported other classes such as InfrahubNode from the root level these need to change to instead be an absolute path.
64108

65109
### Added
66110

infrahub_sdk/_importer.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,23 @@
1616
def import_module(
1717
module_path: Path, import_root: Optional[str] = None, relative_path: Optional[str] = None
1818
) -> ModuleType:
19+
"""Imports a python module.
20+
21+
Args:
22+
module_path (Path): Absolute path of the module to import.
23+
import_root (Optional[str]): Absolute string path to the current repository.
24+
relative_path (Optional[str]): Relative string path between module_path and import_root.
25+
"""
1926
import_root = import_root or str(module_path.parent)
2027

2128
file_on_disk = module_path
2229
if import_root and relative_path:
2330
file_on_disk = Path(import_root, relative_path, module_path.name)
2431

32+
# This is a temporary workaround for to account for issues if "import_root" is a Path instead of a str
33+
# Later we should rework this so that import_root and relative_path are all Path objects. Here we must
34+
# ensure that anything we add to sys.path is a string and not a Path or PosixPath object.
35+
import_root = str(import_root)
2536
if import_root not in sys.path:
2637
sys.path.append(import_root)
2738

infrahub_sdk/checks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from pathlib import Path
1818

1919
from . import InfrahubClient
20-
from .schema import InfrahubCheckDefinitionConfig
20+
from .schema.repository import InfrahubCheckDefinitionConfig
2121

2222
INFRAHUB_CHECK_VARIABLE_TO_IMPORT = "INFRAHUB_CHECKS"
2323

infrahub_sdk/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
from .protocols_base import CoreNode, CoreNodeSync
5151
from .queries import get_commit_update_mutation
5252
from .query_groups import InfrahubGroupContext, InfrahubGroupContextSync
53-
from .schema import InfrahubSchema, InfrahubSchemaSync, NodeSchema
53+
from .schema import InfrahubSchema, InfrahubSchemaSync, NodeSchemaAPI
5454
from .store import NodeStore, NodeStoreSync
5555
from .timestamp import Timestamp
5656
from .types import AsyncRequester, HTTPMethod, SyncRequester
@@ -448,12 +448,12 @@ async def get(
448448
filters: MutableMapping[str, Any] = {}
449449

450450
if id:
451-
if not is_valid_uuid(id) and isinstance(schema, NodeSchema) and schema.default_filter:
451+
if not is_valid_uuid(id) and isinstance(schema, NodeSchemaAPI) and schema.default_filter:
452452
filters[schema.default_filter] = id
453453
else:
454454
filters["ids"] = [id]
455455
if hfid:
456-
if isinstance(schema, NodeSchema) and schema.human_friendly_id:
456+
if isinstance(schema, NodeSchemaAPI) and schema.human_friendly_id:
457457
filters["hfid"] = hfid
458458
else:
459459
raise ValueError("Cannot filter by HFID if the node doesn't have an HFID defined")
@@ -1916,12 +1916,12 @@ def get(
19161916
filters: MutableMapping[str, Any] = {}
19171917

19181918
if id:
1919-
if not is_valid_uuid(id) and isinstance(schema, NodeSchema) and schema.default_filter:
1919+
if not is_valid_uuid(id) and isinstance(schema, NodeSchemaAPI) and schema.default_filter:
19201920
filters[schema.default_filter] = id
19211921
else:
19221922
filters["ids"] = [id]
19231923
if hfid:
1924-
if isinstance(schema, NodeSchema) and schema.human_friendly_id:
1924+
if isinstance(schema, NodeSchemaAPI) and schema.human_friendly_id:
19251925
filters["hfid"] = hfid
19261926
else:
19271927
raise ValueError("Cannot filter by HFID if the node doesn't have an HFID defined")

infrahub_sdk/code_generator.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
from collections.abc import Mapping
2-
from typing import Any, Optional
2+
from typing import Any, Optional, Union
33

44
import jinja2
55

66
from . import protocols as sdk_protocols
77
from .ctl.constants import PROTOCOLS_TEMPLATE
88
from .schema import (
9-
AttributeSchema,
9+
AttributeSchemaAPI,
1010
GenericSchema,
11-
MainSchemaTypes,
11+
GenericSchemaAPI,
12+
MainSchemaTypesAll,
1213
NodeSchema,
13-
ProfileSchema,
14-
RelationshipSchema,
14+
NodeSchemaAPI,
15+
ProfileSchemaAPI,
16+
RelationshipSchemaAPI,
1517
)
1618

1719
ATTRIBUTE_KIND_MAP = {
@@ -40,17 +42,17 @@
4042

4143

4244
class CodeGenerator:
43-
def __init__(self, schema: dict[str, MainSchemaTypes]):
44-
self.generics: dict[str, GenericSchema] = {}
45-
self.nodes: dict[str, NodeSchema] = {}
46-
self.profiles: dict[str, ProfileSchema] = {}
45+
def __init__(self, schema: dict[str, MainSchemaTypesAll]):
46+
self.generics: dict[str, Union[GenericSchemaAPI, GenericSchema]] = {}
47+
self.nodes: dict[str, Union[NodeSchemaAPI, NodeSchema]] = {}
48+
self.profiles: dict[str, ProfileSchemaAPI] = {}
4749

4850
for name, schema_type in schema.items():
49-
if isinstance(schema_type, GenericSchema):
51+
if isinstance(schema_type, (GenericSchemaAPI, GenericSchema)):
5052
self.generics[name] = schema_type
51-
if isinstance(schema_type, NodeSchema):
53+
if isinstance(schema_type, (NodeSchemaAPI, NodeSchema)):
5254
self.nodes[name] = schema_type
53-
if isinstance(schema_type, ProfileSchema):
55+
if isinstance(schema_type, ProfileSchemaAPI):
5456
self.profiles[name] = schema_type
5557

5658
self.base_protocols = [
@@ -92,7 +94,7 @@ def _jinja2_filter_inheritance(value: dict[str, Any]) -> str:
9294
return ", ".join(inherit_from)
9395

9496
@staticmethod
95-
def _jinja2_filter_render_attribute(value: AttributeSchema) -> str:
97+
def _jinja2_filter_render_attribute(value: AttributeSchemaAPI) -> str:
9698
attribute_kind: str = ATTRIBUTE_KIND_MAP[value.kind]
9799

98100
if value.optional:
@@ -101,7 +103,7 @@ def _jinja2_filter_render_attribute(value: AttributeSchema) -> str:
101103
return f"{value.name}: {attribute_kind}"
102104

103105
@staticmethod
104-
def _jinja2_filter_render_relationship(value: RelationshipSchema, sync: bool = False) -> str:
106+
def _jinja2_filter_render_relationship(value: RelationshipSchemaAPI, sync: bool = False) -> str:
105107
name = value.name
106108
cardinality = value.cardinality
107109

@@ -116,12 +118,12 @@ def _jinja2_filter_render_relationship(value: RelationshipSchema, sync: bool = F
116118

117119
@staticmethod
118120
def _sort_and_filter_models(
119-
models: Mapping[str, MainSchemaTypes], filters: Optional[list[str]] = None
120-
) -> list[MainSchemaTypes]:
121+
models: Mapping[str, MainSchemaTypesAll], filters: Optional[list[str]] = None
122+
) -> list[MainSchemaTypesAll]:
121123
if filters is None:
122124
filters = ["CoreNode"]
123125

124-
filtered: list[MainSchemaTypes] = []
126+
filtered: list[MainSchemaTypesAll] = []
125127
for name, model in models.items():
126128
if name in filters:
127129
continue

infrahub_sdk/ctl/check.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ..ctl.repository import get_repository_config
1818
from ..ctl.utils import catch_exception, execute_graphql_query
1919
from ..exceptions import ModuleImportError
20-
from ..schema import InfrahubCheckDefinitionConfig, InfrahubRepositoryConfig
20+
from ..schema.repository import InfrahubCheckDefinitionConfig, InfrahubRepositoryConfig
2121

2222
app = typer.Typer()
2323
console = Console()

infrahub_sdk/ctl/cli_commands.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@
3838
from ..ctl.validate import app as validate_app
3939
from ..exceptions import GraphQLError, ModuleImportError
4040
from ..jinja2 import identify_faulty_jinja_code
41-
from ..schema import (
42-
InfrahubRepositoryConfig,
43-
MainSchemaTypes,
44-
SchemaRoot,
45-
)
41+
from ..schema import MainSchemaTypesAll, SchemaRoot
42+
from ..schema.repository import InfrahubRepositoryConfig
4643
from ..utils import get_branch, write_to_file
4744
from ..yaml import SchemaFile
4845
from .exporter import dump
@@ -364,7 +361,7 @@ def protocols(
364361
) -> None:
365362
"""Export Python protocols corresponding to a schema."""
366363

367-
schema: dict[str, MainSchemaTypes] = {}
364+
schema: dict[str, MainSchemaTypesAll] = {}
368365

369366
if schemas:
370367
schemas_data = load_yamlfile_from_disk_and_exit(paths=schemas, file_type=SchemaFile, console=console)

infrahub_sdk/ctl/generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ..ctl.utils import execute_graphql_query, parse_cli_vars
1111
from ..exceptions import ModuleImportError
1212
from ..node import InfrahubNode
13-
from ..schema import InfrahubRepositoryConfig
13+
from ..schema.repository import InfrahubRepositoryConfig
1414

1515

1616
async def run(

infrahub_sdk/ctl/render.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from rich.console import Console
22

3-
from ..schema import InfrahubRepositoryConfig
3+
from ..schema.repository import InfrahubRepositoryConfig
44

55

66
def list_jinja2_transforms(config: InfrahubRepositoryConfig) -> None:

0 commit comments

Comments
 (0)