-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
350 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: Tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
python-version: ["3.12"] | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install wheel | ||
pip install -e .[test,dev] | ||
- name: Pytest | ||
run: | | ||
pytest | ||
- name: Linters | ||
run: | | ||
pylint example tests | ||
mypy example --ignore-missing-imports --check-untyped-defs | ||
black --check . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
# ariadne-graphql-modules-v2-example | ||
An example GraphQL API implemented with Ariadne GraphQL Modules v2 | ||
|
||
An example GraphQL API implemented with Ariadne GraphQL Modules v2. | ||
|
||
This API aims to use ALL features from GraphQL Modules v2. It can also be used as a reference for other developers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from ariadne.asgi import GraphQL | ||
|
||
from .schema import schema | ||
|
||
|
||
app = GraphQL(schema, debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from typing import Any | ||
|
||
from .fixture import get_data | ||
|
||
|
||
class DataBase: | ||
_data: dict[str, dict[int, Any]] | ||
_id: int | ||
|
||
def __init__(self, data: dict[str, dict[int, Any]], counter: int = 0): | ||
self._data = data | ||
self._id = counter | ||
|
||
async def get_row(self, table: str, **kwargs) -> Any: | ||
assert kwargs, "use kwargs to filter" | ||
|
||
for row in self._data[table].values(): | ||
for attr, value in kwargs.items(): | ||
if getattr(row, attr) != value: | ||
continue | ||
|
||
return row | ||
|
||
return None | ||
|
||
async def get_all(self, table: str, **kwargs) -> list[Any]: | ||
if not kwargs: | ||
return list(self._data[table].values()) | ||
|
||
results: list[Any] = [] | ||
for row in self._data[table].values(): | ||
for attr, value in kwargs.items(): | ||
if getattr(row, attr) != value: | ||
continue | ||
|
||
results.append(row) | ||
|
||
return results | ||
|
||
async def insert(self, table: str, obj: Any): | ||
assert obj.id is None, "obj.id attr must be None" | ||
|
||
self._id += 1 | ||
obj.id = self._id | ||
|
||
self._data[table][obj.id] = obj | ||
|
||
async def update(self, table: str, obj: Any): | ||
self._data[table][obj.id] = obj | ||
|
||
async def delete(self, table: str, id: int): | ||
self._data[table].pop(id, None) | ||
|
||
|
||
db = DataBase(get_data(), 1000) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from enum import StrEnum | ||
|
||
|
||
class GroupFilter(StrEnum): | ||
ALL = "all" | ||
ADMIN = "admin" | ||
MEMBER = "member" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import Any | ||
|
||
from .models.group import Group | ||
from .models.user import User | ||
|
||
|
||
def get_data() -> dict[str, dict[int, Any]]: | ||
return { | ||
"groups": { | ||
1: Group( | ||
id=1, | ||
name="Admins", | ||
is_admin=True, | ||
), | ||
2: Group( | ||
id=2, | ||
name="Members", | ||
is_admin=False, | ||
), | ||
}, | ||
"users": { | ||
1: User( | ||
id=1, | ||
username="JohnDoe", | ||
email="[email protected]", | ||
group_id=1, | ||
), | ||
2: User( | ||
id=2, | ||
username="Alice", | ||
email="[email protected]", | ||
group_id=1, | ||
), | ||
3: User( | ||
id=3, | ||
username="Bob", | ||
email="[email protected]", | ||
group_id=2, | ||
), | ||
4: User( | ||
id=4, | ||
username="Mia", | ||
email="[email protected]", | ||
group_id=2, | ||
), | ||
}, | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass | ||
class Group: | ||
id: int | ||
name: str | ||
is_admin: bool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass | ||
class User: | ||
id: int | ||
username: str | ||
email: str | ||
group_id: int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from ariadne_graphql_modules import GraphQLObject, make_executable_schema | ||
from graphql import GraphQLResolveInfo | ||
|
||
from .database import db | ||
from .enums.groupfilter import GroupFilter | ||
from .types.group import GroupType | ||
from .types.user import UserType | ||
|
||
|
||
class Query(GraphQLObject): | ||
hello: str | ||
|
||
@GraphQLObject.resolver("hello") | ||
@staticmethod | ||
def resolve_hello(obj, info: GraphQLResolveInfo) -> str: | ||
return "Hello world!" | ||
|
||
@GraphQLObject.field(args={"filter_": GraphQLObject.argument("filter")}) | ||
async def groups(obj, info: GraphQLResolveInfo, filter_: GroupFilter) -> list[GroupType]: | ||
if filter_ == GroupFilter.ADMIN: | ||
return await db.get_all("groups", is_admin=True) | ||
|
||
if filter_ == GroupFilter.MEMBER: | ||
return await db.get_all("groups", is_admin=False) | ||
|
||
return await db.get_all("groups") | ||
|
||
@GraphQLObject.field() | ||
async def group(obj, info: GraphQLResolveInfo, id: str) -> GroupType | None: | ||
try: | ||
id_int = int(id) | ||
except (TypeError, ValueError): | ||
return None | ||
|
||
return await db.get_row("groups", id=id_int) | ||
|
||
@GraphQLObject.field() | ||
async def users(obj, info: GraphQLResolveInfo) -> list[UserType]: | ||
return await db.get_all("users") | ||
|
||
|
||
schema = make_executable_schema(Query, convert_names_case=True) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from typing import TYPE_CHECKING, Annotated | ||
|
||
from ariadne_graphql_modules import GraphQLID, GraphQLObject, deferred | ||
from graphql import GraphQLResolveInfo | ||
|
||
from ..database import db | ||
from ..models.group import Group | ||
|
||
if TYPE_CHECKING: | ||
from .user import UserType | ||
|
||
|
||
class GroupType(GraphQLObject): | ||
id: GraphQLID | ||
name: str | ||
is_admin: bool | ||
|
||
@GraphQLObject.field(graphql_type=list[Annotated["UserType", deferred(".user")]]) | ||
@staticmethod | ||
async def users(obj: Group, info: GraphQLResolveInfo): | ||
return await db.get_all("users", group_id=obj.id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from typing import TYPE_CHECKING, Annotated | ||
|
||
from ariadne_graphql_modules import GraphQLID, GraphQLObject, deferred | ||
from graphql import GraphQLResolveInfo | ||
|
||
from ..database import db | ||
from ..models.group import Group | ||
from ..models.user import User | ||
|
||
if TYPE_CHECKING: | ||
from .group import GroupType | ||
|
||
|
||
class UserType(GraphQLObject): | ||
id: GraphQLID | ||
username: str | ||
email: str | ||
group: Annotated["GroupType", deferred(".group")] | ||
|
||
@GraphQLObject.resolver("group") | ||
@staticmethod | ||
async def resolve_group(user: User, info: GraphQLResolveInfo) -> Group: | ||
return await db.get_row("groups", id=user.group_id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
[project] | ||
name = "ariadne-graphql-modules-v2-example" | ||
version = "0.1.0" | ||
description = "An example GraphQL API implemented using the Ariadne GraphQL Modules v2." | ||
authors = [{ name = "Rafał Pitoń", email = "[email protected]" }] | ||
readme = "README.md" | ||
license = { file = "LICENSE" } | ||
classifiers = [ | ||
"Development Status :: 3 - Alpha", | ||
"Intended Audience :: Developers", | ||
"License :: OSI Approved :: BSD License", | ||
"Operating System :: OS Independent", | ||
"Environment :: Web Environment", | ||
"Programming Language :: Python", | ||
"Programming Language :: Python :: 3.12", | ||
"Topic :: Software Development :: Libraries :: Python Modules", | ||
] | ||
dependencies = [ | ||
"ariadne>=0.23.0", | ||
"ariadne-graphql-modules@git+https://github.com/mirumee/ariadne-graphql-modules@next-api", | ||
] | ||
|
||
[project.optional-dependencies] | ||
dev = ["black", "mypy", "pylint"] | ||
test = [ | ||
"pytest", | ||
"pytest-asyncio", | ||
"pytest-benchmark", | ||
"pytest-cov", | ||
"pytest-mock", | ||
"freezegun", | ||
"syrupy", | ||
"werkzeug", | ||
"httpx", | ||
"opentracing", | ||
"opentelemetry-api", | ||
"python-multipart>=0.0.5", | ||
"aiodataloader", | ||
"graphql-sync-dataloaders;python_version>\"3.7\"", | ||
] | ||
|
||
[tool.black] | ||
line-length = 88 | ||
target-version = ['py36', 'py37', 'py38'] | ||
include = '\.pyi?$' | ||
exclude = ''' | ||
/( | ||
\.eggs | ||
| \.git | ||
| \.hg | ||
| \.mypy_cache | ||
| \.tox | ||
| \.venv | ||
| _build | ||
| buck-out | ||
| build | ||
| dist | ||
| snapshots | ||
)/ | ||
''' | ||
|
||
[tool.pytest.ini_options] | ||
asyncio_mode = "strict" | ||
testpaths = ["tests"] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import pytest | ||
from graphql import graphql | ||
|
||
from example.schema import schema | ||
|
||
|
||
@pytest.fixture | ||
def exec_query(): | ||
async def exec_query_( | ||
document: str, | ||
variables: dict | None = None, | ||
operation: str | None = None, | ||
): | ||
return await graphql( | ||
schema, | ||
document, | ||
variable_values=variables, | ||
operation_name=operation, | ||
) | ||
|
||
return exec_query_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import pytest | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_query_hello_field(exec_query): | ||
result = await exec_query("{ hello }") | ||
assert result.data == {"hello": "Hello world!"} |