How to get only a subset of data using graphql? - python

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

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?

Why doesn't pymongo MongoDB return an exact value in find_one()?

I want to retrieve the single value "count "from pymongo DB but it is not working. The image below shows how the data entry is setup.
Here is the call to my Database class to use the db.find_one().
CODE HERE:
filters = {"email": session.get('email')}
returns = {f'words.{today_s}.{self.length - 3}.count': 1}
count_value = Database.find_one_return_one("users", filters, returns)
print({f'words.{today_s}.{self.length - 3}.count':1})
print(count_value)
#staticmethod
def find_one_return_one(collection: str, query: Dict, data: Dict) -> Dict:
return Database.DATABASE[collection].find_one(query, data)
This returns an empty list of dictionaries from the correct data? I want the count value returned.
This is the projection query: {words.20220302.0.count : 1}
This is what is returned:
{'_id': ObjectId('621ee5065d08c44070140df0'), 'words': {'20220302': [{}, {}, {}, {}, {}, {}, {}]}}
What is wrong or is there a better quicker way to retrieve the count value?
The following query projection can be used to get the desired result. Note this worked with MongoDB v5.
A sample document; similar to the one in the question post:
{ _id: 1, words: { fld: [ { a: 1, b: 2 }, { a: 9, b: 100 } ] } }
The expected result is: { "_id" : 1, "words" : { "fld" : { "a" : 9 } } }
The query:
INDEX = 1 # this is the index of the array element
query = { }
projection = {
'words.fld': {
'$arrayElemAt': [
{ '$map': { 'input': '$words.fld', 'in': { 'a': '$$this.a' } } },
INDEX
]
}
}
result = collection.find_one(query, projection)
print(result)

Getting error while Formatting request query in Python

I am trying to request a Graphql API through python. I have written the script which is trying to pull audit log from Github for each organisation.
This is the Python script I have written.
Query = """
query {
organization(login: '{}') {
auditLog(first: 100, '{}') {
edges {
node {
... on RepositoryAuditEntryData {
repository {
name
}
}
... on OrganizationAuditEntryData {
organizationResourcePath
organizationName
organizationUrl
}
... on TeamAuditEntryData {
teamName
}
... on TopicAuditEntryData {
topicName
}
... on OauthApplicationAuditEntryData {
oauthApplicationName
}
... on EnterpriseAuditEntryData {
enterpriseResourcePath
enterpriseUrl
enterpriseSlug
}
... on AuditEntry {
actorResourcePath
action
actorIp
actorLogin
operationType
createdAt
actorLocation {
countryCode
country
regionCode
region
city
}
#User 'Action' was performed on
userLogin
userResourcePath
userUrl
}
}
cursor
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
}
}
}
}
"""
l = []
l.append("CoreDevOpsTools")
l.append("JIRA-Cloud")
res = []
for i in range(len(l)):
org = str(l[i])
after = ''
while True:
result = requests.post('https://api.github.com/graphql',
json={'query': Query.format(org,after)},
headers=headers)
json_data = json.loads(result.text)
if 'errors' in json_data:
print(json_data['errors'])
break
res_list = json_data['data']['organization']['auditLog']
for items in res_list['edges']:
res.append(items)
if not res_list['pageInfo']['hasNextPage']:
break
after = 'after: "%s"' % res_list['edges'][-1]['cursor']
time.sleep(1)
File "../AuditLog.py", line 98, in <module>
json={'query': Query.format(org,after)},
KeyError: '\n organization(login'
This is the structure of query in Insomnia/Postman.
query {
organization(login: "CoreDevOpsTools") {
auditLog(first: 100, after: "XYZ") {
edges {
node {
... on RepositoryAuditEntryData {
repository {
name
}
}
... on OrganizationAuditEntryData {
organizationResourcePath
organizationName
organizationUrl
}
... on TeamAuditEntryData {
teamName
}
... on TopicAuditEntryData {
topicName
}
... on OauthApplicationAuditEntryData {
oauthApplicationName
}
... on EnterpriseAuditEntryData {
enterpriseResourcePath
enterpriseUrl
enterpriseSlug
}
... on AuditEntry {
actorResourcePath
action
actorIp
actorLogin
operationType
createdAt
actorLocation {
countryCode
country
regionCode
region
city
}
#User 'Action' was performed on
userLogin
userResourcePath
userUrl
}
}
cursor
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
}
}
}
}
This is error I am getting, I am not able to figure out what is wrong. I looked at other same type of questions here but that didn't work either.
The issue with your code is that the string you're trying to format itself has curly brackets in places where you don't want to replace things. e.g the first line "query {"
You can fix this by doubling the curly brackets. So "{" becomes "{{" etc.
More on this here: stackoverflow.com

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

Python eve: using Sub Resource value in $match

I need to get a value inside an url (/some/url/value as a Sub Resource) usable as a parameter in an aggregation $match :
event/mac/11:22:33:44:55:66 --> {value:'11:22:33:44:55:66'}
and then:
{"$match":{"MAC":"$value"}},
here is a non-working example :
event = {
'url': 'event/mac/<regex("([\w:]+)"):value>',
'datasource': {
'source':"event",
'aggregation': {
'pipeline': [
{"$match": {"MAC":"$value"}},
{"$group": {"_id":"$MAC", "total": {"$sum": "$count"}}},
]
}
}
}
this example is working correctly with :
event/mac/blablabla?aggregate={"$value":"aa:11:bb:22:cc:33"}
any suggestion ?
The real quick and easy way would be to
path = "event/mac/11:22:33:44:55:66"
value = path.replace("event/mac/", "")
# or
value = path.split("/")[-1]

Categories

Resources