From 053e2c49e3a9a5015360b5eadb5d1f07a49a7a17 Mon Sep 17 00:00:00 2001 From: khushal Date: Wed, 25 Dec 2024 14:51:24 +0530 Subject: [PATCH] (20241225) Small fix in reconnection attempts for MySQL. --- api_v2/blueprints/cred_and_data/blueprint.py | 384 ++++++++++++++++++ controllers/__init__.py | 0 controllers/servers/__init__.py | 0 controllers/servers/server.py | 0 models/__init__.py | 0 models/cred_and_data/__init__.py | 0 models/cred_and_data/api.py | 216 ++++++++++ models/logs/__init__.py | 0 models/logs/api.py | 135 ++++++ models/servers/__init__.py | 0 models/servers/api.py | 216 ++++++++++ models/servers/core.py | 216 ++++++++++ .../api/__pycache__/__init__.cpython-310.pyc | Bin 166 -> 162 bytes .../__pycache__/async_quart.cpython-310.pyc | Bin 32014 -> 32358 bytes .../api/__pycache__/codes.cpython-310.pyc | Bin 3712 -> 3708 bytes utils_v2/api/__pycache__/log.cpython-310.pyc | Bin 1782 -> 1778 bytes .../api/__pycache__/response.cpython-310.pyc | Bin 1877 -> 1865 bytes utils_v2/api/async_quart.py | 2 +- .../__pycache__/__init__.cpython-310.pyc | Bin 168 -> 164 bytes .../async_redis_cache.cpython-310.pyc | Bin 13364 -> 13364 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 171 -> 167 bytes .../async_mongo_v2.cpython-310.pyc | Bin 40273 -> 40265 bytes utils_v2/database/async_mysql_v2.py | 13 +- .../__pycache__/__init__.cpython-310.pyc | Bin 170 -> 166 bytes .../logging/__pycache__/model.cpython-310.pyc | Bin 1713 -> 1709 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 171 -> 167 bytes .../__pycache__/sanitizers.cpython-310.pyc | Bin 1933 -> 1929 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 186 -> 165 bytes .../string/__pycache__/json.cpython-310.pyc | Bin 3563 -> 3542 bytes .../string/__pycache__/regex.cpython-310.pyc | Bin 7739 -> 7718 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 186 -> 165 bytes .../system/__pycache__/files.cpython-310.pyc | Bin 11571 -> 11550 bytes 32 files changed, 1169 insertions(+), 13 deletions(-) create mode 100644 api_v2/blueprints/cred_and_data/blueprint.py create mode 100644 controllers/__init__.py create mode 100644 controllers/servers/__init__.py create mode 100644 controllers/servers/server.py create mode 100644 models/__init__.py create mode 100644 models/cred_and_data/__init__.py create mode 100644 models/cred_and_data/api.py create mode 100644 models/logs/__init__.py create mode 100644 models/logs/api.py create mode 100644 models/servers/__init__.py create mode 100644 models/servers/api.py create mode 100644 models/servers/core.py diff --git a/api_v2/blueprints/cred_and_data/blueprint.py b/api_v2/blueprints/cred_and_data/blueprint.py new file mode 100644 index 0000000..b1caa11 --- /dev/null +++ b/api_v2/blueprints/cred_and_data/blueprint.py @@ -0,0 +1,384 @@ +""" + + AUTHOR: + + Khushal P Soonderji + + DATE: + + Created: Wednesday, 18th Sept., 2024 + Updated: Tuesday, 8th Oct., 2024 + + OBJECTIVE: + + To be able to fetch setup credentials and data for any project. This could include things like default values, + URLs to assets, etc. While 'data' and 'cred' can be used interchangeably, the idea behind giving two services is + for the user of this service to be able to organise his setup variables. + + REFERENCES: + + N/A + + DOWNLOADS: + + N/A + + NOTES: + + N/A + +""" + + +# ***************************************************************************************************************** +# ***** **** +# *** IMPORT *** +# ***** **** +# ***************************************************************************************************************** + + +# To make sibling directories accessible for imports: +import sys +sys.path.append(".") +sys.path.append("..") + +# For using Quart: +from quart import Blueprint, current_app, make_response + +# My utils: +from utils_v2.string import json +from utils_v2.api.codes import StatusCodes, HttpCodes +from utils_v2.api.response import ResponseModel +from utils_v2.api.async_quart import ( + set_api_version, + read_input, + log_request_to_mongo, + should_not_be_under_maintenance, + only_whitelisted_ips, + limit_rate, + validate_input, + handle_cancelled_request, + make_ordered_json +) + +# For asynchronous activities: +import asyncio + + +# ***************************************************************************************************************** +# ***** **** +# *** MACROS / ONE-TIME INIT *** +# ***** **** +# ***************************************************************************************************************** + + +# Related to Quart: +cred_and_data_bp = Blueprint("int_cnd", __name__) + +# related to the operations of this blueprint: +JSON_TYPE_INFO = { + "cred": { + "collection": "_scriptCred" + }, + "data": { + "collection": "_scriptData" + } +} + +# ***************************************************************************************************************** +# ***** **** +# *** VARIABLES *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** FUNCTIONS *** +# ***** **** +# ***************************************************************************************************************** + + +@cred_and_data_bp.record_once +def init(blueprint_setup_state): + + # This gets called when the blueprint is registered. + # Consider this to be a one-time setup for the whole blueprint: + pass + + +# --------------------------------------------------------------------------------------------------------------------- + + +@cred_and_data_bp.route("//set", methods = ["POST", "GET"]) +@set_api_version(api_version = "2.1.0") +@read_input(sanitize_headers = True, sanitize_data = True) +@log_request_to_mongo( + attr_name = "mongo", + project = "internal", + log_type = "credData", + operation = "set", + log_input = False, + log_output = True +) +@should_not_be_under_maintenance(attr_name = "is_under_maintenance") +@only_whitelisted_ips(attr_name = "whitelisted_ips") +@validate_input(mandatory_header_keys = ["X-Script-Id", "X-Script-Desc"]) +@handle_cancelled_request() +async def set_data( + json_type: str = None, + inbound_headers: dict = None, + inbound_data: dict = None, + inbound_files: dict = None, + **kwargs +): + + """ + To set the credentials for a particular script. If the document exists, it will be overwritten. If the document + doesn't exist, it will be created. Ideally use this for only the first time setup. + :param json_type: The choice from one of the fields of 'JSON_TYPE_INFO'. + :param inbound_headers: auto-extracted by the decorators. + :param inbound_data: auto-extracted by the decorators. + :param inbound_files: auto-extracted by the decorators. + :param kwargs: Any number of extra inputs supplied by the decorators. + :return: A standard response structure. + """ + + # If an invalid choice was made: + if json_type not in JSON_TYPE_INFO.keys(): + return ResponseModel( + status_code = StatusCodes.FAILED, + message = f"invalid path '{json_type}'", + http_code = HttpCodes.BAD_REQUEST + ) + + # Construct the document: + description = inbound_headers.get("X-Script-Desc", "") + if len(description) > 200: description = description[:200] + document = { + "scriptId": inbound_headers["X-Script-Id"], + "desc": description, + "content": inbound_data + } + + # Make an attempt to set the credentials: + success = await current_app.mongo.replace_one( + collection = JSON_TYPE_INFO[json_type]["collection"], + filter = {"scriptId": inbound_headers["X-Script-Id"]}, + replacement = document, + upsert = True, + raise_exception = True + ) + + # Return the response: + if success: return ResponseModel(status_code = StatusCodes.OK) + else: return ResponseModel(status_code = StatusCodes.FAILED) + + +# --------------------------------------------------------------------------------------------------------------------- + + +@cred_and_data_bp.route("//get", methods = ["POST", "GET"]) +@set_api_version(api_version = "2.1.0") +@read_input(sanitize_headers = True, sanitize_data = True) +@log_request_to_mongo( + attr_name = "mongo", + project = "internal", + log_type = "credData", + operation = "get", + log_input = True, + log_output = False +) +@should_not_be_under_maintenance(attr_name = "is_under_maintenance") +@only_whitelisted_ips(attr_name = "whitelisted_ips") +@validate_input(mandatory_header_keys = ["X-Script-Id"]) +@handle_cancelled_request() +async def get_data( + json_type: str = None, + inbound_headers: dict = None, + inbound_data: dict = None, + inbound_files: dict = None, + **kwargs +): + + """ + To retrieve the credentials stored for a specific script. The script's id can be anything set by the programmers. + The idea is to have only the script's id stored in the script, and everything else is fetched from the database. + This means that we get to store and update everything from one central location. + :param json_type: The choice from one of the fields of 'JSON_TYPE_INFO'. + :param inbound_headers: auto-extracted by the decorators. + :param inbound_data: auto-extracted by the decorators. + :param inbound_files: auto-extracted by the decorators. + :param kwargs: Any number of extra inputs supplied by the decorators. + :return: A standard response structure. + """ + + # If an invalid choice was made: + if json_type not in JSON_TYPE_INFO.keys(): + return ResponseModel( + status_code = StatusCodes.FAILED, + message = f"invalid path '{json_type}'", + http_code = HttpCodes.BAD_REQUEST + ) + + # Make an attempt to retrieve the credentials: + data_json = await current_app.mongo.find_one( + collection = JSON_TYPE_INFO[json_type]["collection"], + filter = {"scriptId": inbound_headers["X-Script-Id"]}, + projection = {"_id": False, "scriptId": False}, + raise_exception = True + ) + + # In case no result was found: + if data_json is None: + return ResponseModel( + status_code = StatusCodes.FAILED, + message = "invalid script id" + ) + + # Successfully retrieved: + json_data, http_code = ResponseModel( + status_code = StatusCodes.OK, + data = data_json["content"], + message = data_json["desc"] + ).for_quart() + return await make_ordered_json(json_data, http_code) + + +# --------------------------------------------------------------------------------------------------------------------- + + +@cred_and_data_bp.route("//update", methods = ["POST", "GET"]) +@set_api_version(api_version = "2.1.0") +@read_input(sanitize_headers = True, sanitize_data = True) +@log_request_to_mongo( + attr_name = "mongo", + project = "internal", + log_type = "credData", + operation = "update", + log_input = False, + log_output = True +) +@should_not_be_under_maintenance(attr_name = "is_under_maintenance") +@only_whitelisted_ips(attr_name = "whitelisted_ips") +@validate_input(mandatory_header_keys = ["X-Script-Id"]) +@handle_cancelled_request() +async def update_cred( + json_type: str = None, + inbound_headers: dict = None, + inbound_data: dict = None, + inbound_files: dict = None, + **kwargs +): + + """ + To update values of certain fields for a credentials document. It only updates existing values, does NOT add a new + document if the document doesn't already exist. + :param json_type: The choice from one of the fields of 'JSON_TYPE_INFO'. + :param inbound_headers: auto-extracted by the decorators. + :param inbound_data: auto-extracted by the decorators. + :param inbound_files: auto-extracted by the decorators. + :param kwargs: Any number of extra inputs supplied by the decorators. + :return: A standard response structure. + """ + + # If an invalid choice was made: + if json_type not in JSON_TYPE_INFO.keys(): + return ResponseModel( + status_code = StatusCodes.FAILED, + message = f"invalid path '{json_type}'", + http_code = HttpCodes.BAD_REQUEST + ) + + # Pre-process the inbound data: + inbound_data = inbound_data or {} + + # Prepare the update JSON. Pre-process the fields to set and unset. + # Our actual data/cred are held inside a field called "content", so we must wrap the request in that: + update_json = {} + if inbound_data.get("unset"): + update_json["$unset"] = current_app.mongo.dict_to_dot_notation({"content": inbound_data["unset"]}) + if inbound_data.get("set"): + update_json["$set"] = current_app.mongo.dict_to_dot_notation({"content": inbound_data["set"]}) + + # Make an attempt to set the credentials: + success = await current_app.mongo.update_one( + collection = JSON_TYPE_INFO[json_type]["collection"], + filter = {"scriptId": inbound_headers["X-Script-Id"]}, + update = update_json, + upsert = False, + raise_exception = True + ) + + # Return the response: + if success: return ResponseModel(status_code = StatusCodes.OK) + else: return ResponseModel(status_code = StatusCodes.FAILED) + + +# --------------------------------------------------------------------------------------------------------------------- + + +@cred_and_data_bp.route("//delete", methods = ["POST", "GET"]) +@set_api_version(api_version = "2.1.0") +@read_input(sanitize_headers = True, sanitize_data = True) +@log_request_to_mongo( + attr_name = "mongo", + project = "internal", + log_type = "credData", + operation = "delete", + log_input = True, + log_output = True +) +@should_not_be_under_maintenance(attr_name = "is_under_maintenance") +@only_whitelisted_ips(attr_name = "whitelisted_ips") +@validate_input(mandatory_header_keys = ["X-Script-Id"]) +async def delete_data( + json_type: str = None, + inbound_headers: dict = None, + inbound_data: dict = None, + inbound_files: dict = None, + **kwargs +): + + """ + To delete a document for a particular script id. + :param json_type: The choice from one of the fields of 'JSON_TYPE_INFO'. + :param inbound_headers: auto-extracted by the decorators. + :param inbound_data: auto-extracted by the decorators. + :param inbound_files: auto-extracted by the decorators. + :param kwargs: Any number of extra inputs supplied by the decorators. + :return: A standard response structure. + """ + + # If an invalid choice was made: + if json_type not in JSON_TYPE_INFO.keys(): + return ResponseModel( + status_code = StatusCodes.FAILED, + message = f"invalid path '{json_type}'", + http_code = HttpCodes.BAD_REQUEST + ) + + # Make an attempt to set the credentials: + success = await current_app.mongo.delete_one( + collection = JSON_TYPE_INFO[json_type]["collection"], + filter = {"scriptId": inbound_headers["X-Script-Id"]}, + ) + + # Return the response: + if success: return ResponseModel(status_code = StatusCodes.OK) + else: return ResponseModel(status_code = StatusCodes.FAILED) + + +# ***************************************************************************************************************** +# ***** **** +# *** MAIN PROGRAM *** +# ***** **** +# ***************************************************************************************************************** + + +if __name__ == "__main__": + + pass diff --git a/controllers/__init__.py b/controllers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/controllers/servers/__init__.py b/controllers/servers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/controllers/servers/server.py b/controllers/servers/server.py new file mode 100644 index 0000000..e69de29 diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/cred_and_data/__init__.py b/models/cred_and_data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/cred_and_data/api.py b/models/cred_and_data/api.py new file mode 100644 index 0000000..6b74795 --- /dev/null +++ b/models/cred_and_data/api.py @@ -0,0 +1,216 @@ +""" + + AUTHOR: + + Khushal P Soonderji + + DATE: + + Wednesday, 25th Dec., 2024. + + OBJECTIVE: + + To provide a structure to work with requests surrounding Cred and Data handling. + + REFERENCES: + + N/A + + DOWNLOADS: + + N/A + +""" + + +# ***************************************************************************************************************** +# ***** **** +# *** IMPORT *** +# ***** **** +# ***************************************************************************************************************** + + +# To make sibling directories accessible for imports: +import sys +sys.path.append(".") +sys.path.append("..") + +# For making data behaviour_models: +from pydantic import BaseModel, Field, field_validator, PastDatetime, model_validator +from typing import Optional, Literal, Union + +# My utils: +from utils_v2.string import regex +from utils_v2.date_time import date_time + +# To work with date and time: +import datetime + + +# ***************************************************************************************************************** +# ***** **** +# *** MACROS / ONE-TIME INIT *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** VARIABLES *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** FUNCTIONS *** +# ***** **** +# ***************************************************************************************************************** + + +class CredAndDataSetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are setting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + scriptDescription: str = Field( + description = "a short description of the script and what it does", + frozen = True, + alias = "X-Script-Desc" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataGetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are getting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are updating cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestData(BaseModel): + + unsetJson: dict = Field( + description = "the items to unset; this is performed first", + frozen = True, + alias = "unset" + ) + + setJson: dict = Field( + description = "the items to set; this is performed after the 'unset' operation", + frozen = True, + alias = "set" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "forbid" + + # ┓┏ ┓• ┓ • + # ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓ + # ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗ + + @field_validator("unsetJson", "setJson", mode = "before") + def ensure_non_null(cls, value): + if value is None: value = {} + return value + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataDeleteRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are deleting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# ***************************************************************************************************************** +# ***** **** +# *** MAIN PROGRAM *** +# ***** **** +# ***************************************************************************************************************** + + +if __name__ == "__main__": + + pass diff --git a/models/logs/__init__.py b/models/logs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/logs/api.py b/models/logs/api.py new file mode 100644 index 0000000..8b39ab4 --- /dev/null +++ b/models/logs/api.py @@ -0,0 +1,135 @@ +""" + + AUTHOR: + + Khushal P Soonderji + + DATE: + + Wednesday, 25th Dec., 2024. + + OBJECTIVE: + + To provide a structure to work with requests surrounding Log handling. + + REFERENCES: + + N/A + + DOWNLOADS: + + N/A + +""" + + +# ***************************************************************************************************************** +# ***** **** +# *** IMPORT *** +# ***** **** +# ***************************************************************************************************************** + + +# To make sibling directories accessible for imports: +import sys +sys.path.append(".") +sys.path.append("..") + +# For making data behaviour_models: +from pydantic import BaseModel, Field, field_validator, PastDatetime, model_validator +from typing import Optional, Literal, Union + +# My utils: +from utils_v2.string import regex +from utils_v2.date_time import date_time + +# To work with date and time: +import datetime + + +# ***************************************************************************************************************** +# ***** **** +# *** MACROS / ONE-TIME INIT *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** VARIABLES *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** FUNCTIONS *** +# ***** **** +# ***************************************************************************************************************** + + +class LogsByFilterRequestData(BaseModel): + + filter: dict = Field( + description = "the filter condition(s) while picking logs", + frozen = True + ) + + limit: int = Field( + description = "the max. logs to pick", + default = 25, + frozen = True + ) + + skip: int = Field( + description = "how many initial matches to skip before picking logs; needed for pagination", + default = 0, + frozen = True + ) + + sort: dict = Field( + description = "the sorting conditions for the picked logs", + default = {"_id": -1}, + frozen = True + ) + + projection: dict = Field( + description = "to decide what fields are retrieved", + default = {"_id": False}, + frozen = True + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "forbid" + + # ┓┏ ┓• ┓ • + # ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓ + # ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗ + + @field_validator("unsetJson", "setJson", mode = "before") + def ensure_non_null(cls, value): + if value is None: value = {} + return value + + +# ***************************************************************************************************************** +# ***** **** +# *** MAIN PROGRAM *** +# ***** **** +# ***************************************************************************************************************** + + +if __name__ == "__main__": + + pass diff --git a/models/servers/__init__.py b/models/servers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/servers/api.py b/models/servers/api.py new file mode 100644 index 0000000..6b74795 --- /dev/null +++ b/models/servers/api.py @@ -0,0 +1,216 @@ +""" + + AUTHOR: + + Khushal P Soonderji + + DATE: + + Wednesday, 25th Dec., 2024. + + OBJECTIVE: + + To provide a structure to work with requests surrounding Cred and Data handling. + + REFERENCES: + + N/A + + DOWNLOADS: + + N/A + +""" + + +# ***************************************************************************************************************** +# ***** **** +# *** IMPORT *** +# ***** **** +# ***************************************************************************************************************** + + +# To make sibling directories accessible for imports: +import sys +sys.path.append(".") +sys.path.append("..") + +# For making data behaviour_models: +from pydantic import BaseModel, Field, field_validator, PastDatetime, model_validator +from typing import Optional, Literal, Union + +# My utils: +from utils_v2.string import regex +from utils_v2.date_time import date_time + +# To work with date and time: +import datetime + + +# ***************************************************************************************************************** +# ***** **** +# *** MACROS / ONE-TIME INIT *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** VARIABLES *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** FUNCTIONS *** +# ***** **** +# ***************************************************************************************************************** + + +class CredAndDataSetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are setting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + scriptDescription: str = Field( + description = "a short description of the script and what it does", + frozen = True, + alias = "X-Script-Desc" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataGetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are getting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are updating cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestData(BaseModel): + + unsetJson: dict = Field( + description = "the items to unset; this is performed first", + frozen = True, + alias = "unset" + ) + + setJson: dict = Field( + description = "the items to set; this is performed after the 'unset' operation", + frozen = True, + alias = "set" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "forbid" + + # ┓┏ ┓• ┓ • + # ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓ + # ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗ + + @field_validator("unsetJson", "setJson", mode = "before") + def ensure_non_null(cls, value): + if value is None: value = {} + return value + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataDeleteRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are deleting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# ***************************************************************************************************************** +# ***** **** +# *** MAIN PROGRAM *** +# ***** **** +# ***************************************************************************************************************** + + +if __name__ == "__main__": + + pass diff --git a/models/servers/core.py b/models/servers/core.py new file mode 100644 index 0000000..6b74795 --- /dev/null +++ b/models/servers/core.py @@ -0,0 +1,216 @@ +""" + + AUTHOR: + + Khushal P Soonderji + + DATE: + + Wednesday, 25th Dec., 2024. + + OBJECTIVE: + + To provide a structure to work with requests surrounding Cred and Data handling. + + REFERENCES: + + N/A + + DOWNLOADS: + + N/A + +""" + + +# ***************************************************************************************************************** +# ***** **** +# *** IMPORT *** +# ***** **** +# ***************************************************************************************************************** + + +# To make sibling directories accessible for imports: +import sys +sys.path.append(".") +sys.path.append("..") + +# For making data behaviour_models: +from pydantic import BaseModel, Field, field_validator, PastDatetime, model_validator +from typing import Optional, Literal, Union + +# My utils: +from utils_v2.string import regex +from utils_v2.date_time import date_time + +# To work with date and time: +import datetime + + +# ***************************************************************************************************************** +# ***** **** +# *** MACROS / ONE-TIME INIT *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** VARIABLES *** +# ***** **** +# ***************************************************************************************************************** + + +# --- Nothing Yet + + +# ***************************************************************************************************************** +# ***** **** +# *** FUNCTIONS *** +# ***** **** +# ***************************************************************************************************************** + + +class CredAndDataSetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are setting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + scriptDescription: str = Field( + description = "a short description of the script and what it does", + frozen = True, + alias = "X-Script-Desc" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataGetRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are getting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are updating cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataUpdateRequestData(BaseModel): + + unsetJson: dict = Field( + description = "the items to unset; this is performed first", + frozen = True, + alias = "unset" + ) + + setJson: dict = Field( + description = "the items to set; this is performed after the 'unset' operation", + frozen = True, + alias = "set" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "forbid" + + # ┓┏ ┓• ┓ • + # ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓ + # ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗ + + @field_validator("unsetJson", "setJson", mode = "before") + def ensure_non_null(cls, value): + if value is None: value = {} + return value + + +# --------------------------------------------------------------------------------------------------------------------- + + +class CredAndDataDeleteRequestHeaders(BaseModel): + + scriptId: str = Field( + description = "the id of the script for whom you are deleting cred/data", + frozen = True, + alias = "X-Script-Id" + ) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + def model_dump(self, *args, **kwargs): + return super().model_dump(*args, by_alias = True, **kwargs) + + +# ***************************************************************************************************************** +# ***** **** +# *** MAIN PROGRAM *** +# ***** **** +# ***************************************************************************************************************** + + +if __name__ == "__main__": + + pass diff --git a/utils_v2/api/__pycache__/__init__.cpython-310.pyc b/utils_v2/api/__pycache__/__init__.cpython-310.pyc index f44186d9d0089262b43182fa8bd7b156153c914e..e004caccd5375a180e1c21867da9fae3a72381f2 100644 GIT binary patch delta 36 qcmZ3+xQLNEpO=@50SHtUXHVp|VRW77p~8`wSCU$kmzXoLLJt6$wF%My delta 40 ucmZ3)xQvlIpO=@50SH1&ttWEZFnUh(P~k~TPmfQ@PcF?(%`2H$q6YxEBMSHc diff --git a/utils_v2/api/__pycache__/async_quart.cpython-310.pyc b/utils_v2/api/__pycache__/async_quart.cpython-310.pyc index 81ae0d2a259fbb61295a03495b94edda6c71d471..a349bff0891906229961d681a4b0a95793ad7e20 100644 GIT binary patch delta 5398 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 NH=46a6Yn&C@;?PfKo0-_ delta 4940 zcmaJ_32>Xm75?}Cf1Q@)+m0Puw&PPyeB?0k73XkHk~kr84m*cXyuXbcOBUQiVJN4g-#2UPD>ATic&zD|J(QP zzW4UMw{PFB^ucH3#HYkLkeqCn;L}mx+Px$5HLU^h#kQm?U(~UK)@m)Z4xYL2%!6k>JPWiY z&{-sOI%z$<4s0A)*UjZ@uXq9nSDHi3d>cv|3D1WzkGi?0~EByMm| zDqTvKf#PMfjV=dc+vp0q658c-6^!n{B0Fs%5X3SgBSgk=D6@kNPG1T$JpK)-;aRRFgTUD8RP9Fi!Z z@^LvtM&&gURaQ%3nW`bVPobt3DI{-}+-C1N5-qlv3BSiWK|1(CTf0LsY<+_R0S_4E z<@eYYCf|XItpM_oJbTozb<5;|Xse@3CO?dxcHS(Lx1&jE@5w~rmoh#ke~(_s+(<}X zv_5;gOzQcG89ySGd}D47>4^5`dKI!h`cnQSLR$ILuGtFPBJuZKl}>cP0*``owe#G< zf{_q7q073Wt3B$d%(4R^U4lN7Zq_Y53iK=*m)HVb8kcl<8+4CLRBn)NmySut2qddQ z)iG;GS}u)}uoT!$O**`dlKUlUKBGX-7NN}sdin^nHcEYT~43$!wPYWmVPBWP)Gwzh%|TkCYCk z`96dtA69B=YTW6p0$6!#ncHM2{aS$cmo-WaY=b)U^!xliolSdZsNDnogE7xW z_&a6!$zGgq9`HLd916FW*OHTbX?A9`y}U}!!QJCFu?^6OiI@{9&hM-&b8#RIwPz^M z9S@XY+0VSepvKPgH!62z-izF)0VWAUc4+S9OWhgdDZa(sl!{&K41$RC{rn+!ZptLu zgB#XiQ}ft^+}4sGecydqO}ZNyVNha+`8zd@$zMhC9ssu)v=-NPm~f_xe7JUZ?R`K^ zn%LKo-Bqd1K1L%q-Q-9*vIH z&9SZw$!ttFjT7Ar88DZo0B-!vHP zhvlxsj+5Ng=d%lM71n+DrT_{#YEbAn8ehcB72w{ZB5gtQ`ZvhPMLVmt! zj*?HD{QagKjUvdFSaN*1mc($^^Zm`uH9|s6DJBwA3WJ0#!i;#}pXGmS&P&ObucXF| zLUj>)4pO6lJQS^HiJCV@z`9|(-#0ku3-mS>Rj@wjn3UO*(6FZvsu7k04BMvJCY7rg zW+B7XNmkuK$rl*Uy@(D7oj@xM3aRoRkXeD)zNn)f5w?-sCc51-bY}g#qkOas69x4SC zy&xoy;yiOgR>10zjgu4HydjU&@Zt?Qu9LbWr08%yfxyX-5=nu>LkTHRgX`K2i63EE zeD8)JDdWH2&|4jWcnl|PuUBABtvjxA^8D6xiPB>Yc|w$ z6c0om)&52bjZm%Yhf-`GN);Mq4kOosV0Hyk0a@#al8k@NiQrdh3` z_`QotL?Jtd6z*Ym5&>3DVwVs;0x+yYtlz_i`ZYsEWVds5^Sr7kj^pWX*nNRPjp?3& zfM(eJ161qx&>?>ij)&OB=bf9MT7@$jHm?q+Lcr_S*lQ>*3c*`Q{Tks7gf|h;k61NG ztO3P*Q^$>@oJTw66FdK~PjUL2XSoVyVQNmPIz^=UI?d6TrA-(Fj6YGNq4b&51qlj5zR370aoqJ}ANRSv)qK9XBq;pZKkdAL$C%@d8 zpL+k4<#6ETvNU12ot;AK6z_=4gXIPMagR0H-L+2!PmG(5G1K{BpYq8qRC-MjrRbb~o@G|`Dy!BUpOFYaEHlsYZz zmOv3 zoCmHWX8v+uKC$xu1oEn9p;;n9i;)sXUm;S$-o({z<0}U4Xcb9oWzEPW60`*=q382d zB&Nhto*Z1bQ;5Z95t9m8p+#sGO5>@&2zJ zSt-ZRF?b}WT`gm4c_f%`XG=g2>~Oc(;ZgU#N?BP-B>sKol7A-g-?1M1!94`dFCqdU`^kRT`R&(K2N5v0_1cTP z*k%|8c2#Wfbp`sk5+NQ9aglk6f9K#V#Yr;xTL)L?ihZ``|KssI1*KEfD|EJkWA0>+=s;1P39s$p$`I|JM+TA>gAw&0t?^Bs;P Xt70XoF1y2;&hHDCkk$P8@T30&xQ(|S diff --git a/utils_v2/api/__pycache__/codes.cpython-310.pyc b/utils_v2/api/__pycache__/codes.cpython-310.pyc index 47eef7c9e003e8a39553f6860780ee9120afd165..7afe28d69219ac657d906cab5e953a6e2cf1003a 100644 GIT binary patch delta 40 ucmZpW{UgJj&&$ij00b(Fvo~_D;9zu`yoE!BBQvigwJ0w!XY&(|IjjKPp$ts` delta 44 ycmew((;&;8&&$ij00beX)*HE3a4@<}-ol~6lbD_!pOT+knwy$eviSkW9994YSPgRk diff --git a/utils_v2/api/__pycache__/log.cpython-310.pyc b/utils_v2/api/__pycache__/log.cpython-310.pyc index 955fe4b1cba97f759bf53e3c084d6e60c6827d62..268eff108422c4e6c1a43f7a436896ed6b15d5ad 100644 GIT binary patch delta 40 ucmeyy`-zu3pO=@50SHtUXK&;-XJvGl?98gdk(pPLT9lWVv$>eHnGpciD+?b0 delta 44 ycmeyw`;C`7pO=@50SH1&tv7O;vog9&c4k%KNlZ_VPsvX%%}vcK*__YX%m@JbVGKn8 diff --git a/utils_v2/api/__pycache__/response.cpython-310.pyc b/utils_v2/api/__pycache__/response.cpython-310.pyc index 30d35cd3585fea52b8a90457e0972d9dffd9c9dc..7856559f5d32c2dccc14757b894d5837c4e5a8db 100644 GIT binary patch delta 305 zcmcc0cao1cpO=@50SHtUXQw~d$ZNn{-vQ*+Fk~^LFqSeFae`P`jCrg;nkkDhg-Md3 zmJ!NkmSiXrPhrVpOku78i7^+bf@N41u%@u4uq|X-z_t)%5<3ucq_EFntz`nTIKk$c zfmk(6DI7K+6WIjn614DTq(bPf5MS3l~et zOfFf;P$Uo3_RDp$5~~VFW?o5ZQC?!sk&o( DK~7Jv delta 316 zcmX@fca@JfpO=@50SH1&t<#@x8+kjMXg2hZhET9+% zSd0rSW(O4G%3{nDWCb!nmUBun)H2mD)-X*z$~=2=8jF#FUl9+`ZMRr+^3y$2UNQmM zn%qU4V4b82r;!zzqXOLnw2qRawn?_Phxs{d`fMv>$>y!BOxBFQ oCi_@^nJj1IxA~W2J>z77cH7OyOEbWpO=@50SH1&tv7PZurhj0)?iiPNlZ_VPsvX%%}vcK*&M@8svs=jG*M00Nc8*&DeHnHha1+cK+gWagEm7Ud=8Y|dp?U;zNNlnLbk delta 44 ycmeC=@8##t=jG*M0D=%x>y6xo%!~n(ZJAYg64TS;Q}UBbb5rw5HfJ&`umAwof(r`( diff --git a/utils_v2/string/__pycache__/__init__.cpython-310.pyc b/utils_v2/string/__pycache__/__init__.cpython-310.pyc index 56c7f94117f9f456854c9f198613355268e63578..ce213c863af984eb1ce12aaf53daa3bf46bfacd9 100644 GIT binary patch delta 36 qcmdnRxRjAQpO=@50SHtUXHVp|Vf2{jp~8`wSCU$kmzXoL(+~iiKnef= delta 57 zcmZ3=xQmfHpO=@50SMOJ_MgaY!x%f!Lq#?tvnVkyGrlA>CpkYiz96wOH#M&$J~1yP LzBspdVu>LD?TZs# diff --git a/utils_v2/string/__pycache__/json.cpython-310.pyc b/utils_v2/string/__pycache__/json.cpython-310.pyc index 4d899fcd6c0555a254a73ee5fa512b0f6171e121..ddf7d691549370c4dc395c9679340bc4ae835db6 100644 GIT binary patch delta 40 ucmaDYeNCD>pO=@50SHtUXK&;dWM*`kEX%CIk(pPLT9lWVvpJ5rmkR*SZVJQz delta 61 zcmca6{aTtkpO=@50SMOJ_TR`Y$jlfyS(aHvHY2krF)uT|BsC{FKR3Q0u`)L`uOvP( PFD1S>w|KKBb1xSFI~Noo diff --git a/utils_v2/string/__pycache__/regex.cpython-310.pyc b/utils_v2/string/__pycache__/regex.cpython-310.pyc index 1de2bcedf895e8bd15e83f3ec5825460870bf960..540d5a8a78fd7a97de816777c66ea0169c5c3602 100644 GIT binary patch delta 40 ucmdmOv&@D&pO=@50SHtUXK&%yps6D Pyp;Ij+~UnoIGscQW_=Z! diff --git a/utils_v2/system/__pycache__/__init__.cpython-310.pyc b/utils_v2/system/__pycache__/__init__.cpython-310.pyc index aec6600212e369703f5dddc7f9abc2757833de82..30663544a4b3d6ea36f2d421c63d7accb2171e98 100644 GIT binary patch delta 36 qcmdnRxRjAQpO=@50SHtUXHVp|Vf2{jp~8`wSCU$kmzXoL(+~iiKnef= delta 57 zcmZ3=xQmfHpO=@50SMOJ_MgaY!x%f!Lq#?tvnVkyGrlA>CpkYiz96wOH#M&$J~1yP LzBspdVu>LD?TZs# diff --git a/utils_v2/system/__pycache__/files.cpython-310.pyc b/utils_v2/system/__pycache__/files.cpython-310.pyc index 76fd4c4ec55691fb842555259cdbcf5c39628e13..cef38a3fcf60f8d4054db5f7951660aa2933fa9e 100644 GIT binary patch delta 40 ucmdlSH7|-gpO=@50SHtUXK&;_!NTY|`3j2)M`m70YEfQd&Sp_oISl~nO$)04 delta 60 zcmbOiwK%yps6D Oyp;Ij+~Q5FavA_(pcMxI