Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Implement statistics endpoint #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion backend/src/contaxy/api/endpoints/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,15 @@ def check_health(
responses={**AUTH_ERROR_RESPONSES},
)
def get_system_statistics(
include_technical: bool = True,
component_manager: ComponentManager = Depends(get_component_manager),
token: str = Depends(get_api_token),
) -> Any:
"""Returns statistics about this instance."""
component_manager.verify_access(token, "system", AccessLevel.READ)
return component_manager.get_system_manager().get_system_statistics()
return component_manager.get_system_manager().get_system_statistics(
include_technical
)


@router.post(
Expand Down
10 changes: 8 additions & 2 deletions backend/src/contaxy/clients/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ def is_healthy(self, request_kwargs: Dict = {}) -> bool:
handle_errors(response)
return True

def get_system_statistics(self, request_kwargs: Dict = {}) -> SystemStatistics:
response = self._client.get("/system/statistics", **request_kwargs)
def get_system_statistics(
self, include_technical: bool = True, request_kwargs: Dict = {}
) -> SystemStatistics:
response = self._client.get(
"/system/statistics",
params={"include_technical": include_technical},
**request_kwargs,
)
handle_errors(response)
return parse_raw_as(SystemStatistics, response.text)

Expand Down
3 changes: 3 additions & 0 deletions backend/src/contaxy/managers/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ def get_system_manager(self) -> SystemManager:
self.get_json_db_manager(),
self.get_auth_manager(),
self.get_project_manager(),
self.get_service_manager(),
self.get_job_manager(),
self.get_file_manager(),
)

assert self._system_manager is not None
Expand Down
85 changes: 78 additions & 7 deletions backend/src/contaxy/managers/system.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
from typing import Optional
from typing import List, Optional

from contaxy import __version__, config
from contaxy.config import settings
from contaxy.managers.auth import AuthManager
from contaxy.operations import SystemOperations
from contaxy.operations import (
FileOperations,
JobOperations,
ServiceOperations,
SystemOperations,
)
from contaxy.operations.json_db import JsonDocumentOperations
from contaxy.operations.project import ProjectOperations
from contaxy.schema.auth import ADMIN_ROLE, USERS_KIND, AccessLevel, UserRegistration
from contaxy.schema.project import ProjectCreation
from contaxy.schema import File, Job, Service
from contaxy.schema.auth import (
ADMIN_ROLE,
USERS_KIND,
AccessLevel,
User,
UserRegistration,
)
from contaxy.schema.project import Project, ProjectCreation
from contaxy.schema.system import SystemInfo, SystemStatistics
from contaxy.utils import auth_utils
from contaxy.utils.state_utils import GlobalState, RequestState
Expand All @@ -23,6 +35,9 @@ def __init__(
json_db_manager: JsonDocumentOperations,
auth_manager: AuthManager,
project_manager: ProjectOperations,
service_manager: ServiceOperations,
job_manager: JobOperations,
file_manager: FileOperations,
):
"""Initializes the system manager.

Expand All @@ -32,12 +47,18 @@ def __init__(
json_db_manager: Json document manager instance.
auth_manager: Auth manager instance.
project_manager: Project manager instance.
service_manager: Service manager instance.
job_manager: Job manager instance.
file_manager: File manager instance.
"""
self._global_state = global_state
self._request_state = request_state
self._auth_manager = auth_manager
self._project_manager = project_manager
self._json_db_manager = json_db_manager
self._service_manager = service_manager
self._job_manager = job_manager
self._file_manager = file_manager

def get_system_info(self) -> SystemInfo:
return SystemInfo(
Expand All @@ -49,10 +70,18 @@ def is_healthy(self) -> bool:
# TODO: do real healthchecks
return True

def get_system_statistics(self) -> SystemStatistics:
# TODO: Implement system statistics
def get_system_statistics(self, include_technical: bool) -> SystemStatistics:
projects = self._list_all_projects(include_technical)
users = self._list_all_users(include_technical)
jobs = self._list_all_jobs(projects)
services = self._list_all_services(projects)
files = self._list_all_files(projects)
return SystemStatistics(
project_count=0, user_count=0, job_count=0, service_count=0, file_count=0
project_count=len(jobs),
user_count=len(users),
job_count=len(jobs),
service_count=len(services),
file_count=len(files),
)

def initialize_system(
Expand Down Expand Up @@ -103,3 +132,45 @@ def initialize_system(
)

auth_utils.create_user_project(admin_user, self._project_manager)

def _list_all_projects(self, include_technical: bool) -> List[Project]:
# Temporarily set authorized_access to None so that list_projects returns all projects
# TODO: Find better solution to get all projects
temp = self._request_state.authorized_access
self._request_state.authorized_access = None
projects = self._project_manager.list_projects()
self._request_state.authorized_access = temp

if not include_technical:
projects = [proj for proj in projects if not proj.technical_project]
return projects

def _list_all_users(self, include_technical: bool) -> List[User]:
users = self._auth_manager.list_users()
if not include_technical:
users = [user for user in users if not user.technical_user]
return users

def _list_all_jobs(self, projects: List[Project]) -> List[Job]:
return [
job
for project in projects
if project.id
for job in self._job_manager.list_jobs(project.id)
]

def _list_all_services(self, projects: List[Project]) -> List[Service]:
return [
service
for project in projects
if project.id
for service in self._service_manager.list_services(project.id)
]

def _list_all_files(self, projects: List[Project]) -> List[File]:
return [
file
for project in projects
if project.id
for file in self._file_manager.list_files(project.id)
]
2 changes: 1 addition & 1 deletion backend/src/contaxy/operations/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def is_healthy(self) -> bool:
pass

@abstractmethod
def get_system_statistics(self) -> SystemStatistics:
def get_system_statistics(self, include_technical: bool) -> SystemStatistics:
pass

@abstractmethod
Expand Down