How to keep running the same GraphQL query until x is null? - python

I have a Tableau GraphQL query that requires pagination:
test_1 = """
{
fieldsConnection (
first: 10,
orderBy: {field: NAME, direction: ASC}) {
nodes {
name
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
"""
2nd query:
test_2 = """
{
fieldsConnection (
first: 10,
next: SOME_STRING
orderBy: {field: NAME, direction: ASC}) {
nodes {
name
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
"""
This first query will have hasNextPage = true and endCursor = "huge-ass-string". What I saw in my server is that to extract all fields of interest I need to run the query 13 times!
What I want to do is in Python, using from tableau_api_lib import TableauServerConnection as tsc, write a function that runs the first query (test_1). If hasNextPage is true, than run the second query (test_2) updating the next value to be the value we got from endCursor.
This is how I get the JSON response from my query:
response = conn.metadata_graphql_query(query = test_1)
Is this possible in Python?

I just implemented pagination in the query and kept looping and storing the extracted data in a DataFrame

Related

How to use conditionals on Uniswap GraphQL API pool method?

So I'm new to graphQL and I've been figuring out the Uniswap API, through the sandbox browser, but I'm running this program which just gets metadata on the top 100 tokens and their relative pools, but the pool one isn't working at all. I'm trying to put two conditions of if token0's hash is this and token1's hash is this, it should output the pool of those two, however if only outputs pools with the token0 hash, and just ignores the second one. I've tried using and, _and, or two where's seperated by {} or , so on so forth. This is an example I have (python btw):
class ExchangePools:
def QueryPoolDB(self, hash1, hash2):
query = """
{
pools(where: {token0: "%s"}, where: {token1:"%s"}, first: 1, orderBy:volumeUSD, orderDirection:desc) {
id
token0 {
id
symbol
}
token1 {
id
symbol
}
token1Price
}
}""" % (hash1, hash2)
return query
or in the sandbox explorer this:
{
pools(where: {token0: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"} and: {token1:"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"}, first: 1, orderBy:volumeUSD, orderDirection:desc) {
id
token0 {
id
symbol
}
token1 {
id
symbol
}
token1Price
}
}
with this output:
{
"data": {
"pools": [
{
"id": "0x4585fe77225b41b697c938b018e2ac67ac5a20c0",
"token0": {
"id": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
"symbol": "WBTC"
},
"token1": {
"id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"symbol": "WETH"
},
"token1Price": "14.8094450357546760737720184457113"
}
]
}
}
How can I get the API to register both statements?

How to generate a word cloud using elasticsearch?

I have an elasticsearch DB with data of the form
record = {#all but age are strings
'diagnosis': self.diagnosis,
'vignette': self.vignette,
'symptoms': self.symptoms_list,
'care': self.care_level_string,
'age': self.age, #float
'gender': self.gender
}
I want to create a word cloud of the data in vignette.
I tried all sorts of queries and I get error 400, meaning I don't understand how to query the database.
I am using python
This is the only successful query I was able to come up with
def search_phrase_in_vignettes(self, phrase):
body = {
"_source": ["vignette"],
"query": {
"match_phrase": {
"vignette": {
"query": phrase,
}
}
}
}
res = self.es.search(index=self.index_name, doc_type=self.doc_type, body=body)
Which finds any record with phrase contained in the field `'vignette'
I am thinking some aggregation should do the trick, but I can't seem to be able to write a correct query with 'aggr'.
Would love some help on how to correctly write even the simplest query with aggregation in python.
Use terms aggregation for the approach words count. Your query will be:
{
"query": {
"match_phrase": {
"vignette": {
"query": phrase,
}
}
},
"aggs" : {
"cloud" : {
"terms" : { "field" : "vignette" }
}
}
}
When you receive results take buckets from aggregations key:
res = self.es.search(index=self.index_name, doc_type=self.doc_type, body=body)
for bucket in res['aggregations']['cloud']['buckets']:
rest of build cloud

How to get only a subset of data using graphql?

I have a lengthy query of the github API:
query = """
{
repository(name: "fifteen5", owner: "15five") {
commit: object(expression: "c63a83caf81ef21616392fe5acb84f9655f94d92") {
... on Commit {
associatedPullRequests(first:5){
edges{
node{
title
number
body
}
}
}
}
}
}
}
The returned value is a deepnly nested dictionary - to get the values I want (title, number, and body) I have to do something like this:
# barf!
prs = areplStore['data']['repository']['commit']['associatedPullRequests']['edges']
for pr in prs:
print(pr['node'])
The length of that dictionary access makes my eyes bleed. Is there something I can specify in my graphql query to return only the edges result?
One method that looks slightly cleaner is to use py-jsonq. Unfortuantely this still has a lengthy access.
from pyjsonq import JsonQ
j = JsonQ(data={'data':
{'repository':
{'commit':
{'associatedPullRequests':
{'edges':
[
{'node':
{
'title': 'Add more foobar',
'number': 14253,
'body': 'More foo for the win'
}
}
]
}
}
}
}
}
)
prs = [
edge['node'] for edge in j.at('data.repository.commit.associatedPullRequests.edges').get()
]
print(prs)
https://repl.it/#almenon/json-q-test

How to manipulate an object of Google Ads API's Enum class - python

I am using the python client library to connect to Google Ads's API.
ga_service = client_service.get_service('GoogleAdsService')
query = ('SELECT campaign.id, campaign.name, campaign.advertising_channel_type '
'FROM campaign WHERE date BETWEEN \''+fecha+'\' AND \''+fecha+'\'')
response = ga_service.search(<client_id>, query=query,page_size=1000)
result = {}
result['campanas'] = []
try:
for row in response:
print row
info = {}
info['id'] = row.campaign.id.value
info['name'] = row.campaign.name.value
info['type'] = row.campaign.advertising_channel_type
When I parse the values this is the result I get:
{
"campanas": [
{
"id": <campaign_id>,
"name": "Lanzamiento SIKU",
"type": 2
},
{
"id": <campaign_id>,
"name": "lvl1 - website traffic",
"type": 2
},
{
"id": <campaign_id>,
"name": "Lvl 2 - display",
"type": 3
}
]
}
Why am I getting an integer for result["type"] ? When I check the traceback call I can see a string:
campaign {
resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
id {
value: 397083380
}
name {
value: "Lanzamiento SIKU"
}
advertising_channel_type: SEARCH
}
campaign {
resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
id {
value: 1590766475
}
name {
value: "lvl1 - website traffic"
}
advertising_channel_type: SEARCH
}
campaign {
resource_name: "customers/<customer_id>/campaigns/<campaign_id>"
id {
value: 1590784940
}
name {
value: "Lvl 2 - display"
}
advertising_channel_type: DISPLAY
}
I've searched on the Documentation for the API and found out that it's because the field: advertising_channel_type is of Data Type: Enum. How can I manipulate this object of the Enum class to get the string value? There is no helpful information about this on their Documentation.
Please help !!
The Enum's come with some methods to translate between index and string
channel_types = client_service.get_type('AdvertisingChannelTypeEnum')
channel_types.AdvertisingChannelType.Value('SEARCH')
# => 2
channel_types.AdvertisingChannelType.Name(2)
# => 'SEARCH'
This was found by looking at docstrings, e.g.
channel_types.AdvertisingChannelType.__doc__
# => 'A utility for finding the names of enum values.'
I think the best way to do this is this one liner code:
import proto
row_dict = proto.Message.to_dict(google_ads_row, use_integers_for_enums=False)
This will convert the entire google ads row into a dictionary in just one go and automatically get the ENUM values instead of the numbers.
#Vijaysinh Parmar try following
from google.protobuf import json_format
row_dict = json_format.MessageToJson(row, use_integers_for_enums=False)
Just work around it by, create a list
lookup_list = ['DISPLAY', 'HOTEL', 'SEARCH', 'SHOPPING', 'UNKNOWN', 'UNSPECIFIED', 'VIDEO']
and change the assignment in your last row to
info['type'] = lookup_list[row.campaign.advertising_channel_type]

elasticsearch query - two criteria

I have a list of JSON files in elasticsearch.
I have a list of strings, matching which I want to use as the criteria for a search.
Where, matching = ["223232_ds","dnjsnsd_22","2ee2i33","mkddsj2220","23e3efdjn"
I now need to find those records in elasticsearch where two keys contain values in this list, matching.
Without elasticsearch and simply loading the JSON as a python object I can do this like:
results= []
for record in JSON_list:
if record['key_1'] in matching and record['key_2'] in matching:
results.append(record)
Where the JSON_list looks like this:
[{'key_1' : "blahaksds",
'key_2' : "njasdnjkns"},
{'key_1' : "bladfgfdf",
'key_2' : "njasdsfsdrr"}]
How do I search for multiple criteria in es? Previously, I've used this setup to search for a record_id directly.
es = elasticsearch.Elasticsearch()
name = "so_sample"
# Formulate query
query = str("_id:"+'"'+ record_id +'"')
# Query
result = es.search(name,q=query)
You can use a bool query with two terms queries in the must clause, like this:
{
"query": {
"bool": {
"must": [
{
"terms": {
"key_1": ["223232_ds","dnjsnsd_22","2ee2i33","mkddsj2220","23e3efdjn"]
}
},
{
"terms": {
"key_2": ["223232_ds","dnjsnsd_22","2ee2i33","mkddsj2220","23e3efdjn"]
}
}
]
}
}
}

Categories

Resources