Skip to content

Commit 06fff9d

Browse files
authored
Merge pull request #366 from opsmill/develop
Release 1.11
2 parents f3a6b8d + e903010 commit 06fff9d

Some content is hidden

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

62 files changed

+27104
-500
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ jobs:
166166
python-version: "3.12"
167167
- name: "Setup Python environment"
168168
run: |
169-
pipx install poetry==1.8.5
169+
pipx install poetry==2.1
170170
poetry config virtualenvs.create true --local
171171
poetry env use 3.12
172172
- name: "Install dependencies"
@@ -230,7 +230,7 @@ jobs:
230230
python-version: ${{ matrix.python-version }}
231231
- name: "Setup environment"
232232
run: |
233-
pipx install poetry==1.8.5 --python python${{ matrix.python-version }}
233+
pipx install poetry==2.1 --python python${{ matrix.python-version }}
234234
poetry config virtualenvs.create true --local
235235
pip install invoke toml codecov
236236
- name: "Install Package"
@@ -283,14 +283,11 @@ jobs:
283283
echo "PYTEST_DEBUG_TEMPROOT=/var/lib/github/${RUNNER_NAME}/_temp" >> $GITHUB_ENV
284284
- name: "Setup environment"
285285
run: |
286-
pipx install poetry==1.8.5
286+
pipx install poetry==2.1
287287
poetry config virtualenvs.create true --local
288288
pip install invoke toml codecov
289289
- name: "Install Package"
290290
run: "poetry install --all-extras"
291-
- name: "Set environment variables for python_testcontainers"
292-
run: |
293-
echo INFRAHUB_TESTING_IMAGE_VER=latest >> $GITHUB_ENV
294291
- name: "Integration Tests"
295292
run: |
296293
poetry run pytest --cov infrahub_sdk tests/integration/
@@ -359,7 +356,7 @@ jobs:
359356

360357
# - name: "Setup environment"
361358
# run: |
362-
# pipx install poetry==1.8.5
359+
# pipx install poetry==2.1
363360
# poetry config virtualenvs.create true --local
364361
# pip install invoke toml codecov
365362

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ dist/*
2727
**/*.csv
2828

2929
# Generated files
30-
generated/
30+
generated/
31+
sandbox/

.vale/styles/Infrahub/branded-terms-case-swap.yml

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,31 @@ ignorecase: false
66
action:
77
name: replace
88
swap:
9-
(?i:[^/]Github): GitHub
10-
(?i:gitpod): GitPod
11-
(?i:[^/]Graphql): GraphQL
9+
(?:ansible): Ansible
10+
(?:[^"]docker): Docker
11+
(?:[Dd]ockerhub): DockerHub
12+
(?:[^/][Gg]ithub): GitHub
13+
(?:[Gg]itlab): GitLab
14+
(?:gitpod): GitPod
15+
(?:grafana): Grafana
16+
(?:[^/][Gg]raphql): GraphQL
17+
(?:[Ii]nflux[Dd]b): InfluxDB
1218
infrahub(?:\s|$): Infrahub
13-
(?i:Openconfig): OpenConfig
19+
(?:jinja2): Jinja2
20+
(?:k3s): K3s
21+
(?:k8s): K8s
22+
(?:kubernetes): Kubernetes
23+
(?:[^/][Mm]y[Ss]ql): MySQL
24+
(?:neo4j): Neo4j
25+
(?:[^/][Nn]ginx): NGINX
26+
(?:[Nn]odejs): Node.js
27+
(?:[^/][Oo]penapi): OpenAPI
28+
(?:Openconfig): OpenConfig
1429
opsmill(?:\s|$): OpsMill
30+
(?:[Pp]ostgre[Ss]ql): PostgreSQL
31+
(?:[^/]prometheus): Prometheus
32+
(?:[^/-]python): Python
33+
(?:[Rr]abbitmq): RabbitMQ
34+
(?:[^/]terraform): Terraform
35+
(?:ubuntu): Ubuntu
36+
(?:[Vv]s\W?[Cc]ode): VS Code

.yamllint.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ ignore: |
55
/.venv
66
/examples
77
tests/unit/sdk/test_data/schema_encoding_error.yml
8+
/**/node_modules/**
9+
tests/unit/sdk/test_data/multiple_files_valid_not_valid.yml
10+
tests/fixtures/menus/invalid_yaml.yml
811
912
rules:
1013
new-lines: disable

CHANGELOG.md

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

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

14+
## [1.11.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.11.0) - 2025-04-17
15+
16+
### Deprecated
17+
18+
- The 'timeout' parameter while creating a node or fetching the schema has been deprecated. the default_timeout will be used instead.
19+
20+
### Added
21+
22+
- Add support for object Template when generating protocols ([#329](https://github.com/opsmill/infrahub-sdk-python/issues/329))
23+
- Add a Guide related to Python Typing
24+
- Add method `client.schema.set_cache()` to populate the cache manually (primarily for unit testing)
25+
- By default, schema.fetch will now populate the cache (this behavior can be changed with `populate_cache`)
26+
- Add `menu validate` command to validate the format of menu files.
27+
28+
### Fixed
29+
30+
- Raise a proper branch not found error when requesting a node or schema for a branch that doesn't exist. ([#286](https://github.com/opsmill/infrahub-sdk-python/issues/286))
31+
- Fix support for Sync when generating Python Protocols
32+
33+
### Housekeeping
34+
35+
- Add `invoke lint-doc` command to help run the docs linters locally
36+
- Add a fixture to always reset some environment variables before running tests
37+
- Update Pytest-httpx and set all responses as reusable
38+
1439
## [1.10.2](https://github.com/opsmill/infrahub-sdk-python/tree/v1.10.2) - 2025-04-11
1540

1641
### Fixed

docs/docs/infrahubctl/infrahubctl-menu.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $ infrahubctl menu [OPTIONS] COMMAND [ARGS]...
1717
**Commands**:
1818

1919
* `load`: Load one or multiple menu files into...
20+
* `validate`: Validate one or multiple menu files.
2021

2122
## `infrahubctl menu load`
2223

@@ -38,3 +39,24 @@ $ infrahubctl menu load [OPTIONS] MENUS...
3839
* `--branch TEXT`: Branch on which to load the menu.
3940
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
4041
* `--help`: Show this message and exit.
42+
43+
## `infrahubctl menu validate`
44+
45+
Validate one or multiple menu files.
46+
47+
**Usage**:
48+
49+
```console
50+
$ infrahubctl menu validate [OPTIONS] PATHS...
51+
```
52+
53+
**Arguments**:
54+
55+
* `PATHS...`: [required]
56+
57+
**Options**:
58+
59+
* `--debug / --no-debug`: [default: no-debug]
60+
* `--branch TEXT`: Branch on which to validate the objects.
61+
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
62+
* `--help`: Show this message and exit.

docs/docs/infrahubctl/infrahubctl-object.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $ infrahubctl object [OPTIONS] COMMAND [ARGS]...
1717
**Commands**:
1818

1919
* `load`: Load one or multiple objects files into...
20+
* `validate`: Validate one or multiple objects files.
2021

2122
## `infrahubctl object load`
2223

@@ -38,3 +39,24 @@ $ infrahubctl object load [OPTIONS] PATHS...
3839
* `--branch TEXT`: Branch on which to load the objects.
3940
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
4041
* `--help`: Show this message and exit.
42+
43+
## `infrahubctl object validate`
44+
45+
Validate one or multiple objects files.
46+
47+
**Usage**:
48+
49+
```console
50+
$ infrahubctl object validate [OPTIONS] PATHS...
51+
```
52+
53+
**Arguments**:
54+
55+
* `PATHS...`: [required]
56+
57+
**Options**:
58+
59+
* `--debug / --no-debug`: [default: no-debug]
60+
* `--branch TEXT`: Branch on which to validate the objects.
61+
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
62+
* `--help`: Show this message and exit.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: Strict Typing in Python
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
8+
# Overview
9+
10+
This guide explains how to use Python's type system effectively with the Infrahub SDK, focusing on the use of Protocols for type-safe development.
11+
12+
:::note What is Python Typing
13+
14+
Python typing allows you to specify the expected data types of variables, function arguments, and return values to improve code clarity and catch bugs early.
15+
16+
```python
17+
# Basic type hints
18+
def percentage(num1: int, num2: int) -> float:
19+
return (num1 / num2) * 100
20+
```
21+
22+
:::
23+
24+
## Leveraging Python protocols
25+
26+
The Python SDK for Infrahub has been designed to automatically work with any schemas loaded into Infrahub.
27+
Internally, the Python SDK generates dynamic Python representations of your schemas.
28+
29+
While this approach improves code readability, it presents challenges with type checking because each object has a different signature based on your schema.
30+
31+
### Without protocols
32+
33+
In the example below, type checkers like Mypy will typically complain about `blue_tag.description.value` because `description` is a dynamic parameter generated by the SDK.
34+
35+
```python
36+
# Type checker cannot verify the existence of 'description'
37+
blue_tag = client.get("BuiltinTag", name__value="blue") # blue_tag is of type InfrahubNode or InfrahubNodeSync
38+
blue_tag.description.value = "The blue tag" # Mypy: error: "InfrahubNode" has no attribute "description"
39+
blue_tag.save()
40+
```
41+
42+
### With protocols
43+
44+
To provide strict type checking while maintaining platform extensibility, the Python SDK integrates with Python Protocols.
45+
46+
For all core and internal models, the protocols are included in the SDK under `infrahub_sdk.protocols`.
47+
Whenever you need to specify the kind of object you're working with as a string, you can use the corresponding protocol instead.
48+
49+
```python
50+
from infrahub_sdk.protocols import BuiltinTag
51+
52+
# Type checker can now verify all attributes
53+
blue_tag = client.get(BuiltinTag, name__value="blue") # blue_tag is of type BuiltinTag
54+
blue_tag.description.value = "The blue tag" # No type errors
55+
blue_tag.save()
56+
```
57+
58+
:::note Python Protocols
59+
60+
Python Protocols, introduced in PEP 544, define a set of method and property signatures that a class must implement to be considered a match, enabling structural subtyping (also known as "duck typing" with static checks). They allow you to specify behavior without requiring inheritance, making code more flexible and type-safe.
61+
62+
More information about Python Protocols can be found [here](https://typing.python.org/en/latest/spec/protocol.html)
63+
64+
:::
65+
66+
## Generating custom protocols based on your schema
67+
68+
You can generate Python Protocols for your own models using the `infrahubctl protocols` command. This supports both synchronous and asynchronous Python code.
69+
70+
It's possible to provide the schema from a local directory or from an existing Infrahub Instance.
71+
72+
<Tabs groupId="local-remote">
73+
<TabItem value="Existing Infrahub Instance" default>
74+
75+
```shell
76+
export INFRAHUB_ADDRESS=https://infrahub.example.com
77+
infrahubctl protocols --out lib/protocols.py --sync
78+
```
79+
80+
</TabItem>
81+
<TabItem value="Local Directory" default>
82+
83+
```shell
84+
infrahubctl protocols --schemas schemas/tag.schema.yml --out lib/protocols.py
85+
```
86+
87+
</TabItem>
88+
</Tabs>
89+
90+
> When using a local directory, Protocols for Profiles and Object Templates won't be generated.
91+
92+
## Using custom protocols
93+
94+
After generation, you can import and use your custom protocols as describe below.
95+
96+
```python
97+
from lib.protocols import MyOwnObject
98+
99+
# Use your custom protocol
100+
my_object = client.get(MyOwnObject, name__value="example")
101+
```
102+
103+
> if you don't have your own Python module, it's possible to use relative path by having the `procotols.py` in the same directory as your script/transform/generator

0 commit comments

Comments
 (0)