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 f44186d..e004cac 100644 Binary files a/utils_v2/api/__pycache__/__init__.cpython-310.pyc and b/utils_v2/api/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/api/__pycache__/async_quart.cpython-310.pyc b/utils_v2/api/__pycache__/async_quart.cpython-310.pyc index 81ae0d2..a349bff 100644 Binary files a/utils_v2/api/__pycache__/async_quart.cpython-310.pyc and b/utils_v2/api/__pycache__/async_quart.cpython-310.pyc differ diff --git a/utils_v2/api/__pycache__/codes.cpython-310.pyc b/utils_v2/api/__pycache__/codes.cpython-310.pyc index 47eef7c..7afe28d 100644 Binary files a/utils_v2/api/__pycache__/codes.cpython-310.pyc and b/utils_v2/api/__pycache__/codes.cpython-310.pyc differ diff --git a/utils_v2/api/__pycache__/log.cpython-310.pyc b/utils_v2/api/__pycache__/log.cpython-310.pyc index 955fe4b..268eff1 100644 Binary files a/utils_v2/api/__pycache__/log.cpython-310.pyc and b/utils_v2/api/__pycache__/log.cpython-310.pyc differ diff --git a/utils_v2/api/__pycache__/response.cpython-310.pyc b/utils_v2/api/__pycache__/response.cpython-310.pyc index 30d35cd..7856559 100644 Binary files a/utils_v2/api/__pycache__/response.cpython-310.pyc and b/utils_v2/api/__pycache__/response.cpython-310.pyc differ diff --git a/utils_v2/api/async_quart.py b/utils_v2/api/async_quart.py index d7abe9f..2bcabe3 100644 --- a/utils_v2/api/async_quart.py +++ b/utils_v2/api/async_quart.py @@ -96,7 +96,7 @@ import copy ALPHANUMERIC_CHARS = string.ascii_letters + string.digits # To capture system information: -PROCESS_ID = os.getppid() +PROCESS_ID = os.getpid() PARENT_PROCESS_ID = os.getppid() diff --git a/utils_v2/cache/__pycache__/__init__.cpython-310.pyc b/utils_v2/cache/__pycache__/__init__.cpython-310.pyc index b168cc8..2d8ffcd 100644 Binary files a/utils_v2/cache/__pycache__/__init__.cpython-310.pyc and b/utils_v2/cache/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/cache/__pycache__/async_redis_cache.cpython-310.pyc b/utils_v2/cache/__pycache__/async_redis_cache.cpython-310.pyc index 6a0d7d1..53e8261 100644 Binary files a/utils_v2/cache/__pycache__/async_redis_cache.cpython-310.pyc and b/utils_v2/cache/__pycache__/async_redis_cache.cpython-310.pyc differ diff --git a/utils_v2/database/__pycache__/__init__.cpython-310.pyc b/utils_v2/database/__pycache__/__init__.cpython-310.pyc index e6bb512..691f777 100644 Binary files a/utils_v2/database/__pycache__/__init__.cpython-310.pyc and b/utils_v2/database/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/database/__pycache__/async_mongo_v2.cpython-310.pyc b/utils_v2/database/__pycache__/async_mongo_v2.cpython-310.pyc index 7128ae7..d09a291 100644 Binary files a/utils_v2/database/__pycache__/async_mongo_v2.cpython-310.pyc and b/utils_v2/database/__pycache__/async_mongo_v2.cpython-310.pyc differ diff --git a/utils_v2/database/async_mysql_v2.py b/utils_v2/database/async_mysql_v2.py index 6a1996f..09a604c 100644 --- a/utils_v2/database/async_mysql_v2.py +++ b/utils_v2/database/async_mysql_v2.py @@ -129,7 +129,7 @@ class AsyncMySQL: try: - self.__kwargs["db"] = self.__kwargs.pop("database") + self.__kwargs["db"] = self.__kwargs.pop("database", self.__kwargs["db"]) self.__pool = await aiomysql.create_pool( minsize = self.__min_pool_size, maxsize = self.__max_pool_size, @@ -220,17 +220,6 @@ class AsyncMySQL: all_result_sets = await self.fetch_all(cursor) if commit: await connection.commit() - # # Iterate over all result sets, - # # and process them one-by-one: - # while True: - # this_result_set = [] - # result = await cursor.fetchall() - # if not cursor.description: break - # columns = [desc[0] for desc in cursor.description] - # for row in result: this_result_set.append(dict(zip(columns, self.__parse_row(row)))) - # all_result_sets.append(this_result_set) - # await cursor.nextset() - # Done here: return all_result_sets diff --git a/utils_v2/logging/__pycache__/__init__.cpython-310.pyc b/utils_v2/logging/__pycache__/__init__.cpython-310.pyc index f14ac0a..8e4fd4d 100644 Binary files a/utils_v2/logging/__pycache__/__init__.cpython-310.pyc and b/utils_v2/logging/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/logging/__pycache__/model.cpython-310.pyc b/utils_v2/logging/__pycache__/model.cpython-310.pyc index 1ebab57..0adb2ad 100644 Binary files a/utils_v2/logging/__pycache__/model.cpython-310.pyc and b/utils_v2/logging/__pycache__/model.cpython-310.pyc differ diff --git a/utils_v2/security/__pycache__/__init__.cpython-310.pyc b/utils_v2/security/__pycache__/__init__.cpython-310.pyc index 7cd905e..fe851c9 100644 Binary files a/utils_v2/security/__pycache__/__init__.cpython-310.pyc and b/utils_v2/security/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/security/__pycache__/sanitizers.cpython-310.pyc b/utils_v2/security/__pycache__/sanitizers.cpython-310.pyc index 0f1dd54..5492a0d 100644 Binary files a/utils_v2/security/__pycache__/sanitizers.cpython-310.pyc and b/utils_v2/security/__pycache__/sanitizers.cpython-310.pyc differ diff --git a/utils_v2/string/__pycache__/__init__.cpython-310.pyc b/utils_v2/string/__pycache__/__init__.cpython-310.pyc index 56c7f94..ce213c8 100644 Binary files a/utils_v2/string/__pycache__/__init__.cpython-310.pyc and b/utils_v2/string/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/string/__pycache__/json.cpython-310.pyc b/utils_v2/string/__pycache__/json.cpython-310.pyc index 4d899fc..ddf7d69 100644 Binary files a/utils_v2/string/__pycache__/json.cpython-310.pyc and b/utils_v2/string/__pycache__/json.cpython-310.pyc differ diff --git a/utils_v2/string/__pycache__/regex.cpython-310.pyc b/utils_v2/string/__pycache__/regex.cpython-310.pyc index 1de2bce..540d5a8 100644 Binary files a/utils_v2/string/__pycache__/regex.cpython-310.pyc and b/utils_v2/string/__pycache__/regex.cpython-310.pyc differ diff --git a/utils_v2/system/__pycache__/__init__.cpython-310.pyc b/utils_v2/system/__pycache__/__init__.cpython-310.pyc index aec6600..3066354 100644 Binary files a/utils_v2/system/__pycache__/__init__.cpython-310.pyc and b/utils_v2/system/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils_v2/system/__pycache__/files.cpython-310.pyc b/utils_v2/system/__pycache__/files.cpython-310.pyc index 76fd4c4..cef38a3 100644 Binary files a/utils_v2/system/__pycache__/files.cpython-310.pyc and b/utils_v2/system/__pycache__/files.cpython-310.pyc differ