Cat Feeder  1.0.0
The Cat feeder project
Loading...
Searching...
No Matches
server.py
Go to the documentation of this file.
1r"""
2# +==== BEGIN CatFeeder =================+
3# LOGO:
4# ..............(..../\
5# ...............)..(.')
6# ..............(../..)
7# ...............\‍(__)|
8# Inspired by Joan Stark
9# source https://www.asciiart.eu/
10# animals/cats
11# /STOP
12# PROJECT: CatFeeder
13# FILE: server.py
14# CREATION DATE: 19-11-2025
15# LAST Modified: 23:3:21 10-01-2026
16# DESCRIPTION:
17# This is the backend server in charge of making the actual website work.
18# /STOP
19# COPYRIGHT: (c) Cat Feeder
20# PURPOSE: The main class required to set up the environement for the server to run properly.
21# // AR
22# +==== END CatFeeder =================+
23"""
24
25from display_tty import Disp, initialise_logger
26from .sql import SQL
27from .bucket import Bucket
28from .e_mail import MailManagement
29from .path_manager import PathManager
30from .docs import DocumentationHandler
31from .image_reducer import ImageReducer
32from .server_header import ServerHeaders
33from .crons import BackgroundTasks, Crons
34from .endpoint_manager import EndpointManager
35from .utils import CONST, OAuthAuthentication
36from .favicon import FaviconUser, FaviconAdmin
37from .core import ServerManagement, FinalClass, RuntimeControl, RuntimeManager, RI
38from .boilerplates import BoilerplateIncoming, BoilerplateNonHTTP, BoilerplateResponses
39
40
41class Server(metaclass=FinalClass):
42 """_summary_
43 """
44
45 disp: Disp = initialise_logger(__qualname__, False)
46
47 def __init__(self, host: str = "0.0.0.0", port: int = 5000, success: int = 0, error: int = 84, app_name: str = "Asperguide", debug: bool = False) -> None:
48 """_summary_
49 This is the class Server, a class that contains the structures used to allow the uvicorn and fastapi combo to run successfully.
50 host (str, optional): _description_. Defaults to "0.0.0.0".
51 port (int, optional): _description_. Defaults to 5000.
52 character_folder (str, optional): _description_. Defaults to "".
53 usr_db_path (str, optional): _description_. Defaults to "".
54 success (int, optional): _description_. Defaults to 0.
55 error (int, optional): _description_. Defaults to 84.
56 app_name (str, optional): _description_. Defaults to "Desktop Pets".
57 debug (bool, optional): _description_. Defaults to False.
58 """
59 # ------------------------ The logging function ------------------------
60 self.disp.update_disp_debug(debug)
61 self.disp.log_debug("Initialising...")
62 # --------------------- The inherited arguments ---------------------
63 self.host: str = host
64 self.port: int = port
65 self.success: int = success
66 self.error: int = error
67 self.debug: bool = debug
68 self.app_name: str = app_name
69 # ------------------------ Shared Runtime data ------------------------
70 self.runtime_manager: RuntimeManager = RI
71 RuntimeManager.update_debug(self.debug)
72 RI.update_debug(self.debug)
73 # ----- The classes that need to be tracked for the server to run -----
74 self.runtime_manager.set(RuntimeControl)
75 self.runtime_manager.set(
76 ServerHeaders,
77 **{
78 "host": self.host,
79 "port": self.port,
80 "app_name": self.app_name,
81 "error": self.error,
82 "success": self.success,
83 "debug": self.debug
84 }
85 )
86 self.disp.log_debug("Initialising database link.", "__init__")
87 self.runtime_manager.set(
88 SQL,
89 url=CONST.DB_HOST,
90 port=CONST.DB_PORT,
91 username=CONST.DB_USER,
92 password=CONST.DB_PASSWORD,
93 db_name=CONST.DB_DATABASE,
94 success=self.success,
95 error=self.error,
96 debug=self.debug
97 )
98 self.runtime_manager.set(
99 Bucket,
100 **{"success": self.success, "error": self.error, "debug": self.debug}
101 )
102 self.runtime_manager.set(
103 BackgroundTasks,
104 **{"success": self.success, "error": self.error, "debug": self.debug}
105 )
106 self.runtime_manager.set(
107 Crons,
108 **{"success": self.success, "error": self.error, "debug": self.debug}
109 )
110 self.runtime_manager.set(
111 ServerManagement,
112 **{"success": self.success, "error": self.error, "debug": self.debug}
113 )
114 self.runtime_manager.set(
115 BoilerplateResponses,
116 **{"debug": self.debug}
117 )
118 self.runtime_manager.set(
119 BoilerplateIncoming,
120 **{"success": self.success, "error": self.error, "debug": self.debug}
121 )
122 self.runtime_manager.set(
123 BoilerplateNonHTTP,
124 **{"success": self.success, "error": self.error, "debug": self.debug}
125 )
126 self.runtime_manager.set(
127 PathManager,
128 **{"success": self.success, "error": self.error, "debug": self.debug}
129 )
130 self.runtime_manager.set(
131 EndpointManager,
132 **{"success": self.success, "error": self.error, "debug": self.debug}
133 )
134 self.runtime_manager.set(
135 OAuthAuthentication,
136 **{"success": self.success, "error": self.error, "debug": self.debug}
137 )
138 self.runtime_manager.set(
139 MailManagement,
140 **{"success": self.success, "error": self.error, "debug": self.debug}
141 )
142 self.runtime_manager.set(
143 DocumentationHandler,
144 **{"success": self.success, "error": self.error, "debug": self.debug}
145 )
146 self.runtime_manager.set(
147 ImageReducer,
148 **{"success": self.success, "error": self.error, "debug": self.debug}
149 )
150 self.runtime_manager.set(
151 FaviconUser,
152 **{"success": self.success, "error": self.error, "debug": self.debug}
153 )
154 self.runtime_manager.set(
155 FaviconAdmin,
156 **{"success": self.success, "error": self.error, "debug": self.debug}
157 )
158 #
159 # -------------------------- Shared instances --------------------------
160 self.server_management_initialised: ServerManagement = self.runtime_manager.get(
161 ServerManagement)
162 self.paths_initialised: PathManager = self.runtime_manager.get(
163 PathManager)
164 self.crons_initialised: Crons = self.runtime_manager.get(Crons)
165 self.background_tasks_initialised: BackgroundTasks = self.runtime_manager.get(
166 BackgroundTasks)
167 self.runtime_control: RuntimeControl = self.runtime_manager.get(
168 RuntimeControl)
169 self.sql_connection: SQL = self.runtime_manager.get(SQL)
170 self.disp.log_debug("Initialised")
171
172 def __del__(self) -> None:
173 """_summary_
174 The destructor of the class.
175 """
176 self.disp.log_info("The server is shutting down.", "__del__")
177 self.stop_server()
178
179 def main(self) -> int:
180 """_summary_
181 The main function of the server.
182 This is the one in charge of starting the server.
183
184 Returns:
185 int: _description_
186 """
187 self.server_management_initialised.initialise_classes()
188 self.paths_initialised.load_default_paths_initialised()
189 self.paths_initialised.inject_routes()
190 self.crons_initialised.inject_crons()
191 status = self.background_tasks_initialised.safe_start()
192 if status != self.success:
193 self.disp.log_error(
194 "Error: background tasks failed to start.",
195 "main"
196 )
197 return status
198 try:
199 if not self.runtime_control.server:
200 raise RuntimeError("No server to start")
201 self.runtime_control.server.run()
202 except Exception as e:
203 self.disp.log_error(f"Error: {e}", "main")
204 return self.error
205 return self.success
206
207 def is_running(self) -> bool:
208 """_summary_
209 The function in charge of checking if the server is running.
210
211 Returns:
212 bool: _description_: Returns True if the server is running.
213 """
214 return self.server_management_initialised.is_server_running()
215
216 def stop_server(self) -> None:
217 """_summary_
218 The function in charge of stopping the server.
219 """
220 title = "stop_server"
221 self.disp.log_info("Stopping server", title)
222 if hasattr(self, "server_management_initialised") and self.server_management_initialised is not None:
224 if hasattr(self, "crons_initialised") and self.crons_initialised is not None:
225 del self.crons_initialised
226 self.disp.log_info("Server stopped", title)
BackgroundTasks background_tasks_initialised
Definition server.py:165
ServerManagement server_management_initialised
Definition server.py:160
RuntimeControl runtime_control
Definition server.py:167
RuntimeManager runtime_manager
Definition server.py:70
None __init__(self, str host="0.0.0.0", int port=5000, int success=0, int error=84, str app_name="Asperguide", bool debug=False)
Definition server.py:47