在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):profusion/sgqlc开源软件地址(OpenSource Url):https://github.com/profusion/sgqlc开源编程语言(OpenSource Language):Python 98.5%开源软件介绍(OpenSource Introduction):sgqlc - Simple GraphQL ClientIntroductionThis package offers an easy to use GraphQL client. It's composed of the following modules:
What's GraphQL?Straight from http://graphql.org:
It was created by Facebook based on their problems and solutions using REST to develop applications to consume their APIs. It was publicly announced at React.js Conf 2015 and started to gain traction since then. Right now there are big names transitioning from REST to GraphQL: Yelp Shopify and GitHub, that did an excellent post to explain why they changed. A short list of advantages over REST:
From GitHub's Migrating from REST to GraphQL one can see these in real life: $ curl -v https://api.github.com/orgs/github/members [ { "login": "...", "id": 1234, "avatar_url": "https://avatars3.githubusercontent.com/u/...", "gravatar_id": "", "url": "https://api.github.com/users/...", "html_url": "https://github.com/...", "followers_url": "https://api.github.com/users/.../followers", "following_url": "https://api.github.com/users/.../following{/other_user}", "gists_url": "https://api.github.com/users/.../gists{/gist_id}", "starred_url": "https://api.github.com/users/.../starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/.../subscriptions", "organizations_url": "https://api.github.com/users/.../orgs", "repos_url": "https://api.github.com/users/.../repos", "events_url": "https://api.github.com/users/.../events{/privacy}", "received_events_url": "https://api.github.com/users/.../received_events", "type": "User", "site_admin": true }, ... ] brings the whole set of member information, however you just want name and avatar URL: query { organization(login:"github") { # select the organization members(first: 100) { # then select the organization's members edges { # edges + node: convention for paginated queries node { name avatarUrl } } } } } Likewise, instead of 4 HTTP requests: curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9 curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9/commits curl -v https://api.github.com/repos/profusion/sgqlc/issues/9/comments curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9/reviews A single GraphQL query brings all the needed information, and just the needed information: query { repository(owner: "profusion", name: "sgqlc") { pullRequest(number: 9) { commits(first: 10) { # commits of profusion/sgqlc PR #9 edges { node { commit { oid, message } } } } comments(first: 10) { # comments of profusion/sgqlc PR #9 edges { node { body author { login } } } } reviews(first: 10) { # reviews of profusion/sgqlc/ PR #9 edges { node { state } } } } } } Motivation to create sgqlcAs seen above, writing GraphQL queries is very easy, and it is equally easy to interpret the results. So what was the rationale to create sgqlc?
It also helps with code-generation, InstallationAutomatic: pip install sgqlc From source using pip install . UsageTo reach a GraphQL endpoint using synchronous HTTPEndpoint with a
hand-written query (see more at from sgqlc.endpoint.http import HTTPEndpoint
url = 'http://server.com/graphql'
headers = {'Authorization': 'bearer TOKEN'}
query = 'query { ... }'
variables = {'varName': 'value'}
endpoint = HTTPEndpoint(url, headers)
data = endpoint(query, variables) However, writing GraphQL queries and later interpreting the results
may be cumbersome. That's solved by our query { repository(owner: "profusion", name: "sgqlc") { issues(first: 100) { nodes { number title } pageInfo { hasNextPage endCursor } } } } The output JSON object is: {
"data": {
"repository": {
"issues": {
"nodes": [
{"number": 1, "title": "..."},
{"number": 2, "title": "..."}
]
},
"pageInfo": {
"hasNextPage": false,
"endCursor": "..."
}
}
}
} from sgqlc.endpoint.http import HTTPEndpoint
from sgqlc.types import Type, Field, list_of
from sgqlc.types.relay import Connection, connection_args
from sgqlc.operation import Operation
# Declare types matching GitHub GraphQL schema:
class Issue(Type):
number = int
title = str
class IssueConnection(Connection): # Connection provides page_info!
nodes = list_of(Issue)
class Repository(Type):
issues = Field(IssueConnection, args=connection_args())
class Query(Type): # GraphQL's root
repository = Field(Repository, args={'owner': str, 'name': str})
# Generate an operation on Query, selecting fields:
op = Operation(Query)
# select a field, here with selection arguments, then another field:
issues = op.repository(owner=owner, name=name).issues(first=100)
# select sub-fields explicitly: { nodes { number title } }
issues.nodes.number()
issues.nodes.title()
# here uses __fields__() to select by name (*args)
issues.page_info.__fields__('has_next_page')
# here uses __fields__() to select by name (**kwargs)
issues.page_info.__fields__(end_cursor=True)
# you can print the resulting GraphQL
print(op)
# Call the endpoint:
data = endpoint(op)
# Interpret results into native objects
repo = (op + data).repository
for issue in repo.issues.nodes:
print(issue) Why double-underscore and overloaded arithmetic methods?Since we don't want to clobber GraphQL fields, we cannot provide
nicely named methods. Therefore we use overloaded methods such as
To select fields by name, use # just 'a' and 'b'
type_selection.__fields__('a', 'b')
type_selection.__fields__(a=True, b=True) # equivalent
# a(arg1: value1), b(arg2: value2):
type_selection.__fields__(
a={'arg1': value1},
b={'arg2': value2})
# selects all possible fields
type_selection.__fields__()
# all but 'a' and 'b'
type_selection.__fields__(__exclude__=('a', 'b'))
type_selection.__fields__(a=False, b=False) Code GeneratorManually converting an existing GraphQL schema to user@host$ python3 -m sgqlc.introspection \
--exclude-deprecated \
--exclude-description \
-H "Authorization: bearer ${GH_TOKEN}" \
https://api.github.com/graphql \
github_schema.json
user@host$ sgqlc-codegen schema github_schema.json github_schema.py This generates from sgqlc.operation import Operation
from github_schema import github_schema as schema
op = Operation(schema.Query) # note 'schema.'
# -- code below follows as the original usage example:
# select a field, here with selection arguments, then another field:
issues = op.repository(owner=owner, name=name).issues(first=100)
# select sub-fields explicitly: { nodes { number title } }
issues.nodes.number()
issues.nodes.title()
# here uses __fields__() to select by name (*args)
issues.page_info.__fields__('has_next_page')
# here uses __fields__() to select by name (**kwargs)
issues.page_info.__fields__(end_cursor=True)
# you can print the resulting GraphQL
print(op)
# Call the endpoint:
data = endpoint(op)
# Interpret results into native objects
repo = (op + data).repository
for issue in repo.issues.nodes:
print(issue) You can also generate these operations given a GraphQL Domain Specific Language (DSL) operation: # sample_operations.gql query ListIssues($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { issues(first: 100) { nodes { number title } pageInfo { hasNextPage endCursor } } } } user@host$ sgqlc-codegen operation \
--schema github_schema.json \
github_schema \
sample_operations.py \
sample_operations.gql This generates from sample_operations import Operations
op = Operations.query.list_issues
# you can print the resulting GraphQL
print(op)
# Call the endpoint:
data = endpoint(op, {'owner': owner, 'name': name})
# Interpret results into native objects
repo = (op + data).repository
for issue in repo.issues.nodes:
print(issue) AuthorsLicensesgqlc is licensed under the ISC. Getting started developingYou need to use pipenv. pipenv install --dev pipenv shell Install the git hooks: ./utils/git/install-git-hooks.sh Run the tests (one of the below): ./utils/git/pre-commit # flake8 and nose ./setup.py nosetests # only nose (unit/doc tests) flake8 --config setup.cfg . # style checks Keep 100% coverage. You can look at the coverage report at
Build and review the generated Sphinx documentation, and validate if your changes look right: ./setup.py build_sphinx open doc/build/html/index.html To integrate changes from another branch, please rebase instead of creating merge commits ( read more). Public SchemasThe following repositories provides public schemas generated using
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论