Skip to content

Merge stable into develop #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/publish-python-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: Publish Infrahub Python SDK
on: # yamllint disable rule:truthy
push:
tags:
- "python-sdk-v*"
- "v*"

jobs:
publish_to_pypi:
Expand All @@ -14,7 +14,7 @@ jobs:
- name: "Set up Python"
uses: "actions/setup-python@v5"
with:
python-version: "3.11"
python-version: "3.12"

- name: "Install Poetry"
uses: "snok/install-poetry@v1"
Expand All @@ -35,20 +35,16 @@ jobs:

- name: "Install Dependencies"
run: "poetry install"
working-directory: "./python_sdk"
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'

- name: "Add PyPI secret"
run: "poetry config pypi-token.pypi ${{ secrets.PYPI_TOKEN }}"

- name: "Poetry build"
run: "poetry build"
working-directory: "./python_sdk"

- name: "show output"
run: "ls -la dist/"
working-directory: "./python_sdk"

- name: "Poetry push PyPI"
run: "poetry publish"
working-directory: "./python_sdk"
9 changes: 2 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ coverage.xml
script.py
**/*.local.*
.vscode/settings.json
node_modules/*
development/docker-compose.override.yml
development/docker-compose.dev-override.yml
.DS_Store
.python-version
.ruff_cache
Expand All @@ -23,13 +20,11 @@ docs/build

storage/*
.coverage.*
python_sdk/dist/*
dist/*
.benchmarks/*

# Test reports
**/*.csv

# Generated files
generated/
query_performance_results/
sync/dist/
generated/
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the changes for the upcoming release can be found in <https://github.com/opsmill/infrahub/tree/develop/infrahub/python_sdk/changelog/>.

<!-- towncrier release notes start -->

## [0.13.1.dev0](https://github.com/opsmill/infrahub-sdk-python/tree/v0.13.1.dev0) - 2024-09-24

### Added

- Allow id filters to be combined when executing a query ([#3](https://github.com/opsmill/infrahub-sdk-python/issues/3))

### Fixed

- Add ability to construct HFIDs from payload for upsert mutations ([#45](https://github.com/opsmill/infrahub-sdk-python/issues/45))
- Fix pytest plugin integration tests unable to run because we were not properly setting the api_token configuration setting for the SDK.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@

> ⚠️ **Warning**
> This repository is still a WORK IN PROGRESS. Soon it will be the new home of the Python SDK for Infrahub but for now the project still lives in the main repository
</br>

<!-- markdownlint-disable -->
![Infrahub Logo](https://assets-global.website-files.com/657aff4a26dd8afbab24944b/657b0e0678f7fd35ce130776_Logo%20INFRAHUB.svg)
<!-- markdownlint-restore -->
Expand Down
1 change: 1 addition & 0 deletions changelog/46.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`execute_graphql` method for InfrahubClient(Sync) now properly considers the `default_branch` setting
18 changes: 10 additions & 8 deletions infrahub_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,14 +486,14 @@ async def get(
filters[schema.default_filter] = id
else:
filters["ids"] = [id]
elif hfid:
if hfid:
if isinstance(schema, NodeSchema) and schema.human_friendly_id:
filters["hfid"] = hfid
else:
raise ValueError("Cannot filter by HFID if the node doesn't have an HFID defined")
elif kwargs:
filters = kwargs
else:
if kwargs:
filters.update(kwargs)
if len(filters) == 0:
raise ValueError("At least one filter must be provided to get()")

results = await self.filters(
Expand Down Expand Up @@ -777,6 +777,7 @@ async def execute_graphql(
_type_: _description_
"""

branch_name = branch_name or self.default_branch
url = self._graphql_url(branch_name=branch_name, at=at)

payload: dict[str, Union[str, dict]] = {"query": query}
Expand Down Expand Up @@ -1520,6 +1521,7 @@ def execute_graphql(
dict: The result of the GraphQL query or mutation.
"""

branch_name = branch_name or self.default_branch
url = self._graphql_url(branch_name=branch_name, at=at)

payload: dict[str, Union[str, dict]] = {"query": query}
Expand Down Expand Up @@ -1927,14 +1929,14 @@ def get(
filters[schema.default_filter] = id
else:
filters["ids"] = [id]
elif hfid:
if hfid:
if isinstance(schema, NodeSchema) and schema.human_friendly_id:
filters["hfid"] = hfid
else:
raise ValueError("Cannot filter by HFID if the node doesn't have an HFID defined")
elif kwargs:
filters = kwargs
else:
if kwargs:
filters.update(kwargs)
if len(filters) == 0:
raise ValueError("At least one filter must be provided to get()")

results = self.filters(
Expand Down
7 changes: 3 additions & 4 deletions infrahub_sdk/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,12 +724,11 @@ def get_human_friendly_id(self) -> Optional[list[str]]:
if not self._schema.human_friendly_id:
return None

# If all components of an HFID are null, we cannot identify a single node
# If an HFID component is missing we assume that it is invalid and not usable for this node
hfid_components = [self.get_path_value(path=item) for item in self._schema.human_friendly_id]
if all(c is None for c in hfid_components):
if None in hfid_components:
return None

return [str(c) for c in hfid_components]
return [str(hfid) for hfid in hfid_components]

def get_human_friendly_id_as_string(self, include_kind: bool = False) -> Optional[str]:
hfid = self.get_human_friendly_id()
Expand Down
11 changes: 6 additions & 5 deletions infrahub_sdk/pytest_plugin/plugin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from pathlib import Path
from typing import Optional, Union

Expand Down Expand Up @@ -34,6 +35,7 @@ def pytest_addoption(parser: Parser) -> None:
action="store",
dest="infrahub_key",
metavar="INFRAHUB_TESTS_API_KEY",
default=os.getenv("INFRAHUB_API_TOKEN"),
help="Key to use when querying the Infrahub instance for live testing",
)
group.addoption(
Expand Down Expand Up @@ -74,12 +76,11 @@ def pytest_sessionstart(session: Session) -> None:
"default_branch": session.config.option.infrahub_branch,
}
if hasattr(session.config.option, "infrahub_key"):
client_config = {"api_token": session.config.option.infrahub_key}
client_config["api_token"] = session.config.option.infrahub_key
elif hasattr(session.config.option, "infrahub_username") and hasattr(session.config.option, "infrahub_password"):
client_config = {
"username": session.config.option.infrahub_username,
"password": session.config.option.infrahub_password,
}
client_config.pop("api_token")
client_config["username"] = session.config.option.infrahub_username
client_config["password"] = session.config.option.infrahub_password

infrahub_client = InfrahubClientSync(config=client_config)
session.infrahub_client = infrahub_client # type: ignore[attr-defined]
Expand Down
93 changes: 89 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ruff = "0.5.0"
pytest-xdist = "^3.3.1"
types-python-slugify = "^8.0.0.3"
invoke = "^2.2.0"
towncrier = "^24.8.0"

[tool.poetry.extras]
ctl = ["Jinja2", "numpy", "pyarrow", "pyyaml", "rich", "toml", "typer"]
Expand Down Expand Up @@ -346,7 +347,7 @@ max-complexity = 17

[tool.towncrier]

package = "infrahub-sdk"
package = "infrahub_sdk"
directory = "changelog"
filename = "CHANGELOG.md"
start_string = "<!-- towncrier release notes start -->\n"
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/sdk/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1978,25 +1978,25 @@ async def mock_rest_api_artifact_generate(httpx_mock: HTTPXMock) -> HTTPXMock:
@pytest.fixture
async def mock_query_mutation_schema_dropdown_add(httpx_mock: HTTPXMock) -> None:
response = {"data": {"SchemaDropdownAdd": {"ok": True}}}
httpx_mock.add_response(method="POST", url="http://mock/graphql", json=response)
httpx_mock.add_response(method="POST", url="http://mock/graphql/main", json=response)


@pytest.fixture
async def mock_query_mutation_schema_dropdown_remove(httpx_mock: HTTPXMock) -> None:
response = {"data": {"SchemaDropdownRemove": {"ok": True}}}
httpx_mock.add_response(method="POST", url="http://mock/graphql", json=response)
httpx_mock.add_response(method="POST", url="http://mock/graphql/main", json=response)


@pytest.fixture
async def mock_query_mutation_schema_enum_add(httpx_mock: HTTPXMock) -> None:
response = {"data": {"SchemaEnumAdd": {"ok": True}}}
httpx_mock.add_response(method="POST", url="http://mock/graphql", json=response)
httpx_mock.add_response(method="POST", url="http://mock/graphql/main", json=response)


@pytest.fixture
async def mock_query_mutation_schema_enum_remove(httpx_mock: HTTPXMock) -> None:
response = {"data": {"SchemaEnumRemove": {"ok": True}}}
httpx_mock.add_response(method="POST", url="http://mock/graphql", json=response)
httpx_mock.add_response(method="POST", url="http://mock/graphql/main", json=response)


@pytest.fixture
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/sdk/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ async def test_allocate_next_ip_prefix(
assert ip_prefix.description.value == "test"


EXPECTED_ECHO = """URL: http://mock/graphql
EXPECTED_ECHO = """URL: http://mock/graphql/main
QUERY:

query GetTags($name: String!) {
Expand Down