square_administration 4.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,74 @@
1
+ Metadata-Version: 2.3
2
+ Name: square_administration
3
+ Version: 4.0.0
4
+ Summary: common business layer for my personal server.
5
+ Keywords: administration,fastapi,backend
6
+ Author: Parth Mukesh Mangtani
7
+ Author-email: Parth Mukesh Mangtani <thepmsquare@gmail.com>
8
+ License: GPLv3
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Utilities
16
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
17
+ Classifier: Framework :: FastAPI
18
+ Requires-Dist: uvicorn>=0.24.0.post1
19
+ Requires-Dist: fastapi>=0.104.1
20
+ Requires-Dist: pydantic>=2.5.3
21
+ Requires-Dist: requests>=2.32.3
22
+ Requires-Dist: bcrypt>=4.2.0
23
+ Requires-Dist: httpx>=0.27.2
24
+ Requires-Dist: square-commons>=2.1.0
25
+ Requires-Dist: square-logger>=3.0.0
26
+ Requires-Dist: square-database-helper>=2.0.0
27
+ Requires-Dist: square-database-structure>=1.0.0
28
+ Requires-Dist: square-authentication-helper>=3.0.0
29
+ Requires-Dist: pytest>=8.3.3 ; extra == 'all'
30
+ Requires-Dist: pytest>=8.3.3 ; extra == 'dev'
31
+ Requires-Python: >=3.12
32
+ Project-URL: homepage, https://github.com/thepmsquare/square_administration
33
+ Provides-Extra: all
34
+ Provides-Extra: dev
35
+ Description-Content-Type: text/markdown
36
+
37
+ # square_administration
38
+
39
+ > 📌 versioning: see [CHANGELOG.md](./CHANGELOG.md).
40
+
41
+ ## about
42
+
43
+ administration business layer for my personal server.
44
+
45
+ ## goals
46
+
47
+ - administration-specific logic
48
+ - api grouped by usecase
49
+ - integration with square_*
50
+ - simple and sufficient
51
+
52
+ ## installation
53
+
54
+ ```shell
55
+ pip install square_administration
56
+ ```
57
+
58
+ ## usage
59
+
60
+ ### configuration
61
+
62
+ update the settings in `config.ini` and `config.testing.ini` to match your environment (urls, logging, etc.).
63
+
64
+ ### running the service
65
+
66
+ ```shell
67
+ python square_common_bl/main.py
68
+ ```
69
+
70
+ ## env
71
+
72
+ - python>=3.12.0
73
+
74
+ > feedback is appreciated. thank you!
@@ -0,0 +1,38 @@
1
+ # square_administration
2
+
3
+ > 📌 versioning: see [CHANGELOG.md](./CHANGELOG.md).
4
+
5
+ ## about
6
+
7
+ administration business layer for my personal server.
8
+
9
+ ## goals
10
+
11
+ - administration-specific logic
12
+ - api grouped by usecase
13
+ - integration with square_*
14
+ - simple and sufficient
15
+
16
+ ## installation
17
+
18
+ ```shell
19
+ pip install square_administration
20
+ ```
21
+
22
+ ## usage
23
+
24
+ ### configuration
25
+
26
+ update the settings in `config.ini` and `config.testing.ini` to match your environment (urls, logging, etc.).
27
+
28
+ ### running the service
29
+
30
+ ```shell
31
+ python square_common_bl/main.py
32
+ ```
33
+
34
+ ## env
35
+
36
+ - python>=3.12.0
37
+
38
+ > feedback is appreciated. thank you!
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["uv-build"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "square_administration"
7
+ version = "4.0.0"
8
+ description = "common business layer for my personal server."
9
+ readme = "README.md"
10
+ readme-content-type = "text/markdown"
11
+ requires-python = ">=3.12"
12
+ license = { text = "GPLv3" }
13
+ authors = [
14
+ { name = "Parth Mukesh Mangtani", email = "thepmsquare@gmail.com" },
15
+ ]
16
+ urls = { homepage = "https://github.com/thepmsquare/square_administration" }
17
+ keywords = ["administration", "fastapi", "backend"]
18
+ dependencies = [
19
+ "uvicorn>=0.24.0.post1",
20
+ "fastapi>=0.104.1",
21
+ "pydantic>=2.5.3",
22
+ "requests>=2.32.3",
23
+ "bcrypt>=4.2.0",
24
+ "httpx>=0.27.2",
25
+ "square_commons>=2.1.0",
26
+ "square_logger>=3.0.0",
27
+ "square_database_helper>=2.0.0",
28
+ "square_database_structure>=1.0.0",
29
+ "square_authentication_helper>=3.0.0",
30
+ ]
31
+ optional-dependencies = { all = ["pytest>=8.3.3"], dev = ["pytest>=8.3.3"] }
32
+ classifiers = [
33
+ "Development Status :: 3 - Alpha",
34
+ "Intended Audience :: Developers",
35
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
36
+ "Programming Language :: Python :: 3",
37
+ "Programming Language :: Python :: 3.12",
38
+ "Programming Language :: Python :: 3 :: Only",
39
+ "Topic :: Utilities",
40
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
41
+ "Framework :: FastAPI"
42
+ ]
43
+
44
+ [tool.uv.build-backend]
45
+ module-name = "square_administration"
46
+ module-root = ""
47
+ source-include = ["square_administration/data/*"]
@@ -0,0 +1,120 @@
1
+ import os
2
+ import sys
3
+
4
+ from square_authentication_helper import SquareAuthenticationHelper
5
+ from square_commons import ConfigReader
6
+ from square_database_helper import SquareDatabaseHelper
7
+ from square_logger.main import SquareLogger
8
+
9
+ try:
10
+ config_file_path = os.path.join(
11
+ os.path.dirname(os.path.abspath(__file__)), "data", "config.ini"
12
+ )
13
+ config_sample_file_path = os.path.join(
14
+ os.path.dirname(os.path.abspath(__file__)), "data", "config.sample.ini"
15
+ )
16
+ ldict_configuration = ConfigReader(
17
+ config_file_path, config_sample_file_path
18
+ ).read_configuration()
19
+ # get all vars and typecast
20
+ # ===========================================
21
+ # general
22
+ config_str_module_name = ldict_configuration["GENERAL"]["MODULE_NAME"]
23
+ config_str_app_name = ldict_configuration["GENERAL"]["APP_NAME"]
24
+ # ===========================================
25
+
26
+ # ===========================================
27
+ # environment
28
+ config_str_host_ip = ldict_configuration["ENVIRONMENT"]["HOST_IP"]
29
+ config_int_host_port = int(ldict_configuration["ENVIRONMENT"]["HOST_PORT"])
30
+ config_list_allow_origins = eval(
31
+ ldict_configuration["ENVIRONMENT"]["ALLOW_ORIGINS"]
32
+ )
33
+ config_str_log_file_name = ldict_configuration["ENVIRONMENT"]["LOG_FILE_NAME"]
34
+ config_str_admin_password_hash = ldict_configuration["ENVIRONMENT"][
35
+ "ADMIN_PASSWORD_HASH"
36
+ ]
37
+
38
+ config_str_ssl_crt_file_path = ldict_configuration["ENVIRONMENT"][
39
+ "SSL_CRT_FILE_PATH"
40
+ ]
41
+ config_str_ssl_key_file_path = ldict_configuration["ENVIRONMENT"][
42
+ "SSL_KEY_FILE_PATH"
43
+ ]
44
+ config_str_cookie_domain = ldict_configuration["ENVIRONMENT"]["COOKIE_DOMAIN"]
45
+ config_str_db_ip = ldict_configuration["ENVIRONMENT"]["DB_IP"]
46
+ config_int_db_port = int(ldict_configuration["ENVIRONMENT"]["DB_PORT"])
47
+ config_str_db_username = ldict_configuration["ENVIRONMENT"]["DB_USERNAME"]
48
+ config_str_db_password = ldict_configuration["ENVIRONMENT"]["DB_PASSWORD"]
49
+ # ===========================================
50
+
51
+ # ===========================================
52
+ # square_logger
53
+ config_int_log_level = int(ldict_configuration["SQUARE_LOGGER"]["LOG_LEVEL"])
54
+ config_str_log_path = ldict_configuration["SQUARE_LOGGER"]["LOG_PATH"]
55
+ config_int_log_backup_count = int(
56
+ ldict_configuration["SQUARE_LOGGER"]["LOG_BACKUP_COUNT"]
57
+ )
58
+ config_formatter_choice = ldict_configuration["SQUARE_LOGGER"]["FORMATTER_CHOICE"]
59
+ if config_formatter_choice not in ("human_readable", "json"):
60
+ raise ValueError(f"Invalid formatter choice: {config_formatter_choice}")
61
+ config_bool_enable_redaction = eval(
62
+ ldict_configuration["SQUARE_LOGGER"]["ENABLE_REDACTION"]
63
+ )
64
+ # ===========================================
65
+
66
+ # ===========================================
67
+ # square_database_helper
68
+
69
+ config_str_square_database_protocol = ldict_configuration["SQUARE_DATABASE_HELPER"][
70
+ "SQUARE_DATABASE_PROTOCOL"
71
+ ]
72
+ config_str_square_database_ip = ldict_configuration["SQUARE_DATABASE_HELPER"][
73
+ "SQUARE_DATABASE_IP"
74
+ ]
75
+ config_int_square_database_port = int(
76
+ ldict_configuration["SQUARE_DATABASE_HELPER"]["SQUARE_DATABASE_PORT"]
77
+ )
78
+ # ===========================================
79
+ # ===========================================
80
+ # square_authentication_helper
81
+
82
+ config_str_square_authentication_protocol = ldict_configuration[
83
+ "SQUARE_AUTHENTICATION_HELPER"
84
+ ]["SQUARE_AUTHENTICATION_PROTOCOL"]
85
+ config_str_square_authentication_ip = ldict_configuration[
86
+ "SQUARE_AUTHENTICATION_HELPER"
87
+ ]["SQUARE_AUTHENTICATION_IP"]
88
+ config_int_square_authentication_port = int(
89
+ ldict_configuration["SQUARE_AUTHENTICATION_HELPER"][
90
+ "SQUARE_AUTHENTICATION_PORT"
91
+ ]
92
+ )
93
+ # ===========================================
94
+ # Initialize logger
95
+ global_object_square_logger = SquareLogger(
96
+ log_file_name=config_str_log_file_name,
97
+ log_level=config_int_log_level,
98
+ log_path=config_str_log_path,
99
+ log_backup_count=config_int_log_backup_count,
100
+ formatter_choice=config_formatter_choice,
101
+ enable_redaction=config_bool_enable_redaction,
102
+ )
103
+
104
+ global_object_square_database_helper = SquareDatabaseHelper(
105
+ param_str_square_database_ip=config_str_square_database_ip,
106
+ param_int_square_database_port=config_int_square_database_port,
107
+ param_str_square_database_protocol=config_str_square_database_protocol,
108
+ )
109
+ global_object_square_authentication_helper = SquareAuthenticationHelper(
110
+ param_str_square_authentication_protocol=config_str_square_authentication_protocol,
111
+ param_str_square_authentication_ip=config_str_square_authentication_ip,
112
+ param_int_square_authentication_port=config_int_square_authentication_port,
113
+ )
114
+
115
+ except Exception as e:
116
+ print(
117
+ "\033[91mMissing or incorrect config.ini file.\n"
118
+ "Error details: " + str(e) + "\033[0m"
119
+ )
120
+ sys.exit()
@@ -0,0 +1,56 @@
1
+ [GENERAL]
2
+ MODULE_NAME = square_administration
3
+ APP_NAME = square_admin
4
+
5
+ [ENVIRONMENT]
6
+ HOST_IP = 0.0.0.0
7
+ HOST_PORT = 10111
8
+ ALLOW_ORIGINS = ["http://localhost:10111"]
9
+
10
+ LOG_FILE_NAME = square_administration
11
+
12
+ ADMIN_PASSWORD_HASH = $2b$12$tDw4ZR0guiF5s5oVve5PcuELhlWO.lUH.OChPoeWVn95ac7QJlndq
13
+
14
+ # absolute path (mandatory only for http)
15
+ SSL_CRT_FILE_PATH = ssl.crt
16
+ SSL_KEY_FILE_PATH = ssl.key
17
+
18
+ COOKIE_DOMAIN = localhost
19
+
20
+ DB_IP = localhost
21
+ DB_PORT = 10001
22
+ DB_USERNAME = postgres
23
+ DB_PASSWORD = dummy
24
+
25
+ [SQUARE_LOGGER]
26
+
27
+ # | Log Level | Value |
28
+ # | --------- | ----- |
29
+ # | CRITICAL | 50 |
30
+ # | ERROR | 40 |
31
+ # | WARNING | 30 |
32
+ # | INFO | 20 |
33
+ # | DEBUG | 10 |
34
+ # | NOTSET | 0 |
35
+
36
+ LOG_LEVEL = 20
37
+ # absolute or relative path
38
+ LOG_PATH = logs
39
+ # number of backup log files to keep during rotation
40
+ # if backupCount is zero, rollover never occurs.
41
+ LOG_BACKUP_COUNT = 3
42
+ # json or human_readable
43
+ FORMATTER_CHOICE = json
44
+ ENABLE_REDACTION = True
45
+
46
+ [SQUARE_DATABASE_HELPER]
47
+
48
+ SQUARE_DATABASE_PROTOCOL = http
49
+ SQUARE_DATABASE_IP = localhost
50
+ SQUARE_DATABASE_PORT = 10010
51
+
52
+ [SQUARE_AUTHENTICATION_HELPER]
53
+
54
+ SQUARE_AUTHENTICATION_PROTOCOL = http
55
+ SQUARE_AUTHENTICATION_IP = localhost
56
+ SQUARE_AUTHENTICATION_PORT = 10011
@@ -0,0 +1,57 @@
1
+ [GENERAL]
2
+ MODULE_NAME = square_administration
3
+ APP_NAME = square_admin
4
+
5
+ [ENVIRONMENT]
6
+ HOST_IP = 0.0.0.0
7
+ HOST_PORT = 10111
8
+ ALLOW_ORIGINS = ["http://localhost:10111"]
9
+
10
+ LOG_FILE_NAME = square_administration
11
+
12
+ ADMIN_PASSWORD_HASH = $2b$12$tDw4ZR0guiF5s5oVve5PcuELhlWO.lUH.OChPoeWVn95ac7QJlndq
13
+
14
+ # absolute path (mandatory only for http)
15
+ SSL_CRT_FILE_PATH = ssl.crt
16
+ SSL_KEY_FILE_PATH = ssl.key
17
+
18
+ COOKIE_DOMAIN = localhost
19
+
20
+ DB_IP = raspi.thepmsquare.com
21
+ DB_PORT = 15432
22
+ DB_USERNAME = postgres
23
+ DB_PASSWORD = testing_password
24
+
25
+
26
+ [SQUARE_LOGGER]
27
+
28
+ # | Log Level | Value |
29
+ # | --------- | ----- |
30
+ # | CRITICAL | 50 |
31
+ # | ERROR | 40 |
32
+ # | WARNING | 30 |
33
+ # | INFO | 20 |
34
+ # | DEBUG | 10 |
35
+ # | NOTSET | 0 |
36
+
37
+ LOG_LEVEL = 20
38
+ # absolute or relative path
39
+ LOG_PATH = logs
40
+ # number of backup log files to keep during rotation
41
+ # if backupCount is zero, rollover never occurs.
42
+ LOG_BACKUP_COUNT = 3
43
+ # json or human_readable
44
+ FORMATTER_CHOICE = json
45
+ ENABLE_REDACTION = True
46
+
47
+ [SQUARE_DATABASE_HELPER]
48
+
49
+ SQUARE_DATABASE_PROTOCOL = http
50
+ SQUARE_DATABASE_IP = raspi.thepmsquare.com
51
+ SQUARE_DATABASE_PORT = 20010
52
+
53
+ [SQUARE_AUTHENTICATION_HELPER]
54
+
55
+ SQUARE_AUTHENTICATION_PROTOCOL = http
56
+ SQUARE_AUTHENTICATION_IP = raspi.thepmsquare.com
57
+ SQUARE_AUTHENTICATION_PORT = 20011
@@ -0,0 +1,58 @@
1
+ from fastapi import FastAPI, status
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import JSONResponse
4
+ from square_commons import get_api_output_in_standard_format
5
+ from uvicorn import run
6
+
7
+ from square_administration.configuration import (
8
+ config_int_host_port,
9
+ config_str_host_ip,
10
+ global_object_square_logger,
11
+ config_str_module_name,
12
+ config_str_ssl_key_file_path,
13
+ config_str_ssl_crt_file_path,
14
+ config_list_allow_origins,
15
+ )
16
+ from square_administration.routes import core, authentication
17
+ from square_administration.utils.common import is_https
18
+
19
+ app = FastAPI()
20
+
21
+ app.add_middleware(
22
+ CORSMiddleware,
23
+ allow_credentials=True,
24
+ allow_origins=config_list_allow_origins,
25
+ allow_methods=["*"],
26
+ allow_headers=["*"],
27
+ )
28
+
29
+ app.include_router(core.router)
30
+ app.include_router(authentication.router)
31
+
32
+
33
+ @app.get("/")
34
+ @global_object_square_logger.auto_logger()
35
+ async def root():
36
+ output_content = get_api_output_in_standard_format(log=config_str_module_name)
37
+ return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
38
+
39
+
40
+ if __name__ == "__main__":
41
+ try:
42
+ if is_https():
43
+ run(
44
+ app,
45
+ host=config_str_host_ip,
46
+ port=config_int_host_port,
47
+ ssl_certfile=config_str_ssl_crt_file_path,
48
+ ssl_keyfile=config_str_ssl_key_file_path,
49
+ )
50
+ else:
51
+ run(
52
+ app,
53
+ host=config_str_host_ip,
54
+ port=config_int_host_port,
55
+ )
56
+
57
+ except Exception as exc:
58
+ global_object_square_logger.logger.critical(exc, exc_info=True)
@@ -0,0 +1,16 @@
1
+ messages = {
2
+ "REGISTRATION_SUCCESSFUL": "registration was successful. welcome aboard!",
3
+ "LOGIN_SUCCESSFUL": "you have logged in successfully.",
4
+ "LOGOUT_SUCCESSFUL": "you have logged out successfully.",
5
+ "INCORRECT_USERNAME": "the username you entered does not exist.",
6
+ "INCORRECT_PASSWORD": "the password you entered is incorrect. please try again.",
7
+ "GENERIC_CREATION_SUCCESSFUL": "records created successfully.",
8
+ "GENERIC_READ_SUCCESSFUL": "data retrieved successfully.",
9
+ "GENERIC_UPDATE_SUCCESSFUL": "your information has been updated successfully.",
10
+ "GENERIC_DELETE_SUCCESSFUL": "your records have been deleted successfully.",
11
+ "GENERIC_400": "the request is invalid or cannot be processed.",
12
+ "GENERIC_500": "an internal server error occurred. please try again later.",
13
+ "INCORRECT_ACCESS_TOKEN": "the access token provided is invalid or expired.",
14
+ "INCORRECT_REFRESH_TOKEN": "the refresh token provided is invalid or expired.",
15
+ "REFRESH_TOKEN_NOT_FOUND": "refresh token not found. please login again.",
16
+ }
@@ -0,0 +1,36 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class RegisterUsernameV0(BaseModel):
5
+ username: str
6
+ password: str
7
+ admin_password: str
8
+
9
+
10
+ class LoginUsernameV0(BaseModel):
11
+ username: str
12
+ password: str
13
+
14
+
15
+ class RemoveAppForSelfV0(BaseModel):
16
+ password: str
17
+
18
+
19
+ class ResetPasswordAndLoginUsingBackupCodeV0(BaseModel):
20
+ backup_code: str
21
+ username: str
22
+ new_password: str
23
+ logout_other_sessions: bool = False
24
+
25
+
26
+ class ResetPasswordAndLoginUsingResetEmailCodeV0(BaseModel):
27
+ reset_email_code: str
28
+ username: str
29
+ new_password: str
30
+ logout_other_sessions: bool = False
31
+
32
+
33
+ class UpdatePasswordV0(BaseModel):
34
+ old_password: str
35
+ new_password: str
36
+ logout_other_sessions: bool = False
@@ -0,0 +1,12 @@
1
+ from typing import Optional, List
2
+
3
+ from pydantic import BaseModel, Field
4
+ from square_database_structure.square.greeting.tables import Greeting
5
+
6
+
7
+ class GetAllGreetingsV0(BaseModel):
8
+ order_by: List[str] = Field(
9
+ default_factory=lambda: [f"-{Greeting.greeting_datetime.name}"]
10
+ )
11
+ limit: Optional[int] = None
12
+ offset: int = 0