Trying to map nested objects in streamlit using graphql queries

Hi all!

I am trying to write a simple streamlit app to extract certain nested parameters

I am working with the following Speckle model:
https://speckle.xyz/projects/dfdc0d2b01/models/60d4b65b7b

The structural engineer has nested (in a rather convoluted and inconsistent way) some key parameters I need to extract, under the “Tekla Common” and “Tekla Quantity” categories/fields. To make things more interesting (:D) NOT all elements have these parameters.

I had a go both with Grasshopper speckle plugin and with a python streamlit app. The latter shows more potential, however what it does NOT seem able to do is to find all object IDs associated with this model/commit?

I have coded this with substantial help from chatgpt, and despite being able to figure out exactly the path to each of the parameters I am after, by visually examining a full json dump of the data, the script does not seem to be able to loop through all objects IDs.

Following a long trial and error process, chatGPT concluded that:
"


✅ Speckle’s GraphQL API →
you cannot recursively call get_object_data for child IDs
that you don’t first discover through the API.

Why?
Because Speckle only stores one main graph per commit, and:
orphaned or parallel objects
objects not wired under referencedObject → elements → child → elements
are not discoverable from the API without already knowing their IDs."

" The GraphQL API only exposes linked objects via `.referencedObject → elements`, but I need a backend export or full object list for the entire commit or model."

It does suggest to find a way to get object IDs (including orphaned or unlinked objects) for downstream processing.

Is any of you able to help?

Different AI is now suggesting to:

  1. Log the unreachable IDs (you already are).
  2. Ask Speckle support or your server admin:

“Can I get a full backend export of all object IDs for stream dfdc0d2b01, model 60d4b65b7b, commit latest?”

  1. Optionally: filter out unresolved IDs from your final output to keep the UI clean.

Hi Andrea,

I’d suggest to use a specklepy script at this point. You can flatten the structure with the function below and it will -hopefully- return a list of objects.

def GetObjectsList(client, project_id, model_id):

    model = client.model.get_with_versions(model_id, project_id).versions
    root_object_id = model.items[0].referencedObject
    server_transport = ServerTransport(project_id, client)
    data = operations.receive(
        root_object_id, remote_transport=server_transport)

    object_list = []
    objects_to_process = [data]

    while objects_to_process:
        current = objects_to_process.pop()
        object_list.append(current.id)

        elements = getattr(current, "elements",
                           getattr(current, "@elements", None))
        if elements:
            objects_to_process.extend(elements)

    return object_list

Let me know if it works out. We can find other workarounds otherwise :slight_smile:

3 Likes