Как получить плоский массив в качестве ответа от сервера GraphQL

#python #arrays #json #pandas #graphql

#python #массивы #json #pandas #graphql

Вопрос:

У меня возникли трудности с некоторыми запросами GraphQL к веб-сервису. Проблема немного сложная, надеюсь, я постараюсь объяснить ее разумно.

Проблема связана с тем фактом, что одно из полей, которые меня интересуют, является не скалярным, а массивом. Я хочу вернуть одно значение в этом массиве на основе сопоставления строк, что невозможно только с GraphQL, если я правильно понимаю.

Итак, я полагаю, что позже я выполню фильтрацию в python и просто возьму их все. Однако в этом случае проблема заключается в том, что я не могу легко обработать столбцы, поскольку это встроенный массив json в pandas.

Следующий код показывает минимальный пример, в котором я получаю вложенную строку json (массив пар имя: значение) в поле xrefs вместо массива.

 query = 
    f"""
    {{
      targets(
        filter: {{
          facets: [{{
            facet: "Target Development Level",
            values: ["Tchem"]
          }}]
        }}
      ) {{
        targets(top:10){{
            xrefs (source: "Ensembl"){{name}}
            sym
            tdl
            uniprot

          }}
      }}
    }}
    """
url = 'https://pharos-api.ncats.io/graphql'
r = requests.post(url, json={'query': query})
json_data = json.loads(r.text)
df = pd.read_json(json.dumps(json_data['data']['targets']['targets']), orient='records')
 

Чего я хочу добиться в порядке предпочтения:

  1. Иметь возможность выбирать одно значение на xrefs основе сопоставления строк при name использовании только GraphQL
  2. Получите массив строк для xrefs вместо пар имя: значение, опять же из GQL
  3. Попросите pandas / python проанализировать и сгладить json xrefs , чтобы я получил список строк вместо чего-то вроде:

    [{‘name’: ‘ENST00000260967’}, {‘name’: ‘ENSP00000260967’}, {‘name’: ‘ENSG00000138395’}, {‘name’: ‘ENST00000410091’}, {‘name’: ‘ENSP00000386901’}, {‘name’: ‘ENST00000434439’}, {‘name’: ‘ENSP00000412775’}, {‘name’: ‘ENST00000450471’}, {‘name’: ‘ENSP00000406472’}]

Ответ №1:

Что-то вроде этого:

 import json
import requests

query = f"""
{{
    targets(
    filter: {{
        facets: [{{
        facet: "Target Development Level",
        values: ["Tchem"]
        }}]
    }}
    ) {{
    targets(top:10){{
        xrefs (source: "Ensembl"){{name}}
        sym
        tdl
        uniprot
        }}
    }}
}}
"""

url = "https://pharos-api.ncats.io/graphql"
r = requests.post(url, json={"query": query})
data = r.json()["data"]["targets"]["targets"]

# Flatten the xrefs
for row in data:
    row["xrefs"] = [element["name"] for element in row["xrefs"]]

print(json.dumps(data, indent=2))
 

Вывод:

 [
  {
    "xrefs": [
      "ENST00000312988",
      "ENSP00000318197",
      "ENSG00000152086"
    ],
    "sym": "TUBA3E",
    "tdl": "Tchem",
    "uniprot": "Q6PEY2"
  },
  {
    "xrefs": [
      "ENST00000399635",
      "ENSP00000382544",
      "ENSG00000206203"
    ],
    "sym": "TSSK2",
    "tdl": "Tchem",
    "uniprot": "Q96PF2"
  },
  {
    "xrefs": [
      "ENST00000612221",
      "ENSP00000483467",
      "ENSG00000231274"
    ],
    "sym": "SBK3",
    "tdl": "Tchem",
    "uniprot": "P0C264"
  },
  {
    "xrefs": [
      "ENST00000251472",
      "ENSP00000251472",
      "ENSG00000105613"
    ],
    "sym": "MAST1",
    "tdl": "Tchem",
    "uniprot": "Q9Y2H9"
  },
  {
    "xrefs": [
      "ENST00000260967",
      "ENSP00000260967",
      "ENSG00000138395",
      "ENST00000410091",
      "ENSP00000386901",
      "ENST00000434439",
      "ENSP00000412775",
      "ENST00000450471",
      "ENSP00000406472"
    ],
    "sym": "CDK15",
    "tdl": "Tchem",
    "uniprot": "Q96Q40"
  },
  {
    "xrefs": [
      "ENST00000238789",
      "ENSP00000238789",
      "ENSG00000119778"
    ],
    "sym": "ATAD2B",
    "tdl": "Tchem",
    "uniprot": "Q9ULI0"
  },
  {
    "xrefs": [
      "ENST00000358371",
      "ENSP00000351140",
      "ENSG00000176601",
      "ENST00000375844",
      "ENSP00000365004",
      "ENST00000375845",
      "ENSP00000365005",
      "ENST00000392915",
      "ENSP00000376647",
      "ENST00000392917",
      "ENSP00000376649",
      "ENST00000392918",
      "ENSP00000376650"
    ],
    "sym": "MAP3K19",
    "tdl": "Tchem",
    "uniprot": "Q56UN5"
  },
  {
    "xrefs": [
      "ENST00000456354",
      "ENSP00000390423",
      "ENSG00000188782",
      "ENST00000518899",
      "ENSP00000429464"
    ],
    "sym": "CATSPER4",
    "tdl": "Tchem",
    "uniprot": "Q7RTX7"
  },
  {
    "xrefs": [
      "ENST00000370435",
      "ENSP00000359464",
      "ENSG00000119900"
    ],
    "sym": "OGFRL1",
    "tdl": "Tchem",
    "uniprot": "Q5TC84"
  },
  {
    "xrefs": [
      "ENST00000321751",
      "ENSP00000319778",
      "ENSG00000175756",
      "ENST00000338338",
      "ENSP00000340656",
      "ENST00000338370",
      "ENSP00000342676",
      "ENST00000378853",
      "ENSP00000368130"
    ],
    "sym": "AURKAIP1",
    "tdl": "Tchem",
    "uniprot": "Q9NWT8"
  }
]