From 5455a6b359f6dbf3a09aecf15804a088d31a935c Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 6 Jan 2023 14:14:37 +0100 Subject: [PATCH] Added first graphene models --- kdb-bot/src/bot/bot.json | 4 ++- kdb-bot/src/bot/config | 2 +- kdb-bot/src/bot_api/api.py | 11 ++++++ kdb-bot/src/bot_api/api_module.py | 1 + .../bot_api/controller/graphql_controller.py | 32 +++++++++++++++++ .../src/bot_data/graphql/query/__init__.py | 0 .../bot_data/graphql/query/client_query.py | 19 +++++++++++ .../bot_data/graphql/query/server_query.py | 19 +++++++++++ kdb-bot/src/bot_data/graphql/root_query.py | 12 +++++++ kdb-bot/src/bot_data/graphql/schema.py | 5 +++ .../graphql/types/client_query_type.py | 17 ++++++++++ .../graphql/types/server_query_type.py | 30 ++++++++++++++++ .../service/client_repository_service.py | 34 +++++++++++++------ .../service/server_repository_service.py | 16 ++++++--- 14 files changed, 184 insertions(+), 18 deletions(-) create mode 100644 kdb-bot/src/bot_api/controller/graphql_controller.py create mode 100644 kdb-bot/src/bot_data/graphql/query/__init__.py create mode 100644 kdb-bot/src/bot_data/graphql/query/client_query.py create mode 100644 kdb-bot/src/bot_data/graphql/query/server_query.py create mode 100644 kdb-bot/src/bot_data/graphql/root_query.py create mode 100644 kdb-bot/src/bot_data/graphql/schema.py create mode 100644 kdb-bot/src/bot_data/graphql/types/client_query_type.py create mode 100644 kdb-bot/src/bot_data/graphql/types/server_query_type.py diff --git a/kdb-bot/src/bot/bot.json b/kdb-bot/src/bot/bot.json index c9461eb6..7fea125a 100644 --- a/kdb-bot/src/bot/bot.json +++ b/kdb-bot/src/bot/bot.json @@ -28,7 +28,9 @@ "Flask-SocketIO==5.3.2", "eventlet==0.33.2", "requests-oauthlib==1.3.1", - "icmplib==3.0.3" + "icmplib==3.0.3", + "graphene==3.2.1", + "graphql-server==3.0.0b5" ], "DevDependencies": [ "cpl-cli==2022.12.0" diff --git a/kdb-bot/src/bot/config b/kdb-bot/src/bot/config index f15e3ff8..64a551bc 160000 --- a/kdb-bot/src/bot/config +++ b/kdb-bot/src/bot/config @@ -1 +1 @@ -Subproject commit f15e3ff82709bbd274b0645c2b13a482f67f75ff +Subproject commit 64a551bcee7fbfb06ee724355b48baec1c8e8e3e diff --git a/kdb-bot/src/bot_api/api.py b/kdb-bot/src/bot_api/api.py index b31eee19..b44b92b3 100644 --- a/kdb-bot/src/bot_api/api.py +++ b/kdb-bot/src/bot_api/api.py @@ -12,6 +12,7 @@ from eventlet import wsgi from flask import Flask, request, jsonify, Response from flask_cors import CORS from flask_socketio import SocketIO +from graphql_server.flask import GraphQLView from werkzeug.exceptions import NotFound from bot_api.configuration.api_settings import ApiSettings @@ -22,6 +23,7 @@ from bot_api.exception.service_exception import ServiceException from bot_api.logging.api_logger import ApiLogger from bot_api.model.error_dto import ErrorDTO from bot_api.route.route import Route +from bot_data.graphql.schema import schema class Api(Flask): @@ -62,6 +64,15 @@ class Api(Flask): self._requests = {} + self.add_url_rule( + '/api/graphql', + view_func=GraphQLView.as_view( + 'graphql', + schema=schema, + graphiql=True # for having the GraphiQL interface + ) + ) + @staticmethod def _get_methods_from_registered_route() -> Union[list[str], str]: methods = ['Unknown'] diff --git a/kdb-bot/src/bot_api/api_module.py b/kdb-bot/src/bot_api/api_module.py index b4c1735a..f95aa58c 100644 --- a/kdb-bot/src/bot_api/api_module.py +++ b/kdb-bot/src/bot_api/api_module.py @@ -47,6 +47,7 @@ class ApiModule(ModuleABC): services.add_transient(GuiController) services.add_transient(DiscordService) services.add_transient(ServerController) + #services.add_transient(GraphQLController) # cpl-discord self._dc.add_event(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) diff --git a/kdb-bot/src/bot_api/controller/graphql_controller.py b/kdb-bot/src/bot_api/controller/graphql_controller.py new file mode 100644 index 00000000..a1cc5425 --- /dev/null +++ b/kdb-bot/src/bot_api/controller/graphql_controller.py @@ -0,0 +1,32 @@ +import os + +from cpl_core.configuration import ConfigurationABC +from cpl_core.environment import ApplicationEnvironmentABC +from cpl_core.mailing import EMail, EMailClientABC, EMailClientSettings +from cpl_translation import TranslatePipe +from flask import jsonify, request + +from bot_api.api import Api +from bot_api.configuration.authentication_settings import AuthenticationSettings +from bot_api.logging.api_logger import ApiLogger +from bot_api.model.settings_dto import SettingsDTO +from bot_api.model.version_dto import VersionDTO +from bot_api.route.route import Route + + +class GraphQLController: + BasePath = f'/api/graphql' + + def __init__( + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + ): + self._config = config + self._env = env + self._logger = logger + + @Route.get(f'{BasePath}') + async def graphql(self): + return '', 200 diff --git a/kdb-bot/src/bot_data/graphql/query/__init__.py b/kdb-bot/src/bot_data/graphql/query/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/bot_data/graphql/query/client_query.py b/kdb-bot/src/bot_data/graphql/query/client_query.py new file mode 100644 index 00000000..2e34fbdd --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/query/client_query.py @@ -0,0 +1,19 @@ +import graphene +from cpl_core.dependency_injection import ServiceProviderABC +from graphene import ObjectType + +from bot_data.graphql.types.client_query_type import ClientQueryType +from bot_data.service.client_repository_service import ClientRepositoryService + + +class ClientQuery(ObjectType): + clients = graphene.List(ClientQueryType) + + @staticmethod + @ServiceProviderABC.inject + def _get_clients(clients: ClientRepositoryService): + return clients.get_clients() + + @staticmethod + def resolve_clients(root, info): + return ClientQuery._get_clients() diff --git a/kdb-bot/src/bot_data/graphql/query/server_query.py b/kdb-bot/src/bot_data/graphql/query/server_query.py new file mode 100644 index 00000000..d0fa2acc --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/query/server_query.py @@ -0,0 +1,19 @@ +import graphene +from cpl_core.dependency_injection import ServiceProviderABC +from graphene import ObjectType + +from bot_data.graphql.types.server_query_type import ServerQueryType +from bot_data.service.server_repository_service import ServerRepositoryService + + +class ServerQuery(ObjectType): + servers = graphene.List(ServerQueryType) + + @staticmethod + @ServiceProviderABC.inject + def _get_servers(servers: ServerRepositoryService): + return servers.get_servers() + + @staticmethod + def resolve_servers(root, info): + return ServerQuery._get_servers() diff --git a/kdb-bot/src/bot_data/graphql/root_query.py b/kdb-bot/src/bot_data/graphql/root_query.py new file mode 100644 index 00000000..057820bb --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/root_query.py @@ -0,0 +1,12 @@ +from graphene import ObjectType, relay + +from bot_data.graphql.query.client_query import ClientQuery +from bot_data.graphql.query.server_query import ServerQuery + + +class RootQuery( + ServerQuery, + ClientQuery, + ObjectType +): + node = relay.Node.Field() diff --git a/kdb-bot/src/bot_data/graphql/schema.py b/kdb-bot/src/bot_data/graphql/schema.py new file mode 100644 index 00000000..bf335aee --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/schema.py @@ -0,0 +1,5 @@ +import graphene + +from bot_data.graphql.root_query import RootQuery + +schema = graphene.Schema(query=RootQuery) diff --git a/kdb-bot/src/bot_data/graphql/types/client_query_type.py b/kdb-bot/src/bot_data/graphql/types/client_query_type.py new file mode 100644 index 00000000..3d62c3f8 --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/types/client_query_type.py @@ -0,0 +1,17 @@ +from graphene import ObjectType, Int + +from bot_data.model.client import Client + + +class ClientQueryType(ObjectType): + id = Int() + discord_client_id = Int() + sent_message_count = Int() + received_message_count = Int() + deleted_message_count = Int() + received_command_count = Int() + moved_users_count = Int() + + @staticmethod + def resolve_id(client: Client, info): + return client.client_id diff --git a/kdb-bot/src/bot_data/graphql/types/server_query_type.py b/kdb-bot/src/bot_data/graphql/types/server_query_type.py new file mode 100644 index 00000000..1ca96651 --- /dev/null +++ b/kdb-bot/src/bot_data/graphql/types/server_query_type.py @@ -0,0 +1,30 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from graphene import ObjectType, Int, DateTime, String, Field + +from bot_data.graphql.types.client_query_type import ClientQueryType +from bot_data.model.server import Server +from bot_data.service.client_repository_service import ClientRepositoryService + + +class ServerQueryType(ObjectType): + id = Int() + discord_server_id = String() + + created_at = DateTime() + modified_at = DateTime() + + client = Field(ClientQueryType) + + @staticmethod + def resolve_id(server: Server, info): + return server.server_id + + @staticmethod + @ServiceProviderABC.inject + def _get_clients(clients: ClientRepositoryService): + return clients + + @staticmethod + def resolve_client(server: Server, info): + clients: ClientRepositoryService = ServerQueryType._get_clients() + return clients.find_client_by_server_id(server.server_id) diff --git a/kdb-bot/src/bot_data/service/client_repository_service.py b/kdb-bot/src/bot_data/service/client_repository_service.py index ba875a25..102758e5 100644 --- a/kdb-bot/src/bot_data/service/client_repository_service.py +++ b/kdb-bot/src/bot_data/service/client_repository_service.py @@ -33,6 +33,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] )) @@ -49,6 +51,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] ) @@ -63,6 +67,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] ) @@ -71,9 +77,9 @@ class ClientRepositoryService(ClientRepositoryABC): result = self._context.select(Client.get_select_by_discord_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -82,6 +88,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] ) @@ -90,9 +98,9 @@ class ClientRepositoryService(ClientRepositoryABC): result = self._context.select(Client.get_select_by_server_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -101,6 +109,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] ) @@ -109,9 +119,9 @@ class ClientRepositoryService(ClientRepositoryABC): result = self._context.select(Client.get_select_by_discord_id_and_server_id_string(discord_id, server_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -120,17 +130,19 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0] ) - + def add_client(self, client: Client): self._logger.trace(__name__, f'Send SQL command: {client.insert_string}') self._context.cursor.execute(client.insert_string) - + def update_client(self, client: Client): self._logger.trace(__name__, f'Send SQL command: {client.udpate_string}') self._context.cursor.execute(client.udpate_string) - + def delete_client(self, client: Client): self._logger.trace(__name__, f'Send SQL command: {client.delete_string}') self._context.cursor.execute(client.delete_string) @@ -140,12 +152,12 @@ class ClientRepositoryService(ClientRepositoryABC): if server is None: self._logger.warn(__name__, f'Cannot find server by id {server_id}') raise Exception('Value not found') - + client = self.find_client_by_discord_id_and_server_id(id, server.server_id) if client is None: self._logger.warn(__name__, f'Cannot find client by ids {id}@{server.server_id}') raise Exception('Value not found') - + return client def append_sent_message_count(self, client_id: int, server_id: int, value: int): diff --git a/kdb-bot/src/bot_data/service/server_repository_service.py b/kdb-bot/src/bot_data/service/server_repository_service.py index 210a6dee..5ae268ea 100644 --- a/kdb-bot/src/bot_data/service/server_repository_service.py +++ b/kdb-bot/src/bot_data/service/server_repository_service.py @@ -25,6 +25,8 @@ class ServerRepositoryService(ServerRepositoryABC): for result in results: servers.append(Server( result[1], + result[2], + result[3], id=result[0] )) @@ -55,6 +57,8 @@ class ServerRepositoryService(ServerRepositoryABC): result = self._context.select(Server.get_select_by_id_string(server_id))[0] return Server( result[1], + result[2], + result[3], id=result[0] ) @@ -63,6 +67,8 @@ class ServerRepositoryService(ServerRepositoryABC): result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0] return Server( result[1], + result[2], + result[3], id=result[0] ) @@ -71,24 +77,24 @@ class ServerRepositoryService(ServerRepositoryABC): result = self._context.select(Server.get_select_by_discord_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Server( result[1], result[2], result[3], id=result[0] ) - + def add_server(self, server: Server): self._logger.trace(__name__, f'Send SQL command: {server.insert_string}') self._context.cursor.execute(server.insert_string) - + def update_server(self, server: Server): self._logger.trace(__name__, f'Send SQL command: {server.udpate_string}') self._context.cursor.execute(server.udpate_string) - + def delete_server(self, server: Server): self._logger.trace(__name__, f'Send SQL command: {server.delete_string}') self._context.cursor.execute(server.delete_string)