(20250120) Safety Push.
This commit is contained in:
@@ -545,7 +545,7 @@ def read_input(
|
|||||||
|
|
||||||
def get_session_info(
|
def get_session_info(
|
||||||
key: str,
|
key: str,
|
||||||
model: str = None,
|
controller: str = None,
|
||||||
session_func: str = None,
|
session_func: str = None,
|
||||||
session_coro: str = None,
|
session_coro: str = None,
|
||||||
get: str = None,
|
get: str = None,
|
||||||
@@ -560,12 +560,12 @@ def get_session_info(
|
|||||||
PLEASE USE "ResponseModel" AS THE RETURNED VALUE OF THE API ENDPOINT IF YOU ARE USING THIS DECORATOR.
|
PLEASE USE "ResponseModel" AS THE RETURNED VALUE OF THE API ENDPOINT IF YOU ARE USING THIS DECORATOR.
|
||||||
:param key: The key in either the 'inbound_data' or the 'inbound_headers' from which the session info will be
|
:param key: The key in either the 'inbound_data' or the 'inbound_headers' from which the session info will be
|
||||||
available. Examples: 'sessionToken' or 'X-Session-Token'.
|
available. Examples: 'sessionToken' or 'X-Session-Token'.
|
||||||
:param model: The object from which the func/coro should be called. This could be the name of the variable holding
|
:param controller: The object from which the func/coro should be called. This could be the name of the variable
|
||||||
an instance of a class. Should be available in the scope of 'current_app'.
|
holding an instance of a class. Should be available in the scope of 'current_app'.
|
||||||
:param session_func: The synchronous func of the model to call. This can either be an independent function or a
|
:param session_func: The synchronous func of the controller to call. This can either be an independent function or a
|
||||||
class's method. Should be available in the scope of 'current_app'.
|
class's method. Should be available in the scope of 'current_app'.
|
||||||
:param session_coro: The asynchronous func of the model to call. This can either be an independent function or a
|
:param session_coro: The asynchronous func of the controller to call. This can either be an independent function or
|
||||||
class's method. Ignored if 'func' was provided. Should be available in the scope of 'current_app'.
|
a class's method. Ignored if 'func' was provided. Should be available in the scope of 'current_app'.
|
||||||
:param get: The field inside the dict to get. Specify this in dot notation. The whole response will be returned as
|
:param get: The field inside the dict to get. Specify this in dot notation. The whole response will be returned as
|
||||||
is if this is null.
|
is if this is null.
|
||||||
:param mandatory: If set to True, the API call will enforce session checking; and if a session is not found, the
|
:param mandatory: If set to True, the API call will enforce session checking; and if a session is not found, the
|
||||||
@@ -593,12 +593,12 @@ def get_session_info(
|
|||||||
|
|
||||||
# For synchronous functions:
|
# For synchronous functions:
|
||||||
if session_func:
|
if session_func:
|
||||||
if model: session_info = getattr(getattr(current_app, model), session_func)(session_id)
|
if controller: session_info = getattr(getattr(current_app, controller), session_func)(session_id)
|
||||||
else: session_info = getattr(current_app, session_func)(session_id)
|
else: session_info = getattr(current_app, session_func)(session_id)
|
||||||
|
|
||||||
# For asynchronous coroutines:
|
# For asynchronous coroutines:
|
||||||
elif session_coro:
|
elif session_coro:
|
||||||
if model: session_info = await getattr(getattr(current_app, model), session_coro)(session_id)
|
if controller: session_info = await getattr(getattr(current_app, controller), session_coro)(session_id)
|
||||||
else: session_info = await getattr(current_app, session_coro)(session_id)
|
else: session_info = await getattr(current_app, session_coro)(session_id)
|
||||||
|
|
||||||
# If something goes wrong:
|
# If something goes wrong:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ from utils_v2.mail import mail_parser
|
|||||||
from utils_v2.goog.controllers.base import AsyncGoogleBase
|
from utils_v2.goog.controllers.base import AsyncGoogleBase
|
||||||
from utils_v2.goog.models.auth_tokens import GoogleAuthTokens
|
from utils_v2.goog.models.auth_tokens import GoogleAuthTokens
|
||||||
from utils_v2.goog.models.api_call import GoogleApiResponse
|
from utils_v2.goog.models.api_call import GoogleApiResponse
|
||||||
from utils_v2.goog.controllers.gmail.gmail_message import GMailMessage
|
from utils_v2.goog.controllers.gmail.gmail_message import GmailMessage
|
||||||
|
|
||||||
# Related to Google:
|
# Related to Google:
|
||||||
from google.auth.transport.requests import Request
|
from google.auth.transport.requests import Request
|
||||||
@@ -857,7 +857,7 @@ class AsyncGmailClient(AsyncGoogleBase):
|
|||||||
async def send_message(
|
async def send_message(
|
||||||
self,
|
self,
|
||||||
tokens: GoogleAuthTokens,
|
tokens: GoogleAuthTokens,
|
||||||
message: GMailMessage,
|
message: GmailMessage,
|
||||||
thread_id: str = None,
|
thread_id: str = None,
|
||||||
user_id: str = "me"
|
user_id: str = "me"
|
||||||
) -> GoogleApiResponse:
|
) -> GoogleApiResponse:
|
||||||
@@ -940,7 +940,7 @@ if __name__ == "__main__":
|
|||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
# Create an instance of the client:
|
# Create an instance of the client:
|
||||||
my_gmail = AsyncGMailClient(
|
my_gmail = AsyncGmailClient(
|
||||||
service_name = "gmail",
|
service_name = "gmail",
|
||||||
oauth_json = secrets_dict,
|
oauth_json = secrets_dict,
|
||||||
http_client = test_client,
|
http_client = test_client,
|
||||||
@@ -972,7 +972,6 @@ if __name__ == "__main__":
|
|||||||
print("DATA:", json.to_string(response.data, default = str))
|
print("DATA:", json.to_string(response.data, default = str))
|
||||||
if not response.success:
|
if not response.success:
|
||||||
print("\n\n---\n\n")
|
print("\n\n---\n\n")
|
||||||
print("FULL RESPONSE JSON:", json.to_string(await response.get_json()))
|
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ from typing import List
|
|||||||
# *****************************************************************************************************************
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
class GMailMessage:
|
class GmailMessage:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -160,7 +160,7 @@ class GMailMessage:
|
|||||||
# ┣┫┏┫┏┫ ┃ ┏┓┏┓╋┏┓┏┓╋
|
# ┣┫┏┫┏┫ ┃ ┏┓┏┓╋┏┓┏┓╋
|
||||||
# ┛┗┗┻┗┻ ┗┛┗┛┛┗┗┗ ┛┗┗
|
# ┛┗┗┻┗┻ ┗┛┗┛┛┗┗┗ ┛┗┗
|
||||||
|
|
||||||
def add_text(self, text):
|
def add_text(self, text) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add plain-text to the mail body.
|
Add plain-text to the mail body.
|
||||||
@@ -170,7 +170,7 @@ class GMailMessage:
|
|||||||
|
|
||||||
self.message.attach(MIMEText(text, "plain"))
|
self.message.attach(MIMEText(text, "plain"))
|
||||||
|
|
||||||
def add_html(self, html_text):
|
def add_html(self, html_text) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add HTML text to the mail body.
|
Add HTML text to the mail body.
|
||||||
@@ -185,7 +185,7 @@ class GMailMessage:
|
|||||||
image_file: str | io.BytesIO,
|
image_file: str | io.BytesIO,
|
||||||
file_name: str = None,
|
file_name: str = None,
|
||||||
content_id: str = None
|
content_id: str = None
|
||||||
):
|
) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add an inline image to the body of the mail.
|
Add an inline image to the body of the mail.
|
||||||
@@ -238,7 +238,7 @@ class GMailMessage:
|
|||||||
self,
|
self,
|
||||||
attachment_file: str | io.BytesIO,
|
attachment_file: str | io.BytesIO,
|
||||||
file_name: str = None
|
file_name: str = None
|
||||||
):
|
) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add a file as an attachment to the mail. This file, even if possible, will not be rendered on the screen in-line
|
Add a file as an attachment to the mail. This file, even if possible, will not be rendered on the screen in-line
|
||||||
@@ -246,7 +246,7 @@ class GMailMessage:
|
|||||||
:param attachment_file: The file that you would like to attach.
|
:param attachment_file: The file that you would like to attach.
|
||||||
:param file_name: The name of the file. This is the same name by which it will be downloaded. You need not
|
:param file_name: The name of the file. This is the same name by which it will be downloaded. You need not
|
||||||
specify this if the input file is specified as a path. Needed when you give the input file as a buffer.
|
specify this if the input file is specified as a path. Needed when you give the input file as a buffer.
|
||||||
:return:
|
:return: None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Declare the part to be attached to the multipart message:
|
# Declare the part to be attached to the multipart message:
|
||||||
@@ -277,18 +277,19 @@ class GMailMessage:
|
|||||||
|
|
||||||
def get_raw_message(
|
def get_raw_message(
|
||||||
self,
|
self,
|
||||||
as_base64: bool = True
|
as_base64: bool = False
|
||||||
):
|
) -> str:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Get the raw string dump from the current contents of the message. This text will be compliant with RFC 5322 and
|
Get the raw string dump from the current contents of the message. This text will be compliant with RFC 5322 and
|
||||||
RFC 2045 (among others).
|
RFC 2045 (among others).
|
||||||
|
:param
|
||||||
:param as_base64: If set to True, the response will be a URL-safe B64 output, else it'll be a raw string.
|
:param as_base64: If set to True, the response will be a URL-safe B64 output, else it'll be a raw string.
|
||||||
:return: The standardized raw text dump. either as a raw string or as a Base64 (url-safe) string.
|
:return: The standardized raw text dump. either as a raw string or as a Base64 (url-safe) string.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not as_base64: return self.message
|
if as_base64: return base64.urlsafe_b64encode(self.message.as_bytes()).decode()
|
||||||
else: return base64.urlsafe_b64encode(self.message.as_bytes()).decode()
|
else: return self.message.as_string()
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
# *****************************************************************************************************************
|
||||||
@@ -300,13 +301,16 @@ class GMailMessage:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
my_mail = GMailMessage(
|
# Create an instance of a mail message:
|
||||||
|
my_mail = GmailMessage(
|
||||||
from_email = "sender@gmail.com",
|
from_email = "sender@gmail.com",
|
||||||
to_email = "recipient@gmail.com",
|
to_email = "recipient@gmail.com",
|
||||||
subject = "Bhopli is the best!",
|
subject = "Bhopli is the best!",
|
||||||
cc_emails = None,
|
cc_emails = None,
|
||||||
bcc_emails = None
|
bcc_emails = None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add content to it:
|
||||||
my_mail.add_html(
|
my_mail.add_html(
|
||||||
"""
|
"""
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@@ -333,4 +337,13 @@ if __name__ == "__main__":
|
|||||||
my_mail.add_text("This is how you should pet her 👇")
|
my_mail.add_text("This is how you should pet her 👇")
|
||||||
my_mail.add_inline_image(r"../../../../data/images/cat_petting.png")
|
my_mail.add_inline_image(r"../../../../data/images/cat_petting.png")
|
||||||
my_mail.add_attachment(r"../../../../data/pdf/sample_label.pdf")
|
my_mail.add_attachment(r"../../../../data/pdf/sample_label.pdf")
|
||||||
print(my_mail.get_raw_message(as_base64 = False))
|
|
||||||
|
# Get the raw contents of the message:
|
||||||
|
mail_raw = my_mail.get_raw_message(as_base64 = False)
|
||||||
|
print("RAW TYPE:", type(mail_raw))
|
||||||
|
|
||||||
|
# Try parsing it:
|
||||||
|
from utils_v2.string import json
|
||||||
|
from utils_v2.mail import mail_parser
|
||||||
|
mail_json = mail_parser.parse(mail_raw)
|
||||||
|
print("PARSED MAIL (JSON):", json.to_string(mail_json, default = str))
|
||||||
|
|||||||
Reference in New Issue
Block a user