Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
|License| |Release| |Docs| |Code Coverage| |Build Status Travis CI| |Blog|
A simple one-method library makes a GraphQL <https://graphql.org/>
__
query from Python data structures.
Installation
_Usage
_Exceptions
_Parameters
_Reserved keywords
_Examples
_Fields
_Arguments
_Default arguments
_Aliases
_Fragments
_Using variables inside fragments
_Operation name
_Variables
_Default variables
_Directives
_Mutations
_Inline Fragments
_Meta fields
_::
pip install graphql_from_struct
::
# 1. Import GqlFromStruct class
from graphql_from_struct import GqlFromStruct
# 2. Make a query
struct = {'hero':{'@fields':['name']}}
# 3. Generate GraphQL
gql = GqlFromStruct.from_struct(struct)
# Or use OOP-style:
foo = GqlFromStruct(struct)
gql = foo.query()
print (gql)
You should see such result:
::
query{
hero{
name
}
}
The module raises GqlFromStructException
in case of empty or wrong
data structure input.
GqlFromStruct()
constructor and .from_struct()
method take 3 arguments:
a struct (default None), a minimize (optional, default False) flag and a force_quotes (optional, default 0) setting.
Code:
::
foo = GqlFromStruct({'hero':{'@fields':['name']}}, True)
# or foo = GqlFromStruct(struct = {'hero':{'@fields':['name']}}, minimize = True)
gql = foo.query()
# or
gql = GqlFromStruct.from_struct({'hero':{'@fields':['name']}}, True)
print (gql)
gives you:
::
query{hero{name}}
By default the GraphQL-From-Struct sets quotes for any string with spaces. You can change it with the force_quotes flag. It enforces quoting parameters and arguments with 1 value, disables any quotes with -1 or enables only arguments quoting with 2:
::
gql = GqlFromStruct.from_struct({'hero':{'@fields':['name']}}, True, 1)
print (gql)
gives you:
::
"query"{"hero"{"name"}}
Or
::
gql = GqlFromStruct.from_struct({'he ro':{'@fields':['name']}}, True, -1)
print (gql)
gives you:
::
query{he ro{name}}
Or
::
gql = GqlFromStruct.from_struct('human':{'@fields':['name', 'height'], '@args':{'id':['foo', 'bar']}}, True, 2)
print (gql)
gives you:
::
query{human(id:["foo", "bar"]){name height}}
Words
@alias, @args, @fields, @fragments, @fragment_name, @directives, @include, @mutations, @operation_name, @queries, @query, @skip, @variables
are reserved and used for query constructing.
Examples are shown in the same order as in the
GraphQL <https://graphql.org/learn/queries/>
__ documentation.
Fields
Use ``@fields`` keyword:
::
struct = {'hero':{'@fields':['name']}}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
hero{
name
}
}
You can use arbitrary field nesting:
::
struct = {'hero':{'@fields':['name', {'friends':{'@fields':['name']}}]}}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
hero{
name
friends{
name
}
}
}
Arguments
Use @args
keyword:
::
struct = {'human':{'@fields':['name', 'height'], '@args':{'id':'"1000"'}}}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
human(
id : "1000"
){
name
height
}
}
or:
::
struct = {
'human': {
'@fields': ['name', {
'height': {
'@args': {
'unit': 'FOOT'
}
}
}],
'@args': {
'id': "1000"
}
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
human(
id : 1000
){
name
height(
unit : FOOT
)
}
}
Note: GraphQL-From-Struct puts double quotes by default only for values with spaces. Like that:
::
query = {'human':{'@fields':['name', 'height'], '@args':{'id':'1000 meters'}}}
Output:
::
query{
human(
id : "1000 meters"
){
name
height
}
}
Single words or numerical values are output in the form in which you passed them.
::
query = {'human':{'@fields':['name', 'height'], '@args':{'id':1000}}}
query{
human(
id : 1000
){
name
height
}
}
Default arguments ^^^^^^^^^^^^^^^^^^
You can set default values of arguments:
::
struct = {'human':{'@fields':['name', 'height'], '@args':{'$first': {'Int':'3'}}}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
human(
$first : Int = 3
){
name
height
}
}
Aliases
Use ``@alias`` keyword:
::
struct = [{
'hero': {
'@alias': 'empireHero',
'@args': {
'episode': "EMPIRE"
},
'@fields': ['name']
}
}, {
'hero': {
'@alias': 'jediHero',
'@args': {
'episode': "JEDI"
},
'@fields': ['name']
}
}]
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
empireHero : hero(
episode : EMPIRE
){
name
}
jediHero : hero(
episode : JEDI
){
name
}
}
Fragments
Use @fragments
and @fragment_name
keywords for fragments setting
up. Use @query
and @queries
for join some queries into one.
::
struct = {
"@queries": [{
'@query': [{
'hero': {
'@alias': 'leftComparison',
'@args': {
'episode': "EMPIRE"
},
'@fields': ['...comparisonFields']
}
},
{
'hero': {
'@alias': 'rightComparison',
'@args': {
'episode': "JEDI"
},
'@fields': ['...comparisonFields']
}
}
]
}],
"@fragments": [{
'Character': {
'@fragment_name': 'comparisonFields',
'@fields': ['name', 'appearsIn', {
'friends': {
'@fields': ['name']
}
}]
}
}]
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
leftComparison : hero(
episode : EMPIRE
){
...comparisonFields
}
rightComparison : hero(
episode : JEDI
){
...comparisonFields
}
}
fragment comparisonFields on Character{
name
appearsIn
friends{
name
}
}
Using variables inside fragments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
struct = {
"@queries": [{
'@args': {
'$first': {
'Int': '3'
}
},
'@operation_name': 'HeroComparison',
'@query': [{
'hero': {
'@alias': 'leftComparison',
'@args': {
'episode': "EMPIRE"
},
'@fields': ['...comparisonFields']
}
},
{
'hero': {
'@alias': 'rightComparison',
'@args': {
'episode': "JEDI"
},
'@fields': ['...comparisonFields']
}
}
]
}],
"@fragments": [{
'Character': {
'@fragment_name': 'comparisonFields',
'@fields': ['name', {
'friendsConnection': {
'@args': {
'first': '$first'
},
'@fields': ['totalCount', {
'edges': {
'@fields': [{
'node': {
'@fields': ['name']
}
}]
}
}]
}
}]
}
}]
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query HeroComparison (
$first : Int = 3
){
leftComparison : hero(
episode : EMPIRE
){
...comparisonFields
}
rightComparison : hero(
episode : JEDI
){
...comparisonFields
}
}
fragment comparisonFields on Character{
name
friendsConnection(
first : $first
){
totalCount
edges{
node{
name
}
}
}
}
Operation name
Use ``@operation_name`` keyword:
::
struct = {
'@queries': [{
'@operation_name': 'HeroNameAndFriends',
'@query': {
'hero': {
'@fields': ['name', {
'friends': {
'@fields': ['name']
}
}]
}
}
}]
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query HeroNameAndFriends{
hero{
name
friends{
name
}
}
}
Variables
~~~~~~~~~~
Use ``@variables`` block at the same high level nesting as ``@queries``:
::
struct = {
'@queries': [{
'@operation_name': 'HeroNameAndFriends',
'@query': {
'hero': {
'@fields': ['name', {
'friends': {
'@fields': ['name']
}
}]
}
}
}],
'@variables': {
"episode": "JEDI"
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query HeroNameAndFriends{
hero{
name
friends{
name
}
}
}
{
"episode": "JEDI"
}
Default variables
^^^^^^^^^^^^^^^^^^
Use ``@fields`` keyword:
::
struct = {
'@queries': [{
'@operation_name': 'HeroNameAndFriends',
'@args': {
'$episode': {
'Episode': 'JEDI'
}
},
'@query': {
'hero': {
'@fields': ['name', {
'friends': {
'@fields': ['name']
}
}]
}
}
}],
'@variables': {
"episode": "JEDI"
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query HeroNameAndFriends (
$episode : Episode = JEDI
){
hero{
name
friends{
name
}
}
}
{
"episode": "JEDI"
}
Directives
~~~~~~~~~~~
Use ``@directives`` keyword and ``@skip`` or ``@include`` as directives:
::
struct = {
'@queries': [{
'@operation_name': 'Hero',
'@args': {
'$episode': 'Episode',
'$withFriends': 'Boolean!'
},
'@query': {
'hero': {
'@args': {
'episode': '$episode'
},
'@fields': ['name', {
'friends': {
'@fields': ['name'],
'@directives': {
'@include': '$withFriends'
}
}
}]
}
}
}],
'@variables': {
"episode": "JEDI"
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query Hero (
$episode : Episode,
$withFriends : Boolean!
){
hero(
episode : $episode
){
name
friends @include (if : $withFriends){
name
}
}
}
{
"episode": "JEDI"
}
Mutations
~~~~~~~~~~
Use ``@mutations`` keyword:
::
struct = {
'@mutations': [{
'@operation_name': 'CreateReviewForEpisode',
'@args': {
'$episode': 'Episode!',
'$review': 'ReviewInput!'
},
'@query': {
'createReview': {
'@args': {
'episode': '$ep',
'review': '$review'
},
'@fields': ['stars', 'commentary']
}
}
}],
'@variables': {
"episode": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
mutation CreateReviewForEpisode (
$episode : Episode!,
$review : ReviewInput!
){
createReview(
episode : $ep,
review : $review
){
stars
commentary
}
}
{
"episode": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
Inline Fragments
Nothing special needed.
::
struct = {
"@queries": [{
'@args': {
'$ep': 'Episode!'
},
'@operation_name': 'HeroForEpisode',
'@query': [{
'hero': {
'@args': {
'episode': '$ep'
},
'@fields': ['name',
{
'... on Droid': {
'@fields': ['primaryFunction']
}
},
{
'... on Human': {
'@fields': ['height']
}
}
]
}
}]
}]
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query HeroForEpisode (
$ep : Episode!
){
hero(
episode : $ep
){
name
... on Droid{
primaryFunction
}
... on Human{
height
}
}
}
Meta fields
Use meta field as usual field:
::
struct = {
'search': {
'@args': {
'text': 'an'
},
'@fields': ['__typename',
{
'... on Human': {
'@fields': ['name']
}
},
{
'... on Droid': {
'@fields': ['name']
}
},
{
'... on Starship': {
'@fields': ['name']
}
}
]
}
}
print (GqlFromStruct.from_struct(struct))
Output:
::
query{
search(
text : an
){
__typename
... on Human{
name
}
... on Droid{
name
}
... on Starship{
name
}
}
}
.. |Release| image:: https://img.shields.io/github/v/release/artamonoviv/graphql-from-struct.svg
:target: https://github.com/artamonoviv/graphql-from-struct/releases
.. |Code Coverage| image:: https://codecov.io/gh/artamonoviv/graphql-from-struct/branch/master/graph/badge.svg
:target: https://codecov.io/gh/artamonoviv/graphql-from-struct
.. |Build Status Travis CI| image:: https://travis-ci.org/artamonoviv/graphql-from-struct.svg?branch=master
:target: https://travis-ci.org/artamonoviv/graphql-from-struct
.. |Blog| image:: https://img.shields.io/badge/site-my%20blog-yellow.svg
:target: https://artamonoviv.ru
.. |License| image:: https://img.shields.io/badge/License-MIT-yellow.svg
:target: https://opensource.org/licenses/MIT
.. |Docs| image:: https://readthedocs.org/projects/graphql-from-struct/badge/?version=latest&style=flat
:target: https://graphql-from-struct.readthedocs.io/en/latest/
FAQs
Makes a GraphQL query from Python data structures.
We found that graphql-from-struct demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.