【问题标题】:How to update variables in a GraphQL request in Python?如何在 Python 中更新 GraphQL 请求中的变量?
【发布时间】:2021-06-22 12:35:43
【问题描述】:

我是 GraphQL 新手,需要编写一个 Python 函数来更新 2 个 ID 类型(videoIdtrackId)作为变量,每个变量的数量为 10。它们存储在mapped_ids 列表中,该列表由以下形式的 10 个元组组成:('video ID', 'track ID')。

我的目标是编写一个函数,为我在mapped_ids 列表中获得的 10 个 ID 对中的每一个更新查询变量。所以基本上,每个视频都应该得到一个单独的请求,包括视频 ID 和轨道 ID。

使用我当前的方法(位于下面代码的最后),变量总是被覆盖,这就是为什么只考虑mapped_ids 列表的最后一个 ID 对的原因。使用一对 ID,我的代码就可以工作。

我的代码:

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)

不幸的是,尽管我已经做了很多研究,但我还是无法全神贯注地编写所需的函数。

JSON 响应示例:

{'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'}]}}]},

编辑:

在考虑了 Bijay Regmi 的解决方案后,如果我打印出来,我的代码和查询现在看起来像这样:

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
                         }
                     }
                 }
             }
         }
    }
}

现在我收到错误消息

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'}}]}

【问题讨论】:

  • 你能发布一个响应json的样本吗?
  • @BijayRegmi 当然,我刚刚添加了请求的样本。我希望这会有所帮助。
  • 那么您基本上是想更新GET_TRACK_URLS 中的那些id 并获取内容?
  • 是的,我想编写一个函数来更新GET_TRACK_URLS 中的 idtrackId 变量,这样我就可以轻松运行几次一百首曲目。

标签: python-3.x graphql


【解决方案1】:

编辑:新方法: 由于似乎存在变量不匹配,我已经在您编写的内容之上完全重新创建了代码,所以请根据您的数据填充mapped_ids变量。

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)

第一次尝试:

我尝试了string.replace() 之类的方法,因为将 ID 插入必填字段似乎是最简单的方法。下面是我尝试过的示例代码,它适用于我创建的示例。

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)

打印:

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
                         }
                     }
                 }
             }
         }
    }
}

附言我不确定每个ID 之后的! 是否是有意的,所以我保留了它。

【讨论】:

  • 感谢您的回答,我会尝试并告诉您是否有效。问题是,我读到字符串的替换就像“滥用 graphQL”(stackoverflow.com/questions/62384215/…),这就是我到目前为止还没有尝试过的原因。但我现在会的。
  • 如果你想做更多的graphQL方式,你可以做类似query GetUrls($id: [VIDEO_ID!]!, $trackId: [TRACK_ID!]!) {的事情,然后你创建一个新的dict,其中包含你传递的变量列表,比如variables = {'id' : videoID, 'trackID' : trackID},但是你必须创建一个graphql您定义 VIDEO_ID 和 TRACK_ID 的架构。完成此操作后,您可以向端点创建请求,您可以在其中将 variables 定义为 r = requests.post(url, json={'query': your_query , 'variables': variables}),端点将自动决定什么属于哪里!
  • 我已经尝试过您的第一个解决方案,稍微调整了一下(需要交换 videoId 和 trackId),现在我收到错误消息:'message': 'Variable "$id" of required type "ID!" was not provided.'(完整的错误消息以及我的更新的代码可以在我帖子的最后看到)。我不知道现在出了什么问题。
  • 我看到您已将查询修改为在您的示例中看起来像 query GetUrls($id: ID!, $trackId: ID!) { video(id: b8bce3e0-6b84-18jb-b741-7b3016ed7f01) {,我认为正确的方法是 query GetUrls($id: b8bce3e0-6b84-18jb-b741-7b3016ed7f01, $trackId: ID!) { video(id: $id) {
  • 我们需要在GetUrls 中指定$id 并使用id: $id 将其传递给嵌套类别
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2021-05-23
  • 2019-02-08
相关资源
最近更新 更多