(20241209) Small failure view bug fix to show the 'logId' now.
This commit is contained in:
@@ -113,7 +113,7 @@ def init(blueprint_setup_state):
|
|||||||
api_version = "1.0.0",
|
api_version = "1.0.0",
|
||||||
project = constants.PROJECT_NAME,
|
project = constants.PROJECT_NAME,
|
||||||
log_type = constants.MODULE_NAME,
|
log_type = constants.MODULE_NAME,
|
||||||
operation = "gmailCallbk",
|
operation = "gmailCllbk",
|
||||||
log_input = 2,
|
log_input = 2,
|
||||||
log_output = 1,
|
log_output = 1,
|
||||||
sensitive_keys = ["sessionToken", "X-Session-Token"]
|
sensitive_keys = ["sessionToken", "X-Session-Token"]
|
||||||
@@ -300,7 +300,7 @@ async def mail_auth_callback(
|
|||||||
mail_client = mail_client.title(),
|
mail_client = mail_client.title(),
|
||||||
failure_hint = (
|
failure_hint = (
|
||||||
f"Invalid client '{mail_client}' selected. "
|
f"Invalid client '{mail_client}' selected. "
|
||||||
"Please use log-id '{g.log_id}' to check with the support team."
|
f"Please use log-id '{g.log_id}' to check with the support team."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
"""
|
|
||||||
|
|
||||||
AUTHOR:
|
|
||||||
|
|
||||||
Khushal P Soonderji
|
|
||||||
|
|
||||||
DATE:
|
|
||||||
|
|
||||||
Thursday, 5th Dec., 2024
|
|
||||||
|
|
||||||
OBJECTIVE:
|
|
||||||
|
|
||||||
To create an interface between OpenAI and our internal system to perform LLM-based activities.
|
|
||||||
|
|
||||||
REFERENCES:
|
|
||||||
|
|
||||||
N/A
|
|
||||||
|
|
||||||
DOWNLOADS:
|
|
||||||
|
|
||||||
N/A
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** IMPORT ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# To make sibling directories accessible for imports:
|
|
||||||
import sys
|
|
||||||
sys.path.append(".")
|
|
||||||
sys.path.append("..")
|
|
||||||
|
|
||||||
# My async utils:
|
|
||||||
from utils_v2.string import json
|
|
||||||
from utils_v2.date_time import date_time
|
|
||||||
from utils_v2.database.async_mysql_v2 import AsyncMySQL
|
|
||||||
from utils_v2.database.async_mongo_v2 import AsyncMongo
|
|
||||||
|
|
||||||
# Base model:
|
|
||||||
from models.behaviour.base import BaseModel
|
|
||||||
|
|
||||||
# Data Models:
|
|
||||||
from models.data.api.ai.llm import LLMInput, LLMOutput, LLMUsageTokens
|
|
||||||
|
|
||||||
# To work with LLMs:
|
|
||||||
from langchain_openai import ChatOpenAI
|
|
||||||
|
|
||||||
# To work with MongoDB:
|
|
||||||
from bson import ObjectId
|
|
||||||
|
|
||||||
# To work with datatypes:
|
|
||||||
from typing import Literal
|
|
||||||
|
|
||||||
# To make deep-copies:
|
|
||||||
import copy
|
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** MACROS / ONE-TIME INIT ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# --- Nothing Yet
|
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** VARIABLES ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# --- Nothing Yet
|
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** FUNCTIONS ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# --- Nothing Yet
|
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** CLASSES ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
class LLMOpenAI(BaseModel):
|
|
||||||
|
|
||||||
AI_USAGE_COLLECTION = "_aiUsage"
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
llm_creds: dict,
|
|
||||||
cache = None,
|
|
||||||
alert_url = None,
|
|
||||||
http_client = None,
|
|
||||||
debug = True,
|
|
||||||
debug_prefix = "Model | ",
|
|
||||||
debug_only_errors = True
|
|
||||||
):
|
|
||||||
|
|
||||||
"""
|
|
||||||
This is the model that works with OpenAi's LLM to perform tasks like text completion.
|
|
||||||
:param llm_creds: The JSON that holds the credentials to access your OpenAI account. Should have the keys
|
|
||||||
'model', and 'openai_api_key'.
|
|
||||||
:param cache: The object to use for caching results from database calls.
|
|
||||||
:param alert_url: Which URL to call when something goes wrong.
|
|
||||||
:param http_client: The instance of an HTTP client to use when trying to send alerts and make other APIs.
|
|
||||||
:param debug: Whether, or not, you would like to print debugging messages:
|
|
||||||
:param debug_prefix: The prefix to print with the debugging messages.
|
|
||||||
:param debug_only_errors: Whether you would like to print only error messages or all messages.
|
|
||||||
:return: None.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Initialize the parent:
|
|
||||||
super().__init__(
|
|
||||||
cache = cache,
|
|
||||||
alert_url = alert_url,
|
|
||||||
http_client = http_client,
|
|
||||||
debug = debug,
|
|
||||||
debug_prefix = debug_prefix,
|
|
||||||
debug_only_errors = debug_only_errors
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the interface to the LLM:
|
|
||||||
self.__llm = ChatOpenAI(**llm_creds)
|
|
||||||
|
|
||||||
async def invoke(
|
|
||||||
self,
|
|
||||||
mongo_conn: AsyncMongo,
|
|
||||||
user_info: dict,
|
|
||||||
llm_input: LLMInput
|
|
||||||
) -> LLMOutput:
|
|
||||||
|
|
||||||
# Format the message as per the format of OpenAI:
|
|
||||||
prompt = [
|
|
||||||
{
|
|
||||||
"role": {"system": "system", "ai": "assistant", "human": "user"}[message.role],
|
|
||||||
"content": message.content
|
|
||||||
} for message in llm_input.messages
|
|
||||||
]
|
|
||||||
|
|
||||||
# Invoke the AI, and format the response:
|
|
||||||
llm_response = await self.__llm.ainvoke(prompt)
|
|
||||||
llm_response = LLMOutput(
|
|
||||||
messages = llm_input.messages,
|
|
||||||
output = llm_response.content,
|
|
||||||
client = "openai",
|
|
||||||
model = llm_response.response_metadata["model_name"],
|
|
||||||
tokens = LLMUsageTokens(
|
|
||||||
input = llm_response.usage_metadata["input_tokens"],
|
|
||||||
output = llm_response.usage_metadata["output_tokens"],
|
|
||||||
total = llm_response.usage_metadata["total_tokens"],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Store this into MongoDB:
|
|
||||||
mongo_document = {"user": user_info}
|
|
||||||
for k, v in llm_response.model_dump().items(): mongo_document[k] = v
|
|
||||||
inserted_id = await mongo_conn.insert_one(
|
|
||||||
collection = self.AI_USAGE_COLLECTION,
|
|
||||||
document = mongo_document
|
|
||||||
)
|
|
||||||
|
|
||||||
# Done here:
|
|
||||||
return llm_response
|
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
# ***** ****
|
|
||||||
# *** MAIN PROGRAM ***
|
|
||||||
# ***** ****
|
|
||||||
# *****************************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
# import asyncio
|
|
||||||
#
|
|
||||||
# llm_messages = [
|
|
||||||
# {
|
|
||||||
# "role": "system",
|
|
||||||
# "content": "You are an office assistant."
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# "role": "ai",
|
|
||||||
# "content": "Hello, sir. How may I help you today?"
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# "role": "human",
|
|
||||||
# "content": "Please summarize this mail for me..."
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# my_llm = LLMOpenAI(
|
|
||||||
# llm_creds = {
|
|
||||||
# "model": "gpt-4o-mini",
|
|
||||||
# "openai_api_key": "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"
|
|
||||||
# }
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# async def main():
|
|
||||||
#
|
|
||||||
# llm_response = await my_llm.invoke(llm_input = LLMInput(messages = llm_messages))
|
|
||||||
# print("LLM RESPONSE:", llm_response.model_dump_json(indent = 4))
|
|
||||||
#
|
|
||||||
# asyncio.run(main())
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
DATE:
|
DATE:
|
||||||
|
|
||||||
ORIGINAL: Monday, 2nd Dec., 2024
|
ORIGINAL: Monday, 2nd Dec., 2024
|
||||||
UPGRADE: Monday, 9th Dec., 2024
|
UPGRADED: Monday, 9th Dec., 2024
|
||||||
|
|
||||||
OBJECTIVE:
|
OBJECTIVE:
|
||||||
|
|
||||||
@@ -134,9 +134,9 @@ class MailOAuthModel(BaseModel):
|
|||||||
}),
|
}),
|
||||||
update = {
|
update = {
|
||||||
"$set": {
|
"$set": {
|
||||||
"lastRequestTs": request_ts,
|
"lastRequestTs": auth_token.lastRequestTs,
|
||||||
"status": auth_token.status,
|
"status": auth_token.status,
|
||||||
"syncFreq": max(auth_token.syncFreq, 60)
|
"syncFreq": auth_token.syncFreq
|
||||||
},
|
},
|
||||||
"$setOnInsert": {
|
"$setOnInsert": {
|
||||||
"version": auth_token.version,
|
"version": auth_token.version,
|
||||||
@@ -149,7 +149,7 @@ class MailOAuthModel(BaseModel):
|
|||||||
"token": auth_token.token,
|
"token": auth_token.token,
|
||||||
"firstRefreshTs": auth_token.firstRefreshTs,
|
"firstRefreshTs": auth_token.firstRefreshTs,
|
||||||
"lastRefreshTs": auth_token.lastRefreshTs,
|
"lastRefreshTs": auth_token.lastRefreshTs,
|
||||||
"firstRequestTs": auth_token.firstRequestTs,
|
"firstRequestTs": auth_token.firstRequestTs or request_ts,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
projection = {
|
projection = {
|
||||||
@@ -168,7 +168,7 @@ class MailOAuthModel(BaseModel):
|
|||||||
proc_args = (
|
proc_args = (
|
||||||
auth_token.user.entityId, # ......................................... 'p_entity_id'
|
auth_token.user.entityId, # ......................................... 'p_entity_id'
|
||||||
auth_token.client, # ................................................ 'p_provider'
|
auth_token.client, # ................................................ 'p_provider'
|
||||||
"Pending", # ........................................................ 'p_current_status'
|
auth_token.status, # ................................................ 'p_current_status'
|
||||||
"Auth Requested", # ................................................. 'p_last_action'
|
"Auth Requested", # ................................................. 'p_last_action'
|
||||||
None, # ............................................................. 'p_display_name'
|
None, # ............................................................. 'p_display_name'
|
||||||
None, # ............................................................. 'p_display_picture'
|
None, # ............................................................. 'p_display_picture'
|
||||||
@@ -254,7 +254,7 @@ class MailOAuthModel(BaseModel):
|
|||||||
proc_args = (
|
proc_args = (
|
||||||
mongo_json["user"]["entityId"], # ............................... 'p_entity_id'
|
mongo_json["user"]["entityId"], # ............................... 'p_entity_id'
|
||||||
mongo_json["client"], # ......................................... 'p_provider'
|
mongo_json["client"], # ......................................... 'p_provider'
|
||||||
"Active", # ..................................................... 'p_current_status'
|
auth_token.status, # ............................................ 'p_current_status'
|
||||||
"Auth Granted", # ............................................... 'p_last_action'
|
"Auth Granted", # ............................................... 'p_last_action'
|
||||||
auth_token.token.get("displayName"), # .......................... 'p_display_name'
|
auth_token.token.get("displayName"), # .......................... 'p_display_name'
|
||||||
auth_token.token.get("displayPictureUrl"), # .................... 'p_display_picture'
|
auth_token.token.get("displayPictureUrl"), # .................... 'p_display_picture'
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
AUTHOR:
|
||||||
|
|
||||||
|
Khushal P Soonderji
|
||||||
|
|
||||||
|
DATE:
|
||||||
|
|
||||||
|
ORIGINAL: Thursday, 5th Dec., 2024
|
||||||
|
UPGRADED: Monday, 9th Dec., 2024
|
||||||
|
|
||||||
|
OBJECTIVE:
|
||||||
|
|
||||||
|
To work with auth details of SMS clients like Nimbus SMS (India) and Savvy Bulk SMS (Kenya).
|
||||||
|
|
||||||
|
REFERENCES:
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
DOWNLOADS:
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** IMPORT ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# To make sibling directories accessible for imports:
|
||||||
|
import sys
|
||||||
|
sys.path.append(".")
|
||||||
|
sys.path.append("..")
|
||||||
|
|
||||||
|
# My async utils:
|
||||||
|
from utils_v2.string import json
|
||||||
|
from utils_v2.date_time import date_time
|
||||||
|
from utils_v2.database.async_mysql_v2 import AsyncMySQL
|
||||||
|
from utils_v2.database.async_mongo_v2 import AsyncMongo
|
||||||
|
|
||||||
|
# Base model:
|
||||||
|
from models.behaviour.base import BaseModel
|
||||||
|
|
||||||
|
# Data models:
|
||||||
|
from models.data.core.auth_token import CoreAuthTokenModel
|
||||||
|
|
||||||
|
# To work with MongoDB:
|
||||||
|
from bson import ObjectId
|
||||||
|
|
||||||
|
# To work with datatypes:
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
# To make deep-copies:
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** MACROS / ONE-TIME INIT ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** VARIABLES ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** FUNCTIONS ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# --- Nothing Yet
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** CLASSES ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
class SMSAuthModel(BaseModel):
|
||||||
|
|
||||||
|
AUTH_COLLECTION = "_authTokens"
|
||||||
|
|
||||||
|
async def set(
|
||||||
|
self,
|
||||||
|
db_conn: AsyncMySQL,
|
||||||
|
mongo_conn: AsyncMongo,
|
||||||
|
auth_token: CoreAuthTokenModel,
|
||||||
|
session_token: str = None
|
||||||
|
) -> ObjectId | None:
|
||||||
|
|
||||||
|
"""
|
||||||
|
To store auth/tokens for a particular service to the database.
|
||||||
|
:param db_conn: The database connection (MariaDB) to use to perform the action.
|
||||||
|
:param mongo_conn: The database connection (MongoDB) to use to perform the action.
|
||||||
|
:param auth_token: An instance of the core auth-token model that holds data in the database.
|
||||||
|
:param session_token: The session token of the user who requested this service.
|
||||||
|
:return: An ObjectId to later store the granted tokens.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Note down the timestamp at which this event occurred:
|
||||||
|
request_ts = date_time.get_current_utc_date_time(as_string = False)
|
||||||
|
|
||||||
|
# Get the identifier from the database:
|
||||||
|
# BE CAREFUL WITH THE KEYS HERE, THEY SHOULD MATCH THE FIELDS OF THE CORE AUTH-TOKEN MODEL:
|
||||||
|
mongo_json = await mongo_conn.find_one_and_update(
|
||||||
|
collection = self.AUTH_COLLECTION,
|
||||||
|
filter = mongo_conn.dict_to_dot_notation({
|
||||||
|
"serviceType": "email",
|
||||||
|
"user": {
|
||||||
|
"entityId": auth_token.user.entityId,
|
||||||
|
"billingAccountId": auth_token.user.billingAccountId
|
||||||
|
},
|
||||||
|
"clientUserId": auth_token.clientUserId
|
||||||
|
}),
|
||||||
|
update = {
|
||||||
|
"$set": {
|
||||||
|
"lastRequestTs": auth_token.lastRequestTs,
|
||||||
|
"status": auth_token.status,
|
||||||
|
"syncFreq": auth_token.syncFreq
|
||||||
|
},
|
||||||
|
"$setOnInsert": {
|
||||||
|
"version": auth_token.version,
|
||||||
|
"serviceType": auth_token.serviceType,
|
||||||
|
"client": auth_token.client,
|
||||||
|
"authType": auth_token.authType,
|
||||||
|
"user": auth_token.user.model_dump(),
|
||||||
|
"clientUserId": auth_token.clientUserId,
|
||||||
|
"auth": auth_token.auth,
|
||||||
|
"token": auth_token.token,
|
||||||
|
"firstRefreshTs": auth_token.firstRefreshTs,
|
||||||
|
"lastRefreshTs": auth_token.lastRefreshTs,
|
||||||
|
"firstRequestTs": auth_token.firstRequestTs or request_ts
|
||||||
|
}
|
||||||
|
},
|
||||||
|
projection = {
|
||||||
|
"_id": True
|
||||||
|
},
|
||||||
|
upsert = True,
|
||||||
|
return_updated = True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Tell MariaDB that an authorization request was initiated:
|
||||||
|
db_json = {}
|
||||||
|
if mongo_json is not None:
|
||||||
|
token_notes = auth_token.clientUserId
|
||||||
|
db_json = await self.call_procedure(
|
||||||
|
db_conn = db_conn,
|
||||||
|
proc_name = "entity_integration_save",
|
||||||
|
proc_args = (
|
||||||
|
auth_token.user.entityId, # ..................................... 'p_entity_id'
|
||||||
|
auth_token.client, # ............................................ 'p_provider'
|
||||||
|
auth_token.status, # ............................................ 'p_current_status'
|
||||||
|
"Auth Details Accepted", # ...................................... 'p_last_action'
|
||||||
|
None, # ......................................................... 'p_display_name'
|
||||||
|
None, # ......................................................... 'p_display_picture'
|
||||||
|
str(mongo_json["_id"]), # ....................................... 'p_token_id'
|
||||||
|
json.to_string(python_data = token_notes, no_space = True), # ... 'p_notes'
|
||||||
|
auth_token.user.userId # ........................................ 'p_created_by'
|
||||||
|
),
|
||||||
|
session_token = session_token
|
||||||
|
)
|
||||||
|
|
||||||
|
# Done here:
|
||||||
|
return mongo_json["_id"] if mongo_json and db_json.get("status") == 1 else None
|
||||||
|
|
||||||
|
async def get(
|
||||||
|
self,
|
||||||
|
mongo_conn: AsyncMongo,
|
||||||
|
token_id: ObjectId | str = None,
|
||||||
|
**kwargs
|
||||||
|
) -> dict | None:
|
||||||
|
|
||||||
|
"""
|
||||||
|
To retrieve stored auth/tokens from the database.
|
||||||
|
:param mongo_conn: The database connection (MongoDB) to use to perform the action.
|
||||||
|
:param token_id: The identifier granted providing auth details for the first time in 'set_token'.
|
||||||
|
:param kwargs: Any set of key-value pairs to build custom search criteria. This could be things like the user
|
||||||
|
info, the client, the type of authentication used, or even the kind of service.
|
||||||
|
:return: The retrieved record that has the token, and information about the service and client if found, else
|
||||||
|
None when there is no matching record.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Build the filter:
|
||||||
|
filter_json = {k: v for k, v in kwargs.items()}
|
||||||
|
if token_id: filter_json["_id"] = ObjectId(token_id)
|
||||||
|
|
||||||
|
# If there is no search criteria, we exit with failure:
|
||||||
|
if not filter_json: return None
|
||||||
|
|
||||||
|
# If there is some filtering possible, we fetch the token:
|
||||||
|
token = await mongo_conn.find_one(
|
||||||
|
collection = self.AUTH_COLLECTION,
|
||||||
|
filter = filter_json,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Done here:
|
||||||
|
return CoreAuthTokenModel(**token) if token else None
|
||||||
|
|
||||||
|
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
# ***** ****
|
||||||
|
# *** MAIN PROGRAM ***
|
||||||
|
# ***** ****
|
||||||
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
pass
|
||||||
@@ -112,13 +112,13 @@ class CoreAuthTokenModel(BaseModel):
|
|||||||
firstRequestTs: AwareDatetime = Field(
|
firstRequestTs: AwareDatetime = Field(
|
||||||
description = "the time (utc) at which authorization was first requested",
|
description = "the time (utc) at which authorization was first requested",
|
||||||
frozen = True,
|
frozen = True,
|
||||||
default_factory = lambda: date_time.get_current_utc_date_time(as_string = False)
|
default = None
|
||||||
)
|
)
|
||||||
|
|
||||||
lastRequestTs: AwareDatetime = Field(
|
lastRequestTs: AwareDatetime = Field(
|
||||||
description = "the time (utc) at which authorization was last requested",
|
description = "the time (utc) at which authorization was last requested",
|
||||||
frozen = False,
|
frozen = False,
|
||||||
default = None
|
default_factory = lambda: date_time.get_current_utc_date_time(as_string = False)
|
||||||
)
|
)
|
||||||
|
|
||||||
firstRefreshTs: AwareDatetime = Field(
|
firstRefreshTs: AwareDatetime = Field(
|
||||||
|
|||||||
+2
-3
@@ -1,4 +1,3 @@
|
|||||||
kbdev.bicree.com
|
jc.ditscentre.in
|
||||||
wtt.ditscentre.in
|
wtt.ditscentre.in
|
||||||
del.ditscentre.in
|
del.ditscentre.in
|
||||||
jc.ditscentre.in
|
|
||||||
Reference in New Issue
Block a user