datadog-api-client-python icon indicating copy to clipboard operation
datadog-api-client-python copied to clipboard

`SoftwareCatalogApi.list_catalog_entity` does not filter services when `filter_name` is passed

Open meestermuffin opened this issue 5 months ago • 2 comments

Describe the bug I have tried to pass in variations of filter_name such as filter_name=app_name, filter_name=f"name:{app_name}", and filter_name=f"service:{app_name}". The results always return the services in alphabetical order. I have verified the services I'm filtering exist.

Label the issue properly.

  • Add severity/ label.
  • Add documentation label if this issue is related to documentation changes.

To Reproduce Steps to reproduce the behavior:

def associate_datadog_teams(app_name: str, owner: str) -> str:
    if not app_name or not isinstance(app_name, str):
        raise ValueError("Invalid app_name provided")
    if not owner or not isinstance(owner, str):
        raise ValueError("Invalid owner provided")

    # Make sure application key is available under the env var the SDK expects
    if os.getenv("DD_APP_KEY") is None and os.getenv("DD_APPLICATION_KEY"):
        os.environ["DD_APP_KEY"] = os.environ["DD_APPLICATION_KEY"]

    # Validate required credentials are present
    if not os.getenv("DD_API_KEY") or not os.getenv("DD_APP_KEY"):
        raise ValueError(
            "Missing Datadog credentials. Ensure DD_API_KEY and DD_APP_KEY (or DD_APPLICATION_KEY) are set."
        )

    # Helper for safely getting nested attributes whether SDK returns models or dicts
    def _get(obj, path: list[str], default=None):
        cur = obj
        for key in path:
            if cur is None:
                return default
            if isinstance(cur, dict):
                cur = cur.get(key)
            else:
                cur = getattr(cur, key, None)
        return cur if cur is not None else default

    # Search for service by exact name
    configuration = Configuration()
    with ApiClient(configuration) as api_client:
        api = SoftwareCatalogApi(api_client)
        try:
            resp = api.list_catalog_entity(filter_name=f"service:{app_name}", filter_kind="service", page_limit=5)
        except Exception as e:
            raise ValueError(f"Failed to query Datadog Software Catalog: {e}") from e
        
        print("Services returned by API:")
        for item in resp.data:
            service_name = item.attributes.name
            print(f"  - {service_name}")
        print()

        items = _get(resp, ["data"], [])
        # Find an exact name match among returned items
        matched = None
        for it in items or []:
            name = _get(it, ["attributes", "name"]) or _get(it, ["attributes", "metadata", "name"])  # fallback
            if name == app_name:
                matched = it
                break

        if not matched:
            return f"Service '{app_name}' not found in Datadog Service Catalog. Skipping association."

Expected behavior

It should return the service I'm passing as filter_name.

Screenshots If applicable, add screenshots to help explain your problem.

Environment and Versions (please complete the following information): A clear and precise description of your setup: datadog_api_client==2.40.0

meestermuffin avatar Aug 11 '25 16:08 meestermuffin

As a follow up, is there a where to query and list services that DO NOT have ownership and metadata using the software catalog API?

meestermuffin avatar Aug 12 '25 16:08 meestermuffin

Thanks for your contribution!

This issue has been automatically marked as stale because it has not had activity in the last 30 days. Note that the issue will not be automatically closed, but this notification will remind us to investigate why there's been inactivity. Thank you for participating in the Datadog open source community.

If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue in the latest version of this project.

  2. Comment that the issue is still reproducible and include updated details requested in the issue template.

github-actions[bot] avatar Sep 20 '25 00:09 github-actions[bot]