Metadata-Version: 2.1
Name: graphql2python
Version: 0.0.2
Summary: Tools for GraphQL client in python.
Home-page: https://github.com/denisart/graphql2python
Author: Denis A. Artyushin
Maintainer: Denis A. Artyushin
Maintainer-email: artyushinden@gmail.com
License: MIT
Platform: UNKNOWN
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: click (<8.2,>=8.1)
Requires-Dist: graphql-core (<3.3,>=3.2)
Requires-Dist: jinja2 (<3.2,>=3.1)
Requires-Dist: pydantic (<1.11,>=1.10)
Requires-Dist: pyyaml (<6.1,>=6.0)
Provides-Extra: dev
Requires-Dist: isort (<5.11,>=5.10) ; extra == 'dev'
Requires-Dist: mypy (<0.992,>=0.991) ; extra == 'dev'
Requires-Dist: pylint-pydantic (<0.2,>=0.1) ; extra == 'dev'
Requires-Dist: pylint (<2.16,>=2.15) ; extra == 'dev'
Requires-Dist: types-pyyaml (<6.1,>=6.0) ; extra == 'dev'
Requires-Dist: wheel (<0.39,>=0.38) ; extra == 'dev'
Provides-Extra: test
Requires-Dist: pytest-cov (<3.1,>=3.0) ; extra == 'test'
Requires-Dist: pytest-mock (<3.11,>=3.10) ; extra == 'test'
Requires-Dist: pytest (<7.3,>=7.2) ; extra == 'test'

# GRAPHQL2PYTHON

Tools for GraphQL client in python.

## Installation

Install using

```bash
pip install graphql2python
```

## A Simple Example for Query

For the query

```graphql
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}
```

we have

```python
from graphql2python.query import InlineFragment, Operation, Query, Variable, Argument

var_ep = Variable(name="ep", type="Episode!")
arg_episode = Argument(name="episode", value=var_ep)

hero = Query(
    name="hero",
    arguments=[arg_episode],
    fields=[
        "name",
        InlineFragment(type="Droid", fields=["primaryFunction"]),
        InlineFragment(type="Human", fields=["height"]),
    ]
)

operation = Operation(
    type="query",
    name="HeroForEpisode",
    queries=[hero],
    variables=[var_ep]
)
operation.render()
# query HeroForEpisode(
#   $ep: Episode!
# ) {
#   hero(
#     episode: $ep
#   ) {
#     name
#     ... on Droid {
#       primaryFunction
#     }
#     ... on Human {
#       height
#     }
#   }
# }
```

## A simple Example for Model

Run

```bash
graphql2python render --config ./graphql2python.yaml
```

where

```yaml
# graphql2python.yaml
schema: ./schema.graphql
output: ./model.py
```

and

```graphql
# schema.graphql
interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}

type Human implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  starships: [Starship]
  totalCredits: Int
}

type Starship {
  id: ID!
  name: String!
  length: Float
}

type Droid implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  primaryFunction: String
}

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}
```

we have in `model.py`:

```python
"""Auto-generated by graphql2python."""

# pylint: disable-all
# mypy: ignore-errors

import enum
from datetime import date, datetime
from typing import Any, List, Literal, Optional, Union

from pydantic import BaseModel, Field

__all__ = [
    "GraphQLBaseModel",
    # scalars
    "Boolean",
    "Float",
    "ID",
    "Int",
    "String",
    # enums
    "Episode",
    # unions
    # interfaces
    "Character",
    # objects
    "Droid",
    "Human",
    "Starship",
]


class GraphQLBaseModel(BaseModel):
    """Base Model for GraphQL object."""

    class Config:
        allow_population_by_field_name = True
        json_encoders = {
            # custom output conversion for datetime
            datetime: lambda dt: dt.isoformat()
        }
        smart_union = True


# The `Boolean` scalar type represents `true` or `false`.
Boolean = str


# The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE
# 754](https://en.wikipedia.org/wiki/IEEE_floating_point).
Float = str


# The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID
# type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an
# input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
ID = str


# The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31)
# and 2^31 - 1.
Int = str


# The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most
# often used by GraphQL to represent free-form human-readable text.
String = str


class Episode(enum.Enum):
    """
    An Enum type
    See https://graphql.org/learn/schema/#enumeration-types
    """
    EMPIRE = "EMPIRE"
    JEDI = "JEDI"
    NEWHOPE = "NEWHOPE"


class Character(GraphQLBaseModel):
    """
    An Interface type
    See https://graphql.org/learn/schema/#interfaces
    """
    appearsIn: List[Optional['Episode']]
    id: 'ID'
    name: 'String'
    friends: Optional[List[Optional['Character']]] = Field(default_factory=list)


class Droid(
    Character,
):
    """
    An Object type
    See https://graphql.org/learn/schema/#object-types-and-fields
    """
    primaryFunction: Optional['String'] = Field(default=None)


class Human(
    Character,
):
    """
    An Object type
    See https://graphql.org/learn/schema/#object-types-and-fields
    """
    starships: Optional[List[Optional['Starship']]] = Field(default_factory=list)
    totalCredits: Optional['Int'] = Field(default=None)


class Starship(GraphQLBaseModel):
    """
    An Object type
    See https://graphql.org/learn/schema/#object-types-and-fields
    """
    id: 'ID'
    name: 'String'
    length: Optional['Float'] = Field(default=None)
```

