0

I'm new to GraphQL and need to write a Python function that updates 2 ID types (videoId and trackId) as variables, each 10 in number. They are stored in a mapped_ids list, which consists of 10 tupels in the following form: ('video ID', 'track ID').

My goal is to write a function that updates the query's variables for each of the 10 ID pairs that I got in the mapped_ids list. So basically, each video should get a separate request including video ID and track ID.

With my current approach (being at the very end of the code below), the variables are always overwritten, which is why only the last ID pair of the mapped_ids list are considered. With one single pair of IDs, my code works.

My code:

import requests

endpoint = 'endpoint of your choice'

# Query containing video and track ID of German track as variables.
GET_TRACK_URLS = '''
query GetUrls($id: ID!, $trackId: ID!) {
    video(id: $id) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: $trackId) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}
''' 

# POST GraphQL request and parse response.
def run_query(query, variables):
    response = requests.post(
        endpoint,
        json={'query': query, 'variables': variables},
    )
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f'Query failed with a {response.status_code}: {response.json()}')


# Approach 1 to update variables (not successful so far):
for video_id, track_id in mapped_ids:
    video_id = video_id
    track_id = track_id
data2 = run_query(GET_TRACK_URLS, {'id': video_id, 'trackId': track_id})


# Approach 2 to update variables (not successful so far):
my_variables = {}
for video_id, track_id in mapped_ids:
    my_variables['id'] = video_id
    my_variables['trackId'] = track_id
data2 = run_query(GET_TRACK_URLS, my_variables)

Unfortunately I can't wrap my head around writing the desired function, even though I already did a lot of research.

A sample of the JSON response:

{'data': {'video': {'id': 'c0deeabc-6b12-11eb-b741-7b3016ed7f39', 'voices': "
 "[{'id': '745b74d0-7b48-11eb-9e5f-7fc87d0ed7ca', 'dubbingSegments': "
 "[{'start': 140, 'duration': 3539, 'meta': [{'text': 'Heute geht es bei uns "
 "um Reptilien.', 'trackId': '9mn86640-87c0-11eb-a09e-ad706c66b842', 'asset': "
 "{'representations': [{'href': "
 "'https://arbitraryurl.com/5dbb3m88-87c0-11eb-a09e-ad741a76b842/original?av=1'}]}}]}, "
 "{'start': 3700, 'duration': 6469, 'meta': [{'text': 'Im Gegensatz zu "
 'Säugetieren, Amphibien, Vögeln und Fischen, die wir bereits behandelt '
 "haben,', 'trackId': '7bn86640-80c0-11eb-a09e-ad706a76b851', 'asset': "
 "{'representations': [{'href': "
 "'https://arbitraryurl.com/5daa1l79-87c0-11eb-a09e-ad706m16b842/original?av=1'}]}}]}, "
 "{'start': 10170, 'duration': 3099, 'meta': [{'text': 'haben Reptilien "
 "außergewöhnliche Schuppen.', 'trackId': "
 "'5da82140-87c0-11bm-a09e-ad706a76b842', 'asset': {'representations': "
 "[{'href': "
 "'https://arbitraryurl.com/5daa5341-87c0-11eb-a09e-ad706a76b842/original?av=1'}]}}]},

Edit:

After considering Bijay Regmi's solution, my code and my query now looks like this if I print it:

for elem in mapped_ids:
    query_string = GET_TRACK_URLS.replace('(id: $id)','(id: "' + elem[0] + '")')
    query_string = query_string.replace('(trackId: $trackId)', '(trackId: "' + elem[1] + '")')
    print(query_string)

data = run_query(GET_TRACK_URLS, {})
print('\nDATA:\n', data)  # Debug.


query GetUrls($id: ID!, $trackId: ID!) {
    video(id: b8bce3e0-6b84-18jb-b741-7b3016ed7f01) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: 5bv76640-09c0-11eb-a09e-ad706a76b873) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}

Now I'm getting the error message:

Exception: Query failed with a 400: 
{'errors': [{'message': 'Variable "$id" of required type "ID!" was not provided.', 
'locations': [{'line': 2, 'column': 15}], 'extensions': {'code': 'INTERNAL_SERVER_ERROR'}}, 
{'message': 'Variable "$trackId" of required type "ID!" was not provided.', 'locations': [{'line': 2, 'column': 25}], 'extensions': {'code': 'INTERNAL_SERVER_ERROR'}}]}
4
  • could you post a sample of response json? Commented Mar 26, 2021 at 8:27
  • @BijayRegmi Sure, I just added the requested sample. I hope that helps. Commented Mar 26, 2021 at 8:49
  • So you basically want to update those ids in GET_TRACK_URLS and fetch the content? Commented Mar 26, 2021 at 8:55
  • Yes, I want to write a function that updates the id and trackId variables in GET_TRACK_URLS so that I can run this easily for several hundred tracks. Commented Mar 26, 2021 at 9:04

1 Answer 1

1

Edit: new approach: Since there seems to exist a mismatch of variable, I have completely recreated the code on top of what you had written, so please populate the mapped_ids variable as per your data.

import requests

def run_query(query, variables):
   endpoint = "https://api.myserver.de"

   response = requests.post(
       endpoint,
       json={'query': query, 'variables': variables},
   )
   if response.status_code == 200:
       return response.json()
   else:
       raise Exception(f'Query failed with a {response.status_code}: {response.json()}')

GET_TRACK_URLS = '''
query GetUrls($id: ID!, $trackId: ID!) {
   video(id: $id) {
       id
        voices {
            id
            dubbingSegments {
                start
                duration
                meta(trackId: $trackId) {
                    text
                    trackId
                    asset {
                        representations {
                            href
                        }
                    }
                }
            }
        }
   }
}
''' 
mapped_ids = [["video_id_1","track_id_1"], ["video_id_2", "track_id_2"]]

for video_id, track_id in mapped_ids:
   my_variables = {}
   my_variables['id'] = video_id
   my_variables['trackId'] = track_id
   resp_data = run_query(GET_TRACK_URLS, my_variables)
   print(resp_data)

''' 
mapped_ids = [["video_id_1","track_id_1"], ["video_id_2", "track_id_2"]]

for video_id, track_id in mapped_ids:
   my_variables = {}
   my_variables['video_ID'] = video_id
   my_variables['track_ID'] = track_id
   resp_data = run_query(GET_TRACK_URLS, my_variables)
   print(resp_data)

First Attempt:

I tried something like string.replace() as it seems to be the easiest to insert the IDs into required fields. Below is a sample code I tried and it works for my sample I created.

GET_TRACK_URLS = '''
query GetUrls($id: ID!, $trackId: ID!) {
    video(id: $id) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: $trackId) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}
''' 

id_list = [("t1","v1"),("t2","v2"),("t3","v3")] #trackID and videoIDs i created as sample.

for elem in id_list:
    QUERY_STRING = GET_TRACK_URLS.replace("$id: ID!","$id: " + elem[1] + "!")
    QUERY_STRING = QUERY_STRING.replace("$trackId: ID!", "$trackId: "+ elem[0] +"!")
    print(QUERY_STRING)

prints :

query GetUrls($id: v1!, $trackId: t1!) {
    video(id: $id) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: $trackId) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}


query GetUrls($id: v2!, $trackId: t2!) {
    video(id: $id) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: $trackId) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}


query GetUrls($id: v3!, $trackId: t3!) {
    video(id: $id) {
        id
         voices {
             id
             dubbingSegments {
                 start
                 duration
                 meta(trackId: $trackId) {
                     text
                     trackId
                     asset {
                         representations {
                             href
                         }
                     }
                 }
             }
         }
    }
}

p.s. I was not sure if ! after each ID was intended so I kept it.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for your answer, I'll try it out and let you know if it works. The thing is, I've read that the replacement of strings is like "abusing graphQL" (stackoverflow.com/questions/62384215/…) which is why I haven't tried it out so far. But I will now.
If you want to do a more graphQL way, you can do something like query GetUrls($id: [VIDEO_ID!]!, $trackId: [TRACK_ID!]!) { and you create a new dict with list of variables you pass like variables = {'id' : videoID, 'trackID' : trackID} but then you have to create a graphql schema where you define VIDEO_ID and TRACK_ID. Once you do that, you can create request to your endpoint where you can just define variables as r = requests.post(url, json={'query': your_query , 'variables': variables}) and the endpoint will decide automatically what belongs where!
I have tried your first solution approach, adjusted it a little (videoId and trackId needed to be exchanged) and now I'm getting the error message: 'message': 'Variable "$id" of required type "ID!" was not provided.' (full error message as well as my updated code can be seen at the very end of my post). I don't know what's wrong now.
I see that you have modified the query to look like query GetUrls($id: ID!, $trackId: ID!) { video(id: b8bce3e0-6b84-18jb-b741-7b3016ed7f01) { in your example, i think the correct way would be query GetUrls($id: b8bce3e0-6b84-18jb-b741-7b3016ed7f01, $trackId: ID!) { video(id: $id) {
We need to specify $id in GetUrls and pass it on to nested categories with id: $id
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.