No access to referencedObject

Hi,
I´m new to specklepy and try to read data from an Archicad model on our server. I simply want to read out the data from referencedObject via python like so:

commit = client.commit.get(STREAM_ID, COMMIT_ID)
refObj = commit.referencedObject(id=“5edbde50e9f1c66a1da5bf91f82a2f93”)

This throws the exception:
AttributeError: ‘SpeckleException’ object has no attribute ‘referencedObject’

In my understanding there definitely should be a referencedObject.
grafik

Maybe someone can help me out with this?
thanks in advance!

in this case, refObj = commit.referencedObject will return the string value "5edbde50e9f1c66a1da5bf91f82a2f93"

there is no need to retrieve this as if it were a method named referencedObject

to then retrieve the data in the commit using this id

# Create the server transport for the specified stream.
transport = ServerTransport(client=client, stream_id=STREAM_ID)

# Receive the object
received_base = operations.receive(obj_id=refObj, remote_transport=transport)

Hi Jonathan,
thanks for your answer! I must admit, the whole specklepy experience is pure frustration to me at this point. I simply want to read out data from an Archicad model on our server. Nothing specific at this point. I just want to be able to read out lets say all columns for example. with GraphQL under the referencedObject I get at least a list of children and there data. With specklepy I m not getting even close to any data of use so far. The speckledocs didn´t really help me. I´m new to python and speckle, so I guess the problem is me.
Is there somewhere a simple example how to retrieve Data from an architectural Model (Revit or Archicad) via specklepy that shows how to dig into the collections? Maybe I just missed the right resource to build up some knowledge.
Thank you!

Thank you for reaching out and sharing your experience.

I understand your frustration and appreciate your patience. Many of our connectors handle the complex task of translating database graph data into a format usable by various applications. The specifics of what you aim to extract from the raw data will influence the best approach to traverse it.

Given that you’re new to Python, I don’t want to overwhelm you with too much detail at once. Knowing more about what you’re trying to achieve and why would be helpful. This way, I can provide the most relevant and straightforward guidance.

@Jedd gave a great talk at SpeckleCon23 about the nature of data in Speckle, and consequently, it isn’t straightforward to point to the URL and create a table, say.

We include a helper function in every Speckle Automate function template that can get you started.

def flatten_base(base: Base) -> Iterable[Base]:
    """Flatten a base object into an iterable of bases.
    
    This function recursively traverses the 
    `elements` or `@elements` attribute of the 
    base object, yielding each nested base object.

    Args:
        base (Base): The base object to flatten.

    Yields:
        Base: Each nested base object in the hierarchy.
    """
    # Attempt to get the elements attribute, 
    elements = getattr(base, "elements", 
               getattr(base, "@elements", None)) # fallback to @elements 
    
    if elements is not None:
        for element in elements:
            yield from flatten_base(element)
    
    yield base

This may not be ideal, and I’m happy to work with you on something more appropriate, but this does give you a flat list of all the Speckle Base objects in a given version commit.

Calling this function will be as simple as following up the transport retrieved from earlier with:

# Receive the object
received_base = operations.receive(obj_id=refObj, remote_transport=transport)


element_list = flatten_base(received_base)

This will give you a flat list of all the Speckle Base objects in the commit. From there, you can filter or manipulate the data as needed. It’s not the end of the story as a Revit dataset can include instances of types and other complications (which we can overcome)

I gave a talk at BILT earlier this month that rapidly goes step-by-step through a Revit dataset that might be interesting to you… but apologies again if this is a Python too far right now: GitHub - specklesystems/automate-function-bilt-workshop

1 Like

If you aren’t already, running all of this in a Jupyter notebook can be a great way to ease your way through, it certainly makes exploring easier, and you may wish to quickly visualise that flat list in a dataframe

import pandas as pd
# Convert the list of base objects to a DataFrame
df = pd.DataFrame([element.get_data_dict() for element in element_list])

# Display the DataFrame (optional)
print(df)
1 Like

Thanks for your help Jonathan!

1 Like