Improved ariadne with DI
This commit is contained in:
parent
b13695b018
commit
77e18027a0
@ -21,6 +21,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_service import GraphQLService
|
||||||
|
|
||||||
|
|
||||||
class Api(Flask):
|
class Api(Flask):
|
||||||
@ -32,6 +33,7 @@ class Api(Flask):
|
|||||||
api_settings: ApiSettings,
|
api_settings: ApiSettings,
|
||||||
frontend_settings: FrontendSettings,
|
frontend_settings: FrontendSettings,
|
||||||
auth_settings: AuthenticationSettings,
|
auth_settings: AuthenticationSettings,
|
||||||
|
graphql: GraphQLService,
|
||||||
*args, **kwargs
|
*args, **kwargs
|
||||||
):
|
):
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -7,8 +7,8 @@ from flask import request, jsonify
|
|||||||
|
|
||||||
from bot_api.logging.api_logger import ApiLogger
|
from bot_api.logging.api_logger import ApiLogger
|
||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
from bot_data.abc.query_abc import QueryABC
|
|
||||||
from bot_data.graphql.query import Query
|
from bot_data.graphql.query import Query
|
||||||
|
from bot_data.graphql.schema import Schema
|
||||||
|
|
||||||
|
|
||||||
class GraphQLController:
|
class GraphQLController:
|
||||||
@ -19,10 +19,12 @@ class GraphQLController:
|
|||||||
config: ConfigurationABC,
|
config: ConfigurationABC,
|
||||||
env: ApplicationEnvironmentABC,
|
env: ApplicationEnvironmentABC,
|
||||||
logger: ApiLogger,
|
logger: ApiLogger,
|
||||||
|
schema: Schema,
|
||||||
):
|
):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._env = env
|
self._env = env
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
self._schema = schema
|
||||||
|
|
||||||
@Route.get(f'{BasePath}/playground')
|
@Route.get(f'{BasePath}/playground')
|
||||||
async def playground(self):
|
async def playground(self):
|
||||||
@ -30,13 +32,12 @@ class GraphQLController:
|
|||||||
|
|
||||||
@Route.post(f'{BasePath}')
|
@Route.post(f'{BasePath}')
|
||||||
async def graphql(self):
|
async def graphql(self):
|
||||||
QueryABC.init()
|
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
|
||||||
# Note: Passing the request to the context is optional.
|
# Note: Passing the request to the context is optional.
|
||||||
# In Flask, the current request is always accessible as flask.request
|
# In Flask, the current request is always accessible as flask.request
|
||||||
success, result = graphql_sync(
|
success, result = graphql_sync(
|
||||||
make_executable_schema(Query),
|
self._schema.schema,
|
||||||
data,
|
data,
|
||||||
context_value=request
|
context_value=request
|
||||||
)
|
)
|
||||||
|
@ -1,64 +1,5 @@
|
|||||||
from ariadne_graphql_modules import ObjectType
|
from ariadne import ObjectType
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
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
|
|
||||||
from modules.level.service.level_service import LevelService
|
|
||||||
|
|
||||||
|
|
||||||
class QueryABC(ObjectType):
|
class QueryABC(ObjectType):
|
||||||
__abstract__ = True
|
__abstract__ = True
|
||||||
|
|
||||||
_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]
|
|
||||||
|
|
||||||
_bot: DiscordBotServiceABC
|
|
||||||
_level_service: LevelService
|
|
||||||
|
|
||||||
@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,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
level_service: LevelService,
|
|
||||||
):
|
|
||||||
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()
|
|
||||||
cls._bot = bot
|
|
||||||
cls._level_service = level_service
|
|
||||||
|
@ -10,11 +10,17 @@ from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
|||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||||
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
||||||
|
from bot_data.abc.query_abc import QueryABC
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
from bot_data.abc.statistic_repository_abc import StatisticRepositoryABC
|
from bot_data.abc.statistic_repository_abc import StatisticRepositoryABC
|
||||||
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
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_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
||||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||||
|
from bot_data.graphql.graphql_service import GraphQLService
|
||||||
|
from bot_data.graphql.query import Query
|
||||||
|
from bot_data.graphql.schema import Schema
|
||||||
|
from bot_data.graphql.server_query import ServerQuery
|
||||||
|
from bot_data.graphql.types.server_query_type import ServerQueryType
|
||||||
from bot_data.service.auth_user_repository_service import AuthUserRepositoryService
|
from bot_data.service.auth_user_repository_service import AuthUserRepositoryService
|
||||||
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
|
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
|
||||||
from bot_data.service.client_repository_service import ClientRepositoryService
|
from bot_data.service.client_repository_service import ClientRepositoryService
|
||||||
@ -48,4 +54,10 @@ class DataModule(ModuleABC):
|
|||||||
services.add_transient(LevelRepositoryABC, LevelRepositoryService)
|
services.add_transient(LevelRepositoryABC, LevelRepositoryService)
|
||||||
services.add_transient(StatisticRepositoryABC, StatisticRepositoryService)
|
services.add_transient(StatisticRepositoryABC, StatisticRepositoryService)
|
||||||
|
|
||||||
|
services.add_singleton(Schema)
|
||||||
|
services.add_singleton(GraphQLService)
|
||||||
|
services.add_singleton(Query)
|
||||||
|
# services.add_transient(QueryABC, ServerQuery)
|
||||||
|
services.add_transient(QueryABC, ServerQueryType)
|
||||||
|
|
||||||
services.add_transient(SeederService)
|
services.add_transient(SeederService)
|
||||||
|
7
kdb-bot/src/bot_data/graphql/graphql_service.py
Normal file
7
kdb-bot/src/bot_data/graphql/graphql_service.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from bot_data.abc.query_abc import QueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class GraphQLService:
|
||||||
|
|
||||||
|
def __init__(self, queries: list[QueryABC]):
|
||||||
|
self._queries = queries
|
@ -1,17 +1,18 @@
|
|||||||
from ariadne import gql
|
from ariadne import QueryType
|
||||||
|
|
||||||
from bot_data.abc.query_abc import QueryABC
|
from bot_data.service.server_repository_service import ServerRepositoryService
|
||||||
from bot_data.graphql.types.server_query_type import ServerQueryType
|
|
||||||
|
|
||||||
|
|
||||||
class Query(QueryABC):
|
class Query(QueryType):
|
||||||
__schema__ = gql("""
|
|
||||||
type Query {
|
|
||||||
servers: [Server]
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
__requires__ = [ServerQueryType]
|
|
||||||
|
|
||||||
@classmethod
|
def __init__(
|
||||||
def resolve_servers(cls, *_):
|
self,
|
||||||
return cls._servers
|
servers: ServerRepositoryService
|
||||||
|
):
|
||||||
|
QueryType.__init__(self)
|
||||||
|
self._servers = servers
|
||||||
|
|
||||||
|
self.set_field('servers', self.resolve_servers)
|
||||||
|
|
||||||
|
def resolve_servers(self, *_):
|
||||||
|
return self._servers.get_servers()
|
||||||
|
31
kdb-bot/src/bot_data/graphql/schema.py
Normal file
31
kdb-bot/src/bot_data/graphql/schema.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from ariadne import make_executable_schema, gql
|
||||||
|
from graphql import GraphQLSchema
|
||||||
|
|
||||||
|
from bot_data.graphql.query import Query
|
||||||
|
from bot_data.graphql.server_query import ServerQuery
|
||||||
|
from bot_data.graphql.types.server_query_type import ServerQueryType
|
||||||
|
|
||||||
|
|
||||||
|
class Schema:
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
query: Query,
|
||||||
|
server_query: ServerQuery,
|
||||||
|
server_query_type: ServerQueryType
|
||||||
|
):
|
||||||
|
type_defs = gql("""
|
||||||
|
type Query {
|
||||||
|
servers: [Server]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server {
|
||||||
|
id: Int
|
||||||
|
discord_id: String
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
self._schema = make_executable_schema(type_defs, query, server_query_type)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def schema(self) -> GraphQLSchema:
|
||||||
|
return self._schema
|
20
kdb-bot/src/bot_data/graphql/server_query.py
Normal file
20
kdb-bot/src/bot_data/graphql/server_query.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from bot_data.abc.query_abc import QueryABC
|
||||||
|
from bot_data.graphql.query import Query
|
||||||
|
from bot_data.service.server_repository_service import ServerRepositoryService
|
||||||
|
|
||||||
|
|
||||||
|
class ServerQuery(QueryABC):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
query: Query,
|
||||||
|
servers: ServerRepositoryService
|
||||||
|
):
|
||||||
|
QueryABC.__init__(self, 'servers')
|
||||||
|
self._query = query
|
||||||
|
self._servers = servers
|
||||||
|
|
||||||
|
query.set_field('servers', self.resolve_servers)
|
||||||
|
|
||||||
|
async def resolve_servers(self):
|
||||||
|
return self._servers.get_servers()
|
@ -1,22 +0,0 @@
|
|||||||
from ariadne import gql
|
|
||||||
|
|
||||||
from bot_data.abc.query_abc import QueryABC
|
|
||||||
from bot_data.model.client import Client
|
|
||||||
|
|
||||||
|
|
||||||
class ClientQueryType(QueryABC):
|
|
||||||
__schema__ = gql("""
|
|
||||||
type Client {
|
|
||||||
id: ID
|
|
||||||
discord_id: String
|
|
||||||
sent_message_count: Int
|
|
||||||
received_message_count: Int
|
|
||||||
deleted_message_count: Int
|
|
||||||
received_command_count: Int
|
|
||||||
moved_users_count: Int
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_id(cls, client: Client, *_):
|
|
||||||
return client.client_id
|
|
@ -1,21 +0,0 @@
|
|||||||
from ariadne import gql
|
|
||||||
|
|
||||||
from bot_data.abc.query_abc import QueryABC
|
|
||||||
from bot_data.model.client import Client
|
|
||||||
from bot_data.model.level import Level
|
|
||||||
|
|
||||||
|
|
||||||
class LevelQueryType(QueryABC):
|
|
||||||
__schema__ = gql("""
|
|
||||||
type Level {
|
|
||||||
id: ID
|
|
||||||
name: String
|
|
||||||
color: String
|
|
||||||
min_xp: Int
|
|
||||||
permissions: String
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# def resolve_id(cls, level: Level, *_):
|
|
||||||
# return level.id
|
|
@ -1,40 +1,21 @@
|
|||||||
from ariadne import gql
|
from ariadne import ObjectType
|
||||||
|
|
||||||
from bot_data.abc.query_abc import QueryABC
|
from bot_data.abc.query_abc import QueryABC
|
||||||
from bot_data.graphql.types.client_query_type import ClientQueryType
|
|
||||||
from bot_data.graphql.types.level_query_type import LevelQueryType
|
|
||||||
from bot_data.graphql.types.user_query_type import UserQueryType
|
|
||||||
from bot_data.model.server import Server
|
from bot_data.model.server import Server
|
||||||
|
|
||||||
|
|
||||||
class ServerQueryType(QueryABC):
|
class ServerQueryType(QueryABC):
|
||||||
__schema__ = gql("""
|
|
||||||
type Server {
|
|
||||||
id: ID
|
|
||||||
discord_id: String
|
|
||||||
clients: [Client]
|
|
||||||
users: [User]
|
|
||||||
levels: [Level]
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
__requires__ = [ClientQueryType, UserQueryType, LevelQueryType]
|
|
||||||
|
|
||||||
@classmethod
|
def __init__(self):
|
||||||
def resolve_id(cls, server: Server, *_):
|
QueryABC.__init__(self, 'Server')
|
||||||
|
|
||||||
|
self.set_field('id', self.resolve_id)
|
||||||
|
self.set_field('discord_id', self.resolve_discord_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_id(server: Server, *_):
|
||||||
return server.server_id
|
return server.server_id
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def resolve_discord_id(cls, server: Server, *_):
|
def resolve_discord_id(server: Server, *_):
|
||||||
return server.discord_server_id
|
return server.discord_server_id
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_clients(cls, server: Server, *_):
|
|
||||||
return cls._clients.where(lambda c: c.server.server_id == server.server_id)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_users(cls, server: Server, *_):
|
|
||||||
return cls._users.where(lambda u: u.server.server_id == server.server_id)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_levels(cls, server: Server, *_):
|
|
||||||
return cls._levels.where(lambda l: l.server.server_id == server.server_id)
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
from ariadne import gql
|
|
||||||
|
|
||||||
from bot_data.abc.query_abc import QueryABC
|
|
||||||
from bot_data.graphql.types.level_query_type import LevelQueryType
|
|
||||||
from bot_data.model.user import User
|
|
||||||
|
|
||||||
|
|
||||||
class UserQueryType(QueryABC):
|
|
||||||
__schema__ = gql("""
|
|
||||||
type User {
|
|
||||||
id: ID
|
|
||||||
discord_id: String
|
|
||||||
name: String
|
|
||||||
xp: Int
|
|
||||||
ontime: Int
|
|
||||||
level: Level
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
__requires__ = [LevelQueryType]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_id(cls, user: User, *_):
|
|
||||||
return user.user_id
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_name(cls, user: User, *_):
|
|
||||||
return cls._bot.get_user(user.discord_id).name
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_ontime(cls, user: User, *_):
|
|
||||||
return cls._user_joined_voice_channel.where(lambda ujvc: ujvc.user.user_id == user.user_id) \
|
|
||||||
.where(lambda x: x.leaved_on is not None and x.joined_on is not None) \
|
|
||||||
.sum(lambda join: round((join.leaved_on - join.joined_on).total_seconds() / 3600, 2))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resolve_level(cls, user: User, *_):
|
|
||||||
levels = cls._levels.where(lambda l: l.server.server_id == user.server.server_id).order_by(lambda l: l.min_xp)
|
|
||||||
return levels.where(lambda l: user.xp >= l.min_xp).last_or_default()
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user