(20250825) -Added new google places API Integration system, no more oauth system for places api integration,

added multiple files for and correction and changes as well.
This commit is contained in:
yatmesh
2025-08-25 14:43:14 +05:30
parent ddc29a7fe1
commit 7f7a16d4d2
8 changed files with 221 additions and 102 deletions
+10 -76
View File
@@ -52,20 +52,12 @@ from utils_v2.rest.models.api_call import ApiResponse
from models.core.user import CoreUserInfoModel
from models.core.auth_token import CoreAuthTokenModel
from models.core.user import CoreUserInfoModel
from models.api.message.mail.oauth import (
OAuthMailAuthorizationRequestHeaders,
OAuthMailAuthorizationRequestData
)
from models.message.mail.oauth import OAuthMailGetAuthorizationURLResponse, OAuthMailHandleCallbackResponse
from models.core.message import CoreMessageModel
from models.api.software.places.oauth import PlacesAuthResponse
# To make HTTP requests:
import httpx
# to work with MongoDB:
from bson.objectid import ObjectId
# Mail Client(s):
from utils_v2.goog.controllers.places.places_client import AsyncPlacesClient
# To make abstract classes:
from abc import ABC, abstractmethod
@@ -173,80 +165,22 @@ class GooglePlacesController(CoreSoftwareController, ABC):
debug_only_errors = debug_only_errors
)
# ┏┓┏┓ ┓ ┏┓ ┏┓
# ┃┃┣┫┓┏╋┣┓┏┛ ┃┫
# ┗┛┛┗┗┻┗┛┗┗━•┗┛
@abstractmethod
async def get_authorization_url(
async def save_auth(
self,
sql_conn: AsyncMySQL,
mongo_data_conn: AsyncMongo,
mail_client: AsyncPlacesClient,
user_info: CoreUserInfoModel,
inbound_data: OAuthMailAuthorizationRequestData,
auth: CoreAuthTokenModel,
user: CoreUserInfoModel,
session_token: str
) -> OAuthMailGetAuthorizationURLResponse:
) -> PlacesAuthResponse:
"""
To accept an incoming request for mail integration and provide a URL that the user can use to authorize your
service to access his mail inbox.
Checks if a particular set of incoming credentials give access to a valid server and then stores the
credentials.
:param sql_conn: The database connection to use to perform this task.
:param mongo_data_conn: The database connection to use to perform this task.
:param mail_client: The instance of the third-party mail client that will be used to get the URL.
:param user_info: The information about your user who is trying to use this system.
:param inbound_data: The data that came in with the request (API call).
:param session_token: The session token of the user.
:return: A structure response with details about the URL generation process.
"""
pass
@abstractmethod
async def handle_authorization_callback(
self,
sql_conn: AsyncMySQL,
mongo_data_conn: AsyncMongo,
mail_client: AsyncPlacesClient,
request_url: str,
inbound_data: dict,
session_token: str = None
) -> OAuthMailHandleCallbackResponse:
"""
To handle the authorization callback for the mail client. The user may grant or deny authorization.
:param sql_conn: The database connection to use to perform this task.
:param mongo_data_conn: The database connection to use to perform this task.
:param mail_client: The instance of the third-party mail client that will be used to get the URL.
:param request_url: The full callback URL invoked by the third-party client.
:param inbound_data: The data that came in with the request (API call).
:param session_token: The session token of the user. It is expected that this will be null in all cases.
:return: A structured response of the process of handling the mail callback.
"""
pass
@abstractmethod
async def refresh_authorization(
self,
sql_conn: AsyncMySQL,
mongo_data_conn: AsyncMongo,
mail_client: AsyncPlacesClient,
http_client: httpx.AsyncClient,
auth_token: CoreAuthTokenModel,
force_refresh: bool = False,
session_token: str = None
) -> CoreAuthTokenModel:
"""
To refresh the third-party client's access/authorization token(s) before use.
:param sql_conn: The database connection to use when storing the refreshed tokens.
:param mongo_data_conn: The database connection to use when storing the refreshed tokens.
:param mail_client: The connection of the third-party mail client.
:param http_client: The HTTP client to use to make the token refresh request.
:param auth_token: The auth-token model of the existing integration. This may get updated if a refresh is needed
(or forced).
:param force_refresh: Whether, or not, you would like to force a refresh even if the token hasn't expired yet.
:param session_token: The session token of the user. This will be null if this method is invoked by a cron
script in the background. Needed only to identify the user in case of a failure to send a timely alert.
:return: The same auth-token model instance, but maybe with updated tokens.
:param auth: The set of credentials as received from the UI/API.
:return: A structured response to indicate what happened during authorization.
"""
pass
@@ -34,7 +34,7 @@
import sys
sys.path.append(".")
sys.path.append("..")
import aiohttp
# My async utils:
from utils_v2.string import json
from utils_v2.mail import mail_parser
@@ -53,7 +53,8 @@ from models.core.auth_token import CoreAuthTokenModel
from models.core.message import CoreMessageModel
from models.api.software.places.oauth import (
OAuthPlacesAuthorizationRequestHeaders,
OAuthPlacesAuthorizationRequestData
OAuthPlacesAuthorizationRequestData,
PlacesAuthResponse
)
from models.software.places.oauth import OAuthPlacesGetAuthorizationURLResponse, OAuthPlacesHandleCallbackResponse
@@ -168,6 +169,81 @@ class PlacesController(GooglePlacesController):
# Init a variable in a parent:
self._client = self.CLIENT_NAME
async def is_google_places_api_key_valid(api_key: str) -> bool:
url = "https://places.googleapis.com/v1/places:searchText"
headers = {
"Content-Type": "application/json",
"X-Goog-Api-Key": api_key,
"X-Goog-FieldMask": "places.displayName" # minimal required field
}
payload = {
"textQuery": "Google Sydney" # dummy search text
}
try:
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, json=payload, timeout=10) as response:
if response.status != 200:
return False
data = await response.json()
# If key invalid, response will contain "error"
if "error" in data:
return False
return True
except Exception:
return False
async def save_auth(
self,
sql_conn: AsyncMySQL,
mongo_data_conn: AsyncMongo,
auth: CoreAuthTokenModel ,
user: CoreUserInfoModel,
session_token: str
) -> PlacesAuthResponse:
# CHECK -- API KEY IS VALID -
valid_api = await PlacesController.is_google_places_api_key_valid(api_key=auth.apiKey)
if valid_api:
success, object_id = await self.set_token_direct_with_return_id(
sql_conn=sql_conn,
mongo_data_conn=mongo_data_conn,
auth_token=CoreAuthTokenModel(
serviceType=self.SERVICE_TYPE,
client=self.CLIENT_NAME,
authType="auth",
auth=auth.model_dump(),
user=user,
clientUserId={
"email": auth.email,
"apiKey": auth.apiKey
},
status="active",
syncFreq=60
),
token_notes={
"email": auth.email,
"apiKey": auth.apiKey
},
display_name=auth.displayName,
display_picture=None,
session_token=session_token
)
# Done here:
return PlacesAuthResponse(
success=success,
token_id=str(object_id),
message="Places Account Added successfully." if success else "Places Account Added failed."
)
else:
return PlacesAuthResponse(
success=False,
token_id="",
message="Invalid Google Places API KEY, please provide valid API KEY. Thank You"
)
# ┏┓┏┓ ┓ ┏┓ ┏┓
# ┃┃┣┫┓┏╋┣┓┏┛ ┃┫
# ┗┛┛┗┗┻┗┛┗┗━•┗┛