Compare commits

..

2 Commits

Author SHA1 Message Date
75500076a7 Improved gql data layer 2023-01-06 14:47:45 +01:00
5455a6b359 Added first graphene models 2023-01-06 14:14:37 +01:00
13 changed files with 201 additions and 18 deletions

View File

@ -28,7 +28,9 @@
"Flask-SocketIO==5.3.2", "Flask-SocketIO==5.3.2",
"eventlet==0.33.2", "eventlet==0.33.2",
"requests-oauthlib==1.3.1", "requests-oauthlib==1.3.1",
"icmplib==3.0.3" "icmplib==3.0.3",
"graphene==3.2.1",
"graphql-server==3.0.0b5"
], ],
"DevDependencies": [ "DevDependencies": [
"cpl-cli==2022.12.0" "cpl-cli==2022.12.0"

@ -1 +1 @@
Subproject commit f15e3ff82709bbd274b0645c2b13a482f67f75ff Subproject commit 64a551bcee7fbfb06ee724355b48baec1c8e8e3e

View File

@ -12,6 +12,7 @@ from eventlet import wsgi
from flask import Flask, request, jsonify, Response from flask import Flask, request, jsonify, Response
from flask_cors import CORS from flask_cors import CORS
from flask_socketio import SocketIO from flask_socketio import SocketIO
from graphql_server.flask import GraphQLView
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from bot_api.configuration.api_settings import ApiSettings 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.logging.api_logger import ApiLogger
from bot_api.model.error_dto import ErrorDTO from bot_api.model.error_dto import ErrorDTO
from bot_api.route.route import Route from bot_api.route.route import Route
from bot_data.graphql.graphql import GraphQL
class Api(Flask): class Api(Flask):
@ -62,6 +64,16 @@ class Api(Flask):
self._requests = {} self._requests = {}
gql = GraphQL()
self.add_url_rule(
'/api/graphql',
view_func=GraphQLView.as_view(
'graphql',
schema=gql.schema,
graphiql=True # for having the GraphiQL interface
)
)
@staticmethod @staticmethod
def _get_methods_from_registered_route() -> Union[list[str], str]: def _get_methods_from_registered_route() -> Union[list[str], str]:
methods = ['Unknown'] methods = ['Unknown']

View File

@ -0,0 +1,53 @@
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_query.extension import List
from graphene import ObjectType
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.client_repository_abc import ClientRepositoryABC
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from bot_data.abc.level_repository_abc import LevelRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.auto_role import AutoRole
from bot_data.model.client import Client
from bot_data.model.known_user import KnownUser
from bot_data.model.level import Level
from bot_data.model.server import Server
from bot_data.model.user import User
from bot_data.model.user_joined_server import UserJoinedServer
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
class QueryABC(ObjectType):
_auto_roles: List[AutoRole]
_clients: List[Client]
_known_users: List[KnownUser]
_levels: List[Level]
_servers: List[Server]
_user_joined_servers: List[UserJoinedServer]
_user_joined_voice_channel: List[UserJoinedVoiceChannel]
_users: List[User]
@classmethod
@ServiceProviderABC.inject
def init(
cls,
auto_roles: AutoRoleRepositoryABC,
clients: ClientRepositoryABC,
known_users: KnownUserRepositoryABC,
levels: LevelRepositoryABC,
servers: ServerRepositoryABC,
user_joined_servers: UserJoinedServerRepositoryABC,
user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC,
users: UserRepositoryABC,
):
cls._auto_roles = auto_roles.get_auto_roles()
cls._clients = clients.get_clients()
cls._known_users = known_users.get_users()
cls._levels = levels.get_levels()
cls._servers = servers.get_servers()
cls._user_joined_servers = user_joined_servers.get_user_joined_servers()
cls._user_joined_voice_channel = user_joined_voice_channel.get_user_joined_voice_channels()
cls._users = users.get_users()

View File

@ -0,0 +1,16 @@
import graphene
from graphene import Schema
from bot_data.abc.queryABC import QueryABC
from bot_data.graphql.root_query import RootQuery
class GraphQL:
def __init__(self):
QueryABC.init()
self._schema = graphene.Schema(query=RootQuery)
@property
def schema(self) -> Schema:
return self._schema

View File

@ -0,0 +1,12 @@
import graphene
from bot_data.abc.queryABC import QueryABC
from bot_data.graphql.types.client_query_type import ClientQueryType
class ClientQuery(QueryABC):
clients = graphene.List(ClientQueryType)
@classmethod
def resolve_clients(cls, root, info):
return cls._clients

View File

@ -0,0 +1,19 @@
import graphene
from cpl_core.dependency_injection import ServiceProviderABC
from bot_data.abc.queryABC import QueryABC
from bot_data.graphql.types.server_query_type import ServerQueryType
from bot_data.service.server_repository_service import ServerRepositoryService
class ServerQuery(QueryABC):
servers = graphene.List(ServerQueryType)
@staticmethod
@ServiceProviderABC.inject
def _get_servers(servers: ServerRepositoryService):
return servers.get_servers()
@classmethod
def resolve_servers(cls, root, info):
return cls._servers

View File

@ -0,0 +1,10 @@
from graphene import ObjectType, relay
from bot_data.graphql.queries.server_query import ServerQuery
class RootQuery(
ServerQuery,
ObjectType
):
node = relay.Node.Field()

View File

@ -0,0 +1,18 @@
from graphene import Int, String
from bot_data.abc.queryABC import QueryABC
from bot_data.model.client import Client
class ClientQueryType(QueryABC):
id = Int()
discord_id = String()
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

View File

@ -0,0 +1,23 @@
from graphene import Int, DateTime, String, List
from bot_data.abc.queryABC import QueryABC
from bot_data.graphql.types.client_query_type import ClientQueryType
from bot_data.model.server import Server
class ServerQueryType(QueryABC):
id = Int()
discord_server_id = String()
created_at = DateTime()
modified_at = DateTime()
clients = List(ClientQueryType)
@staticmethod
def resolve_id(server: Server, info):
return server.server_id
@classmethod
def resolve_clients(cls, server: Server, info):
return cls._clients.where(lambda c: c.server.server_id == server.server_id)

View File

@ -33,6 +33,8 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] id=result[0]
)) ))
@ -49,6 +51,8 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] id=result[0]
) )
@ -63,6 +67,8 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] id=result[0]
) )
@ -71,9 +77,9 @@ class ClientRepositoryService(ClientRepositoryABC):
result = self._context.select(Client.get_select_by_discord_id_string(discord_id)) result = self._context.select(Client.get_select_by_discord_id_string(discord_id))
if result is None or len(result) == 0: if result is None or len(result) == 0:
return None return None
result = result[0] result = result[0]
return Client( return Client(
result[1], result[1],
result[2], result[2],
@ -82,6 +88,8 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] id=result[0]
) )
@ -90,9 +98,9 @@ class ClientRepositoryService(ClientRepositoryABC):
result = self._context.select(Client.get_select_by_server_id_string(discord_id)) result = self._context.select(Client.get_select_by_server_id_string(discord_id))
if result is None or len(result) == 0: if result is None or len(result) == 0:
return None return None
result = result[0] result = result[0]
return Client( return Client(
result[1], result[1],
result[2], result[2],
@ -101,6 +109,8 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] 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)) 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: if result is None or len(result) == 0:
return None return None
result = result[0] result = result[0]
return Client( return Client(
result[1], result[1],
result[2], result[2],
@ -120,17 +130,19 @@ class ClientRepositoryService(ClientRepositoryABC):
result[5], result[5],
result[6], result[6],
self._servers.get_server_by_id(result[7]), self._servers.get_server_by_id(result[7]),
result[8],
result[9],
id=result[0] id=result[0]
) )
def add_client(self, client: Client): def add_client(self, client: Client):
self._logger.trace(__name__, f'Send SQL command: {client.insert_string}') self._logger.trace(__name__, f'Send SQL command: {client.insert_string}')
self._context.cursor.execute(client.insert_string) self._context.cursor.execute(client.insert_string)
def update_client(self, client: Client): def update_client(self, client: Client):
self._logger.trace(__name__, f'Send SQL command: {client.udpate_string}') self._logger.trace(__name__, f'Send SQL command: {client.udpate_string}')
self._context.cursor.execute(client.udpate_string) self._context.cursor.execute(client.udpate_string)
def delete_client(self, client: Client): def delete_client(self, client: Client):
self._logger.trace(__name__, f'Send SQL command: {client.delete_string}') self._logger.trace(__name__, f'Send SQL command: {client.delete_string}')
self._context.cursor.execute(client.delete_string) self._context.cursor.execute(client.delete_string)
@ -140,12 +152,12 @@ class ClientRepositoryService(ClientRepositoryABC):
if server is None: if server is None:
self._logger.warn(__name__, f'Cannot find server by id {server_id}') self._logger.warn(__name__, f'Cannot find server by id {server_id}')
raise Exception('Value not found') raise Exception('Value not found')
client = self.find_client_by_discord_id_and_server_id(id, server.server_id) client = self.find_client_by_discord_id_and_server_id(id, server.server_id)
if client is None: if client is None:
self._logger.warn(__name__, f'Cannot find client by ids {id}@{server.server_id}') self._logger.warn(__name__, f'Cannot find client by ids {id}@{server.server_id}')
raise Exception('Value not found') raise Exception('Value not found')
return client return client
def append_sent_message_count(self, client_id: int, server_id: int, value: int): def append_sent_message_count(self, client_id: int, server_id: int, value: int):

View File

@ -25,6 +25,8 @@ class ServerRepositoryService(ServerRepositoryABC):
for result in results: for result in results:
servers.append(Server( servers.append(Server(
result[1], result[1],
result[2],
result[3],
id=result[0] id=result[0]
)) ))
@ -55,6 +57,8 @@ class ServerRepositoryService(ServerRepositoryABC):
result = self._context.select(Server.get_select_by_id_string(server_id))[0] result = self._context.select(Server.get_select_by_id_string(server_id))[0]
return Server( return Server(
result[1], result[1],
result[2],
result[3],
id=result[0] id=result[0]
) )
@ -63,6 +67,8 @@ class ServerRepositoryService(ServerRepositoryABC):
result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0] result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0]
return Server( return Server(
result[1], result[1],
result[2],
result[3],
id=result[0] id=result[0]
) )
@ -71,24 +77,24 @@ class ServerRepositoryService(ServerRepositoryABC):
result = self._context.select(Server.get_select_by_discord_id_string(discord_id)) result = self._context.select(Server.get_select_by_discord_id_string(discord_id))
if result is None or len(result) == 0: if result is None or len(result) == 0:
return None return None
result = result[0] result = result[0]
return Server( return Server(
result[1], result[1],
result[2], result[2],
result[3], result[3],
id=result[0] id=result[0]
) )
def add_server(self, server: Server): def add_server(self, server: Server):
self._logger.trace(__name__, f'Send SQL command: {server.insert_string}') self._logger.trace(__name__, f'Send SQL command: {server.insert_string}')
self._context.cursor.execute(server.insert_string) self._context.cursor.execute(server.insert_string)
def update_server(self, server: Server): def update_server(self, server: Server):
self._logger.trace(__name__, f'Send SQL command: {server.udpate_string}') self._logger.trace(__name__, f'Send SQL command: {server.udpate_string}')
self._context.cursor.execute(server.udpate_string) self._context.cursor.execute(server.udpate_string)
def delete_server(self, server: Server): def delete_server(self, server: Server):
self._logger.trace(__name__, f'Send SQL command: {server.delete_string}') self._logger.trace(__name__, f'Send SQL command: {server.delete_string}')
self._context.cursor.execute(server.delete_string) self._context.cursor.execute(server.delete_string)