Skip to content

Commit

Permalink
Merge pull request #102 from opsmill/bkr-hotfix-throw-up-behind-the-c…
Browse files Browse the repository at this point in the history
…urtain

Be able to use the HFID on relationships toward Generic
  • Loading branch information
BeArchiTek authored Nov 26, 2024
2 parents 67c662b + f4fb9e1 commit 755271d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 25 deletions.
26 changes: 13 additions & 13 deletions emma/infrahub.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,35 +93,35 @@ def get_client(address: str | None = None, branch: str | None = None) -> Infrahu

@st.cache_data
def get_schema(branch: str | None = None) -> dict[str, MainSchemaTypes] | None:
client = get_client(branch=branch)
client = get_client()
if check_reachability(client=client):
return client.schema.all(branch=branch)
return None


def fetch_schema(branch: str | None = None) -> dict[str, MainSchemaTypes] | None:
client = get_client(branch=branch)
client = get_client()
if check_reachability(client=client):
return client.schema.fetch(branch=branch)
return None


@st.cache_data
def get_gql_schema(branch: str | None = None) -> dict[str, Any] | None:
client = get_client(branch=branch)
client = get_client()
schema_query = get_introspection_query()
return client.execute_graphql(schema_query)
return client.client.execute_graphql(query=schema_query, branch_name=branch)


def load_schema(branch: str, schemas: list[dict] | None = None) -> SchemaLoadResponse | None:
client = get_client(branch=branch)
client = get_client()
if check_reachability(client=client):
return client.schema.load(schemas, branch)
return None


def check_schema(branch: str, schemas: list[dict] | None = None) -> SchemaCheckResponse | None:
client = get_client(branch=branch)
client = get_client()
if check_reachability(client=client):
success, response = client.schema.check(schemas=schemas, branch=branch)
schema_check = SchemaCheckResponse(success=success, response=response)
Expand Down Expand Up @@ -168,7 +168,7 @@ def check_reachability(client: InfrahubClientSync) -> bool:


def get_objects_as_df(kind: str, include_id: bool = True, branch: str | None = None) -> pd.DataFrame | None:
client = get_client(branch=branch)
client = get_client()
if not check_reachability(client=client):
return None

Expand All @@ -195,23 +195,23 @@ def convert_node_to_dict(obj: InfrahubNodeSync, include_id: bool = True) -> dict
rel.fetch()
related_node = obj._client.store.get(key=rel.peer.id, raise_when_missing=False)
data[rel_name] = (
related_node.get_human_friendly_id_as_string(include_kind=False)
related_node.get_human_friendly_id_as_string(include_kind=True)
if related_node.hfid
else related_node.id
)
elif rel and isinstance(rel, RelationshipManagerSync):
peers: List[dict[str, Any]] = []
# FIXME: Seem dirty
if not rel.initialized:
rel.fetch()
for peer in rel.peers:
# TODO: Should we use the store to speed things up ? Will the HFID be populated ?
# FIXME: We are using the store to avoid doing to many queries to Infrahub
# but we could end up doing store+infrahub if the store is not populated
related_node = obj._client.store.get(key=peer.id, raise_when_missing=False)
if not related_node:
peer.fetch()
related_node = peer.peer
peers.append(
related_node.get_human_friendly_id_as_string(include_kind=False)
related_node.get_human_friendly_id_as_string(include_kind=True)
if related_node.hfid
else related_node.id
)
Expand Down Expand Up @@ -356,8 +356,8 @@ def is_feature_enabled(feature_name: str) -> bool:


def run_gql_query(query: str, branch: str | None = None) -> dict[str, MainSchemaTypes]:
client = get_client(branch=branch)
return client.execute_graphql(query, raise_for_error=False)
client = get_client()
return client.execute_graphql(query, branch_name=branch, raise_for_error=False)


def is_uuid(value: str) -> bool:
Expand Down
36 changes: 24 additions & 12 deletions pages/data_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import pandas as pd
import streamlit as st
from infrahub_sdk.exceptions import GraphQLError
from infrahub_sdk.schema import NodeSchema
from infrahub_sdk.schema import GenericSchema, NodeSchema
from infrahub_sdk.utils import compare_lists
from pandas.errors import EmptyDataError
from pydantic import BaseModel

from emma.infrahub import get_client, get_schema, handle_reachability_error, is_uuid, parse_hfid
from emma.infrahub import get_client, get_instance_branch, get_schema, handle_reachability_error, is_uuid, parse_hfid
from emma.streamlit_utils import set_page_config
from menu import menu_with_redirect

Expand All @@ -28,25 +28,31 @@ class Message(BaseModel):
message: str


def parse_item(item: str) -> Union[str, List[str]]:
def parse_item(item: str, is_generic: bool) -> Union[str, List[str]]:
"""Parse a single item as a UUID, HFID, or leave as-is."""
if is_uuid(item):
return item
return parse_hfid(item)
# FIXME: If the relationship is toward Generic we will retrieve the ID as we can't use HFID with a relationship to Generic
if is_generic:
tmp_hfid = parse_hfid(item)
obj = get_client().get(kind=tmp_hfid[0], hfid=tmp_hfid[1:], branch=get_instance_branch())
return obj.id
# If it's not a Generic we gonna parse the HFID
return parse_hfid(item)[1:]


def parse_value(value: Union[str, List[str]]) -> Union[str, List[str]]:
def parse_value(value: Union[str, List[str]], is_generic: bool) -> Union[str, List[str]]:
"""Parse a single value, either a UUID, HFID, or a list."""
if isinstance(value, str):
return parse_item(value)
return parse_item(item=value, is_generic=is_generic)
return value


def parse_list_value(value: str) -> Union[str, List[Union[str, List[str]]]]:
def parse_list_value(value: str, is_generic: bool) -> Union[str, List[Union[str, List[str]]]]:
"""Convert list-like string to a list and parse items as UUIDs or HFIDs."""
parsed_value = literal_eval(value)
if isinstance(parsed_value, list):
return [parse_item(item) for item in parsed_value]
return [parse_item(item=item, is_generic=is_generic) for item in parsed_value]
return value


Expand Down Expand Up @@ -80,11 +86,17 @@ def preprocess_and_validate_data(
continue

if column in target_schema.relationship_names:
relation_schema = target_schema.get_relationship(column)
peer_schema = get_client().schema.get(kind=relation_schema.peer, branch=get_instance_branch())
is_generic = False
if isinstance(peer_schema, GenericSchema):
is_generic = True
# Process relationships for HFID or UUID
if isinstance(value, str) and value.startswith("[") and value.endswith("]"):
processed_row[column] = parse_list_value(value=value)
processed_row[column] = parse_list_value(value=value, is_generic=is_generic)
else:
processed_row[column] = parse_value(value=value)
processed_row[column] = parse_value(value=value, is_generic=is_generic)

elif column in target_schema.attribute_names:
# Directly use attribute values
processed_row[column] = value
Expand Down Expand Up @@ -132,7 +144,7 @@ def preprocess_and_validate_data(

if st.button("Import Data"):
nbr_errors = 0
client = get_client(branch=st.session_state.infrahub_branch)
client = get_client()
st.write()
msg.toast(body=f"Loading data for {selected_schema.namespace}{selected_schema.name}")
for index, row in edited_df.iterrows():
Expand All @@ -142,7 +154,7 @@ def preprocess_and_validate_data(
for key, value in dict(row).items()
if not isinstance(value, float) or pd.notnull(value)
}
node = client.create(kind=selected_option, **data, branch=st.session_state.infrahub_branch)
node = client.create(kind=selected_option, **data, branch=get_instance_branch())
try:
node.save(allow_upsert=True)
edited_df.at[index, "Status"] = "ONGOING"
Expand Down

0 comments on commit 755271d

Please sign in to comment.