(20250212) Started a new util to handle MikroTik config. in async mode through REST API.
This commit is contained in:
@@ -312,6 +312,8 @@ def describe_exception(exc):
|
|||||||
:return: The dict that explains the exception.
|
:return: The dict that explains the exception.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if exc is None: return None
|
||||||
|
|
||||||
exc_desc = {
|
exc_desc = {
|
||||||
"type": type(exc).__name__,
|
"type": type(exc).__name__,
|
||||||
"msg": str(exc),
|
"msg": str(exc),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ sys.path.append("..")
|
|||||||
import io
|
import io
|
||||||
|
|
||||||
# The base model:
|
# The base model:
|
||||||
|
from utils_v2.rest.controllers.auth import RESTAuth
|
||||||
from utils_v2.rest.models.api_call import ApiResponse
|
from utils_v2.rest.models.api_call import ApiResponse
|
||||||
|
|
||||||
# My utils:
|
# My utils:
|
||||||
@@ -156,7 +157,8 @@ class AsyncREST:
|
|||||||
url: str,
|
url: str,
|
||||||
headers: dict = None,
|
headers: dict = None,
|
||||||
params: dict = None,
|
params: dict = None,
|
||||||
auth: httpx.Auth = None
|
auth: RESTAuth = None,
|
||||||
|
request_id: str | int = None
|
||||||
) -> ApiResponse:
|
) -> ApiResponse:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -165,6 +167,7 @@ class AsyncREST:
|
|||||||
:param headers: The headers to pass.
|
:param headers: The headers to pass.
|
||||||
:param params: The params to send in the query string itself.
|
:param params: The params to send in the query string itself.
|
||||||
:param auth: Any authentication credentials that need to be sent.
|
:param auth: Any authentication credentials that need to be sent.
|
||||||
|
:param request_id: An id to give this request. Can be useful for debugging later.
|
||||||
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -172,7 +175,10 @@ class AsyncREST:
|
|||||||
api_response = ApiResponse(
|
api_response = ApiResponse(
|
||||||
action = inspect.stack()[1].function,
|
action = inspect.stack()[1].function,
|
||||||
url = url,
|
url = url,
|
||||||
method = "GET"
|
method = "GET",
|
||||||
|
requestHeaders = headers,
|
||||||
|
requestParams = params,
|
||||||
|
requestId = request_id
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -182,7 +188,7 @@ class AsyncREST:
|
|||||||
url = url,
|
url = url,
|
||||||
headers = headers,
|
headers = headers,
|
||||||
params = params,
|
params = params,
|
||||||
auth = auth
|
auth = auth.encode()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note down the results:
|
# Note down the results:
|
||||||
@@ -209,7 +215,8 @@ class AsyncREST:
|
|||||||
json: dict = None,
|
json: dict = None,
|
||||||
data: dict = None,
|
data: dict = None,
|
||||||
content: str | bytes = None,
|
content: str | bytes = None,
|
||||||
auth: httpx.Auth = None
|
auth: RESTAuth = None,
|
||||||
|
request_id: str | int = None
|
||||||
) -> ApiResponse:
|
) -> ApiResponse:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -220,6 +227,7 @@ class AsyncREST:
|
|||||||
:param data: The params to send in the form-data in the body.
|
:param data: The params to send in the form-data in the body.
|
||||||
:param content: The raw content to be sent in the body (typically as an octet-stream).
|
:param content: The raw content to be sent in the body (typically as an octet-stream).
|
||||||
:param auth: Any authentication credentials that need to be sent.
|
:param auth: Any authentication credentials that need to be sent.
|
||||||
|
:param request_id: An id to give this request. Can be useful for debugging later.
|
||||||
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -227,7 +235,12 @@ class AsyncREST:
|
|||||||
api_response = ApiResponse(
|
api_response = ApiResponse(
|
||||||
action = inspect.stack()[1].function,
|
action = inspect.stack()[1].function,
|
||||||
url = url,
|
url = url,
|
||||||
method = "POST"
|
method = "POST",
|
||||||
|
requestHeaders = headers,
|
||||||
|
requestJson = json,
|
||||||
|
requestData = data,
|
||||||
|
requestContent = content,
|
||||||
|
requestId = request_id
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -239,7 +252,7 @@ class AsyncREST:
|
|||||||
json = json,
|
json = json,
|
||||||
data = data,
|
data = data,
|
||||||
content = content,
|
content = content,
|
||||||
auth = auth
|
auth = auth.encode()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note down the results:
|
# Note down the results:
|
||||||
@@ -265,7 +278,8 @@ class AsyncREST:
|
|||||||
headers: dict = None,
|
headers: dict = None,
|
||||||
json: dict = None,
|
json: dict = None,
|
||||||
data: dict = None,
|
data: dict = None,
|
||||||
auth: httpx.Auth = None
|
auth: RESTAuth = None,
|
||||||
|
request_id: str | int = None
|
||||||
) -> ApiResponse:
|
) -> ApiResponse:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -275,6 +289,7 @@ class AsyncREST:
|
|||||||
:param json: The params to send in the JSON body.
|
:param json: The params to send in the JSON body.
|
||||||
:param data: The params to send in the form-data in the body.
|
:param data: The params to send in the form-data in the body.
|
||||||
:param auth: Any authentication credentials that need to be sent.
|
:param auth: Any authentication credentials that need to be sent.
|
||||||
|
:param request_id: An id to give this request. Can be useful for debugging later.
|
||||||
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -282,7 +297,11 @@ class AsyncREST:
|
|||||||
api_response = ApiResponse(
|
api_response = ApiResponse(
|
||||||
action = inspect.stack()[1].function,
|
action = inspect.stack()[1].function,
|
||||||
url = url,
|
url = url,
|
||||||
method = "PUT"
|
method = "PUT",
|
||||||
|
requestHeaders = headers,
|
||||||
|
requestJson = json,
|
||||||
|
requestData = data,
|
||||||
|
requestId = request_id
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -293,7 +312,7 @@ class AsyncREST:
|
|||||||
headers = headers,
|
headers = headers,
|
||||||
json = json,
|
json = json,
|
||||||
data = data,
|
data = data,
|
||||||
auth = auth
|
auth = auth.encode()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note down the results:
|
# Note down the results:
|
||||||
@@ -320,7 +339,8 @@ class AsyncREST:
|
|||||||
json: dict = None,
|
json: dict = None,
|
||||||
data: dict = None,
|
data: dict = None,
|
||||||
content: str | bytes = None,
|
content: str | bytes = None,
|
||||||
auth: httpx.Auth = None
|
auth: RESTAuth = None,
|
||||||
|
request_id: str | int = None
|
||||||
) -> ApiResponse:
|
) -> ApiResponse:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -331,6 +351,7 @@ class AsyncREST:
|
|||||||
:param data: The params to send in the form-data in the body.
|
:param data: The params to send in the form-data in the body.
|
||||||
:param content: The raw content to be sent in the body (typically as an octet-stream).
|
:param content: The raw content to be sent in the body (typically as an octet-stream).
|
||||||
:param auth: Any authentication credentials that need to be sent.
|
:param auth: Any authentication credentials that need to be sent.
|
||||||
|
:param request_id: An id to give this request. Can be useful for debugging later.
|
||||||
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -338,7 +359,11 @@ class AsyncREST:
|
|||||||
api_response = ApiResponse(
|
api_response = ApiResponse(
|
||||||
action = inspect.stack()[1].function,
|
action = inspect.stack()[1].function,
|
||||||
url = url,
|
url = url,
|
||||||
method = "PATCH"
|
method = "PATCH",
|
||||||
|
requestHeaders = headers,
|
||||||
|
requestJson = json,
|
||||||
|
requestData = data,
|
||||||
|
requestId = request_id
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -350,7 +375,7 @@ class AsyncREST:
|
|||||||
json = json,
|
json = json,
|
||||||
data = data,
|
data = data,
|
||||||
content = content,
|
content = content,
|
||||||
auth = auth
|
auth = auth.encode()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note down the results:
|
# Note down the results:
|
||||||
@@ -374,7 +399,8 @@ class AsyncREST:
|
|||||||
self,
|
self,
|
||||||
url: str,
|
url: str,
|
||||||
headers: dict = None,
|
headers: dict = None,
|
||||||
auth: httpx.Auth = None
|
auth: RESTAuth = None,
|
||||||
|
request_id: str | int = None
|
||||||
) -> ApiResponse:
|
) -> ApiResponse:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -382,6 +408,7 @@ class AsyncREST:
|
|||||||
:param url: The URL to call.
|
:param url: The URL to call.
|
||||||
:param headers: The headers to pass.
|
:param headers: The headers to pass.
|
||||||
:param auth: Any authentication credentials that need to be sent.
|
:param auth: Any authentication credentials that need to be sent.
|
||||||
|
:param request_id: An id to give this request. Can be useful for debugging later.
|
||||||
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
:return: A structured response that includes the raw response, the exception (if any), and so on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -389,7 +416,9 @@ class AsyncREST:
|
|||||||
api_response = ApiResponse(
|
api_response = ApiResponse(
|
||||||
action = inspect.stack()[1].function,
|
action = inspect.stack()[1].function,
|
||||||
url = url,
|
url = url,
|
||||||
method = "DELETE"
|
method = "DELETE",
|
||||||
|
requestHeaders = headers,
|
||||||
|
requestId = request_id
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -398,7 +427,7 @@ class AsyncREST:
|
|||||||
response = await self._http_client.delete(
|
response = await self._http_client.delete(
|
||||||
url = url,
|
url = url,
|
||||||
headers = headers,
|
headers = headers,
|
||||||
auth = auth
|
auth = auth.encode()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note down the results:
|
# Note down the results:
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
AUTHOR:
|
||||||
|
|
||||||
|
Khushal P Soonderji
|
||||||
|
|
||||||
|
DATE:
|
||||||
|
|
||||||
|
Wednesday, 12th Feb., 2025.
|
||||||
|
|
||||||
|
OBJECTIVE:
|
||||||
|
|
||||||
|
To provide authentication abstraction for using with the Async REST class.
|
||||||
|
The idea is that if an input library changes, the rest of the code shouldn't change.
|
||||||
|
|
||||||
|
REFERENCES:
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
DOWNLOADS:
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** IMPORT ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# To make sibling directories accessible for imports:
|
||||||
|
import sys
|
||||||
|
sys.path.append(".")
|
||||||
|
sys.path.append("..")
|
||||||
|
|
||||||
|
# System-level activities:
|
||||||
|
import io
|
||||||
|
|
||||||
|
# The base model:
|
||||||
|
from utils_v2.rest.models.api_call import ApiResponse
|
||||||
|
|
||||||
|
# My utils:
|
||||||
|
from utils_v2.date_time import date_time
|
||||||
|
|
||||||
|
# To make API calls:
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
# To work with date and time:
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# For working with datatypes:
|
||||||
|
from typing import Literal, List
|
||||||
|
|
||||||
|
# For creating abstract classes:
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
# For debugging:
|
||||||
|
from icecream import IceCreamDebugger
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** MACROS / ONE-TIME INIT ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** VARIABLES ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** FUNCTIONS ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** CLASSES ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
class RESTAuth(ABC):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def encode(self) -> httpx.Auth:
|
||||||
|
|
||||||
|
"""
|
||||||
|
Use this method to give the desired output. For example, in Basic Auth, you convert the input username and
|
||||||
|
password to a Base64 string. If you are using, say, the HTTPX library, you would want to return its class from
|
||||||
|
this method.
|
||||||
|
:return: Whatever object is needed by the library you are using inside 'AsyncREST'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class BasicAuth(RESTAuth):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
username: str,
|
||||||
|
password: str
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
self._username = username
|
||||||
|
self._password = password
|
||||||
|
|
||||||
|
def encode(self) -> httpx.BasicAuth:
|
||||||
|
return httpx.BasicAuth(self._username, self._password)
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** MAIN PROGRAM ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
pass
|
||||||
@@ -79,11 +79,19 @@ class ApiResponse(BaseModel):
|
|||||||
default = None
|
default = None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
requestId: str | int | None = None
|
||||||
|
|
||||||
url: str = Field(frozen = True)
|
url: str = Field(frozen = True)
|
||||||
method: str = Field(frozen = True)
|
method: str = Field(frozen = True)
|
||||||
response: Any = None
|
response: Any = None
|
||||||
httpCode: int = None
|
httpCode: int = None
|
||||||
|
|
||||||
|
requestHeaders: dict | None = None
|
||||||
|
requestParams: dict | None = None
|
||||||
|
requestJson: dict | None = None
|
||||||
|
requestData: Any | None = None
|
||||||
|
requestContent: Any | None = None
|
||||||
|
|
||||||
success: bool = False
|
success: bool = False
|
||||||
message: str = None
|
message: str = None
|
||||||
data: Any = None
|
data: Any = None
|
||||||
|
|||||||
Reference in New Issue
Block a user