Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to cast a quiz.Query to JSON? #114

Open
g-k opened this issue Mar 16, 2019 · 4 comments
Open

how to cast a quiz.Query to JSON? #114

g-k opened this issue Mar 16, 2019 · 4 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@g-k
Copy link
Contributor

g-k commented Mar 16, 2019

Thanks for writing quiz it's been really helpful!

Not sure if there's a better to do this, but I've been paging over github repo adjacent data and extending edges to bulid out a quiz.Query object: https://github.com/mozilla-services/find-package-rugaru/blob/d89ddf661a8c36f6a68e6ae87f624df486571718/bin/fetch_github_metadata_for_repo.py

I'd like to serialize the Query to JSON. Is there a way to do that?

Something like the inverse of load. I've been staring at the quiz.utils.JSON, which seems like the right type to use, but I thought I'd ask the expert. Thanks!

@ariebovenberg
Copy link
Owner

hi @g-k, what do you mean exactly by serializing a Query to JSON?
Perhaps a simple example can help.

If a query looks like this:

query = schema.query[
    _
    .repository(owner='octocat', name='hello-world')[
        _
        .createdAt
        .description
    ]
]

as graphql:

>>> str(query)
query {
  repository(owner: "octocat", name: "Hello-World") {
    createdAt
    description
  }
}

What would you like the JSON serialized result to look like?

Like this?

>>> import json
>>> json.dumps(str(query))
'"query {\\n  repository(owner: \\"octocat\\", name: \\"Hello-World\\") {\\n    createdAt\\n    description\\n  }\\n}"'

@ariebovenberg ariebovenberg added the question Further information is requested label Mar 16, 2019
@g-k
Copy link
Contributor Author

g-k commented Mar 18, 2019

@ariebovenberg I'm interested in the response data. e.g. for the GQL query above:

>>> str(query)
query {
  repository(owner: "octocat", name: "hello-world") {
    createdAt
    description
  }
}

I can get the response as a Query object and as a JSON string:

>>> exec(query)
Query(repository=Repository(createdAt='2011-01-26T19:01:12Z', description='My first repository on GitHub!'))
>>> exec(str(query))
{'repository': {'createdAt': '2011-01-26T19:01:12Z', 'description': 'My first repository on GitHub!'}}

Is there a way to take a python response object and schema and serialize it to JSON? (the inverse of loading a JSON file + schema and populating python object would be good too but I think load does that). Basically, deferring the JSON serialization of the Python response object.

@g-k
Copy link
Contributor Author

g-k commented Mar 18, 2019

To expand: my use case is populating a response Python object with additional data from multiple responses from pagination e.g.

>>> str(query)
query {
  repository(owner: "octocat", name: "linguist") {
    createdAt
    description
    languages(first: 1) {
      pageInfo {
        hasNextPage
        endCursor
      }
      totalCount
      totalSize
      edges {
        node {
          id
          name
        }
      }
    }
  }
}
>>> repo = exec(query)
>>> repo
Query(repository=Repository(createdAt='2016-08-02T17:35:14Z', description="Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", languages=LanguageConnection(pageInfo=PageInfo(hasNextPage=True, endCursor='Y3Vyc29yOnYyOpHONHyIeA=='), totalCount=2, totalSize=205775, edges=[LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxNDE=', name='Ruby'))])))
>>> exec(str(query))
{'repository': {'createdAt': '2016-08-02T17:35:14Z', 'description': "Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", 'languages': {'pageInfo':{'hasNextPage': True, 'endCursor': 'Y3Vyc29yOnYyOpHONHyIeA=='}, 'totalCount': 2, 'totalSize': 205775, 'edges': [{'node': {'id': 'MDg6TGFuZ3VhZ2UxNDE=', 'name': 'Ruby'}}]}}}
>>> assert repo.repository.languages.pageInfo.hasNextPage
>>> next_lang_query =  schema.query[
...     _
...     .repository(owner='octocat', name='linguist')[
...         _
...         .createdAt
...         .description
...         .languages(
...             first=1, after=repo.repository.languages.pageInfo.endCursor
...         )[
...             _.pageInfo[_.hasNextPage.endCursor].totalCount.totalSize.edges[
...                 _.node[_.id.name]
...             ]
...         ]
...     ]
... ]
>>> str(next_lang_query)
query {
  repository(owner: "octocat", name: "linguist") {
    createdAt
    description
    languages(first: 1, after: "Y3Vyc29yOnYyOpHONHyIeA==") {
      pageInfo {
        hasNextPage
        endCursor
      }
      totalCount
      totalSize
      edges {
        node {
          id
          name
        }
      }
    }
  }
}
>>> next_lang_repo = exec(next_lang_query)
>>> next_lang_repo
Query(repository=Repository(createdAt='2016-08-02T17:35:14Z', description="Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", languages=LanguageConnection(pageInfo=PageInfo(hasNextPage=False, endCursor='Y3Vyc29yOnYyOpHONHyIeQ=='), totalCount=2, totalSize=205775, edges=[LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxMzk=', name='Shell'))])))
>>> exec(str(next_lang_query))
{'repository': {'createdAt': '2016-08-02T17:35:14Z', 'description': "Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", 'languages': {'pageInfo': {'hasNextPage': False, 'endCursor': 'Y3Vyc29yOnYyOpHONHyIeQ=='}, 'totalCount': 2, 'totalSize': 205775, 'edges': [{'node': {'id': 'MDg6TGFuZ3VhZ2UxMzk=', 'name': 'Shell'}}]}}}
>>> # combine pages of query responses                                                                                                                                                                 
>>> repo.repository.languages.edges.extend(next_lang_repo.repository.languages.edges)
>>> repo
Query(repository=Repository(createdAt='2016-08-02T17:35:14Z', description="Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", languages=LanguageConnection(pageInfo=PageInfo(hasNextPage=True, endCursor='Y3Vyc29yOnYyOpHONHyIeA=='), totalCount=2, totalSize=205775, edges=[LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxNDE=', name='Ruby')), LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxMzk=', name='Shell'))])))
>>> str(repo)
Query(repository=Repository(createdAt='2016-08-02T17:35:14Z', description="Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", languages=LanguageConnection(pageInfo=PageInfo(hasNextPage=True, endCursor='Y3Vyc29yOnYyOpHONHyIeA=='), totalCount=2, totalSize=205775, edges=[LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxNDE=', name='Ruby')), LanguageEdge(node=Language(id='MDg6TGFuZ3VhZ2UxMzk=', name='Shell'))])))
>>> 

Is there something like?

>>> quiz.dump(combined_repo, schema, type=quiz.utils.JSON)  # or json.dumps
{'repository': {'createdAt': '2016-08-02T17:35:14Z', 'description': "Language Savant. If your repository's language is being reported incorrectly, send us a pull request!", 'languages': {'pageInfo': {'hasNextPage': False, 'endCursor': 'Y3Vyc29yOnYyOpHONHyIeQ=='}, 'totalCount': 2, 'totalSize': 205775, 'edges': [{'node': {'id': 'MDg6TGFuZ3VhZ2UxNDE=', 'name': 'Ruby'}}, {'node': {'id': 'MDg6TGFuZ3VhZ2UxMzk=', 'name': 'Shell'}}]}}}

#22 might be related.

@ariebovenberg
Copy link
Owner

Hmm, I guess it makes sense for the raw JSON to be accessible in a query. I'll see if I can fit it into a coming release.

As a current workaround, you can use the request metadata (introduced in 0.1.5):

result = quiz.execute(next_lang_query)
as_json = json.loads(result.__metadata__.response.content.decode())

I don't know about retrieving an object, mutating it, and dumping it back to JSON though...

@ariebovenberg ariebovenberg added enhancement New feature or request question Further information is requested and removed question Further information is requested labels Mar 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants