GraphQLException: 'You do not have the required privileges.'

HI,
I have produced a couple of streamlist apps, and I am now trying to write one that can link to a Speckle stream and interrogate a Revit model, ultimately to map materials and constructions to embodied carbon figures.

I did try to follow the tutorial at: https://speckle.systems/tutorials/create-your-first-speckle-app-using-only-python/, and integrated the code found there with that provided by chatGPT (which unfortunately suffered from the sep 2021 data )

This is the code I came up with - only a first draft towards a much more articulated final version:


import streamlit as st
from specklepy.api.client import SpeckleClient



# Get the Revit model from Speckle
@st.cache_data()
def get_model(host, token, stream_id):
    # initialise the client
    client = SpeckleClient(host=host)

    # authenticate the client with a token
    client.authenticate(token)

    # get the stream
    # this is a placeholder function. The actual implementation will depend on
    # the structure of the Revit model.
    model = client.stream.get(stream_id)

    # Cache the model data
    # st.cache_data('model', model)

    return model




# Extract the materials and components from the Revit model
def extract_components(model):
    # This is a placeholder function. The actual implementation will depend on
    # the structure of the Revit model.
    pass



def combine_with_carbon(components, carbon_data):
    # This is a placeholder function. The actual implementation will depend on
    # the structure of the components and the carbon_data.
    pass



def main():
    st.title('Embodied Carbon Calculator')


    # User input for the embodied carbon figures
    carbon_data = {}
    materials = ['Material1', 'Material2', 'Material3']  # replace with your actual materials
    for material in materials:
        carbon_data[material] = st.number_input(f'Enter the embodied carbon figure for {material}:')



    # User input for the Speckle server and token
    server = st.text_input(
        'Enter the Speckle server URL:',
        'speckle.xyz',
        help="Speckle server to connect."
        )
    
    token = st.text_input(
        'Enter your Speckle token:',
        '',
        help="If you don't know how to get your token, take a look at this [link](<https://speckle.guide/dev/tokens.html>)👈"
        )

    stream_id = st.text_input(
        'Enter your Speckle Stream:',
        'https://speckle.xyz/streams/eab8e7837c',
        )


    if server and token:
        model = get_model(server, token, stream_id)
        components = extract_components(model)
        result = combine_with_carbon(components, carbon_data)
        st.write(result)

if __name__ == "__main__":
    main()

Whenever I used a Personal Access Token generated following the guidance found here: https://speckle.guide/dev/tokens.html but receive the error:

specklepy.logging.exceptions.GraphQLException: GraphQLException: Failed to execute the GraphQL active_user request. Errors: [{‘message’: ‘You do not have the required privileges.’, ‘locations’: [{‘line’: 2, ‘column’: 3}], ‘path’: [‘activeUser’], ‘extensions’: {‘code’: ‘FORBIDDEN’}}]

2 Likes

Ciao @andrea.botti and welcome to these parts!
Judging from the error, there might be something going on with your access token, what scopes did you select when creating it?
I think streams:read is needed for your app.

@teocomi I had set that up properly, I believe.
I am really puzzled as to what the problem may be.

The following is what I am giving as input to streamlit / specklepy:

PS
Luca Pedrielli says hi!

1 Like

Hey @andrea.botti ,

I am not a Python expert but afais your stream id input is a URL (https://speckle.xyz/streams/eab8e7837c), instead it should be the id of the stream👉(eab8e7837c). We have a StreamWrapper that gives you some handy helpers to deal with URLs. So you can write your code like this:

import streamlit as st
from specklepy.api.client import SpeckleClient
from specklepy.api.wrapper import StreamWrapper

# Get the Revit model from Speckle
@st.cache_data()
def get_model(host, token, stream_id):
    # initialise the client
    client = SpeckleClient(host=host)

    # authenticate the client with a token
    client.authenticate(token)

    # get the stream
    # this is a placeholder function. The actual implementation will depend on
    # the structure of the Revit model.
    model = client.stream.get(stream_id)

    # Cache the model data
    # st.cache_data('model', model)

    return model




# Extract the materials and components from the Revit model
def extract_components(model):
    # This is a placeholder function. The actual implementation will depend on
    # the structure of the Revit model.
    pass



def combine_with_carbon(components, carbon_data):
    # This is a placeholder function. The actual implementation will depend on
    # the structure of the components and the carbon_data.
    pass



def main():
    st.title('Embodied Carbon Calculator')


    # User input for the embodied carbon figures
    carbon_data = {}
    materials = ['Material1', 'Material2', 'Material3']  # replace with your actual materials
    for material in materials:
        carbon_data[material] = st.number_input(f'Enter the embodied carbon figure for {material}:')



    # User input for the Speckle server and token
    server = st.text_input(
        'Enter the Speckle server URL:',
        'speckle.xyz',
        help="Speckle server to connect."
        )
    
    token = st.text_input(
        'Enter your Speckle token:',
        'TOKEN_HERE',
        help="If you don't know how to get your token, take a look at this [link](<https://speckle.guide/dev/tokens.html>)👈"
        )
    
    

    stream_url = st.text_input(
        'Enter your Speckle Stream:',
        'https://speckle.xyz/streams/STREAM_ID',
        )
    # 👇👇👇👇
    wrapper = StreamWrapper(stream_url)
    stream_id = wrapper.stream_id
    # ☝️☝️☝️☝️

    if server and token:
        model = get_model(server, token, stream_id)
        components = extract_components(model)
        result = combine_with_carbon(components, carbon_data)
        st.write(model)

if __name__ == "__main__":
    main()

StreamWrapper also can help with getting authenticated clients and transports. Take a look at this tutorial:

I hope this helps. Let us know if it doesnt.

3 Likes

@gokermu I am bit confused about the various components. So, to break that down, I decided to first run the example you referred to, i.e. https://speckle.systems/tutorials/scheduling-app-for-revit-data/

I did paste the URL from a personal commit, and received the error:

AttributeError: 'SpeckleException' object has no attribute 'referencedObject'

I also intermittently get the following error:

SpeckleException: SpeckleException: Failed to execute the GraphQL commit request. Inner exception: 403 Client Error: Forbidden for url: https://speckle.xyz/graphql

AttributeError: 'SpeckleException' object has no attribute 'referencedObject'

why is it so difficult to authenticate and extract data??

You are right that it shouldn’t be.

From the same machine ate you able to follow to https://speckle.xyz/graphql

I will look through your postings above and check might be going wrong

@jonathon thank you very much for your help.
The link does take a while to open and then it leads to the following:

great, are you running the example pasted by @gokermu here or in the tutorial?

I’ve tried both, and the error does arise in both cases

Reducing the test to the bare minimum

import streamlit as st
from specklepy.api.client import SpeckleClient
from specklepy.api.wrapper import StreamWrapper


def main():
    st.title("Stream Access Test")

    token = st.text_input(
        "Enter your Speckle token:",
        "{{TOKEN}}",  # don't share your token with anyone!!
    )

    stream_url = st.text_input(
        "Enter your Speckle Stream:",
        "https://speckle.xyz/streams/{{STREAM_ID}}",
    )

    # This now uses the StreamWrapper to shortcut from URL 
    # to all the details we need
    wrapper = StreamWrapper(stream_url)

    host = wrapper.host
    stream_id = wrapper.stream_id

    client = SpeckleClient(host)
    client.authenticate_with_token(token)

    if client.account.token is not None:
        # This checks that we authenticate as the user we expected
        st.write(f"Client: {client} ({client.user.account.userInfo.email})")
    else:
        st.write(
            f"Client: {client} ({client.user.account.userInfo.email})",
            "Invalid token"
        )
        return

    stream = client.stream.get(stream_id)
    st.write("Stream: " + str(stream))

if __name__ == "__main__":
    main()

I noticed your example code was defaulting to an ancient token from @gokermu - lets omit that - always good advice to keep those tokens private!!

:point_up_2: This also makes me think of potential internet issues, that URL should load instantly…

The tester script revealed for me that under one pyenv, that specklepy was always resolving to the local default account, regardless of authenticating with the token; this only really affects you if you have a number of accounts and servers, but it did cause me some consternation for a short while.

@jonathon thanks mate. This example works, but so did the previous example I had shared until that point (finally!).

It is when I try to take the script ‘further’, i.e. start interrogating data, that receive the error
AttributeError: 'SpeckleException' object has no attribute 'referencedObject'

@teocomi I see your point, but I actually tried this on 3 different machines connected to different wifi networks!

for the record, the ‘minimum working example’ you provided return successfully the following:

right so which version of which code are we working to get working - as that should be all you need, but I lost track with your posts of both code and tutorials that were different things?

I have a hunch that streamlits data caching may be an arse here, but I’m not a streamlit expert

@jonathon my bad, I have not been very clear due to the frustration to get this to work.

There were two elements of the code provided in on of the two examples that are available online (https://speckle.systems/tutorials/scheduling-app-for-revit-data/) that I struggled to make work:

1. Getting stream and authorising via a token
which was returning the specklepy.logging.exceptions.GraphQLException: error: I have solved that by deleting my personal access token (streams:read apparently was not sufficient) and recreating a new one with everything authorised. I have also tested your minimum example on that and it works well - thanks!

2. Extracting data
Whatever happens later is a bit unclear to me.

I consider myself decent in python and ok with streamlit, but all the object retrieval using the commits and everything happening after that is still a bit confusing for me.
From another tutorial example @gokermu posted (
https://speckle.systems/tutorials/create-your-first-speckle-app-using-only-python/ it seems this can be chosen within the app menus, so it may be a question to mix and match the code from the two.

Specifically here the issue is that the following code section:

# COMMIT 🍀
# gets a commit given a stream and the commit id
commit = client.commit.get(wrapper.stream_id, wrapper.commit_id)
# get obj id from commit
obj_id = commit.referencedObject
# receive objects from commit
commit_data = operations.receive(obj_id, transport)

returns the error: AttributeError: 'SpeckleException' object has no attribute 'referencedObject'

and this happened when I ran the example file (main.py) provided by @gokermu

2 Likes

print the result of this:

commits = client.commit.list(stream_id=stream_id, limit=2)

and report back

1 Like

0 : "Commit( id: 82b1ca6635, message: Sent 314 objects from Revit2023., referencedObject: fa22dd42105ba0f4a606b7cc054d241c, authorName: Remo Fabrizi, branchName: main, createdAt: 2023-06-06 14:41:52.443000+00:00 )"
which seems promising.