Nickfis
Nickfis

Reputation: 328

Turn Python dictionary into GraphQL query string

I have a GraphQL backend, which was written in NodeJS, through which I can add content via a mutation. The data that gets fed into that mutation is created via a Python script. At the moment I have a dictionary that looks like this:

{
  'title': 'ContentTitle',
  'description': 'content description',
  'active': True,
  'chapters': [
    {
      'title': 'chapter title',
      'lessons': [
        {
          'title': 'lesson title',
          'filePath': 'static-resource-path'
        },
        {
          'title': 'lesson title 2',
          'filePath': 'static-resource-path2'
        }
      ]
    }
  ]
}

Which I need to turn into a GraphQL query looking like this:

mutation {
    addContent(
        title: "ContentTitle",
        description: "content description",
        active: true,
        chapters: [
            {
                title: "chapter title",
                lessons: [
                    {
                        title: "lesson title",
                        filePath: "static-resource-path"
                    },
                    {
                        title: "lesson title 2",
                        filePath: "static-resource-path2"
                    }
                ]
            }
        ]
    ) {
        success
    }
}

Is there any simple way to turn the dictionary, which generally has the correct format, into the GraphQL string?

Upvotes: 3

Views: 1501

Answers (1)

Denis Artyushin
Denis Artyushin

Reputation: 374

you can using the graphql-query package.

The following code it is a simple implementation of your problem:

from typing import Any, Dict, List
from graphql_query import Argument, Operation, Query

example_dict = {
    'title': 'ContentTitle',
    'description': 'content description',
    'active': True,
    'chapters': [
        {
            'title': 'chapter title',
            'lessons': [
                {
                    'title': 'lesson title',
                    'filePath': 'static-resource-path'
                },
                {
                    'title': 'lesson title 2',
                    'filePath': 'static-resource-path2'
                }
            ]
        }
    ]
}

def scalar_argument(key: str, value: Any) -> Argument:
    """Generate an Argument in the following form

    key: "value"
    key: true
    key: false
    ...

    """

    if isinstance(value, str):
        return Argument(name=key, value=f'"{value}"')

    elif isinstance(value, bool):
        return Argument(name=key, value=str(value).lower())

    # your cases here...

def get_query_arguments(arguments_dict: Dict[str, Any]) -> List[Argument]:
    query_arguments = []

    for key, value in arguments_dict.items():
        # processing of scalar values
        if isinstance(value, str) or isinstance(value, bool):
            query_arguments.append(scalar_argument(key, value))

        # processing of list with objects
        elif isinstance(value, list):
            values = [get_query_arguments(obj) for obj in value]
            query_arguments.append(Argument(name=key, value=values))

    return query_arguments

target_mutation = Operation(
    type="mutation",
    queries=[
        Query(
            name="addContent",
            arguments=get_query_arguments(example_dict),
            fields=["success"]
        )
    ]
)

print(target_mutation.render())
# mutation {
#   addContent(
#     title: "ContentTitle"
#     description: "content description"
#     active: true
#     chapters: [
#       {
#         title: "chapter title"
#         lessons: [
#           {
#             title: "lesson title"
#             filePath: "static-resource-path"
#           }
#           {
#             title: "lesson title 2"
#             filePath: "static-resource-path2"
#           }
#         ]
#       }
#     ]
#   ) {
#     success
#   }
# }

Upvotes: 3

Related Questions