(20250704) - Created Oauth Authentication for google places api with all files
This commit is contained in:
@@ -0,0 +1,752 @@
|
||||
"""
|
||||
|
||||
AUTHOR:
|
||||
|
||||
Khushal P Soonderji
|
||||
|
||||
DATE:
|
||||
|
||||
Friday, 27th Jun., 2025
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
To get location and business info from Google's Places API.
|
||||
|
||||
REFERENCES:
|
||||
|
||||
1. GMail Quickstart: https://developers.google.com/gmail/api/quickstart/python
|
||||
2. GMail Labels: https://developers.google.com/gmail/api/guides/labels
|
||||
3. GMail Messages: https://developers.google.com/gmail/api/reference/rest/v1/users.messages
|
||||
4. People Profile: https://developers.google.com/people/api/rest/v1/people/get
|
||||
|
||||
DOWNLOADS:
|
||||
|
||||
N/A
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** IMPORT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# To make sibling directories accessible for imports:
|
||||
import sys
|
||||
sys.path.append(".")
|
||||
sys.path.append("..")
|
||||
|
||||
# System-level activities:
|
||||
import io
|
||||
|
||||
# My utils:
|
||||
from utils_v2.string import json
|
||||
|
||||
# My Google utils:
|
||||
from utils_v2.goog.controllers.base import AsyncGoogleBase
|
||||
from utils_v2.goog.models.auth_tokens import GoogleAuthTokens
|
||||
from utils_v2.goog.models.api_call import GoogleApiResponse
|
||||
|
||||
# Related to Google:
|
||||
from google.auth.transport.requests import Request
|
||||
from google.oauth2.credentials import Credentials
|
||||
from googleapiclient.discovery import build
|
||||
|
||||
# To make API calls:
|
||||
import httpx
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
|
||||
# For working with datatypes:
|
||||
from typing import Dict, Literal, List, Any
|
||||
|
||||
# For debugging:
|
||||
from icecream import IceCreamDebugger
|
||||
import inspect
|
||||
|
||||
# For computational help:
|
||||
import math
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MACROS / ONE-TIME INIT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# Google Scopes:
|
||||
SCOPES_PLACES_FULL = [
|
||||
r"https://www.googleapis.com/auth/cloud-platform",
|
||||
r"https://www.googleapis.com/auth/userinfo.profile",
|
||||
r"https://www.googleapis.com/auth/gmail.metadata"
|
||||
]
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** VARIABLES ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** FUNCTIONS ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** CLASSES ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
class AsyncPlacesClient(AsyncGoogleBase):
|
||||
|
||||
# The types of places:
|
||||
PLACE_TYPES = {
|
||||
"Automotive": [
|
||||
"car_dealer",
|
||||
"car_rental",
|
||||
"car_repair",
|
||||
"car_wash",
|
||||
"electric_vehicle_charging_station",
|
||||
"gas_station",
|
||||
"parking",
|
||||
"rest_stop"
|
||||
],
|
||||
"Business": [
|
||||
"corporate_office",
|
||||
"farm",
|
||||
"ranch"
|
||||
],
|
||||
"Culture": [
|
||||
"art_gallery",
|
||||
"art_studio",
|
||||
"auditorium",
|
||||
"cultural_landmark",
|
||||
"historical_place",
|
||||
"monument",
|
||||
"museum",
|
||||
"performing_arts_theater",
|
||||
"sculpture"
|
||||
],
|
||||
"Education": [
|
||||
"library",
|
||||
"preschool",
|
||||
"primary_school",
|
||||
"secondary_school",
|
||||
"university"
|
||||
],
|
||||
"Entertainment and Recreation": [
|
||||
"adventure_sports_center",
|
||||
"amphitheatre",
|
||||
"amusement_center",
|
||||
"amusement_park",
|
||||
"aquarium",
|
||||
"banquet_hall",
|
||||
"barbecue_area",
|
||||
"botanical_garden",
|
||||
"bowling_alley",
|
||||
"casino",
|
||||
"childrens_camp",
|
||||
"comedy_club",
|
||||
"community_center",
|
||||
"concert_hall",
|
||||
"convention_center",
|
||||
"cultural_center",
|
||||
"cycling_park",
|
||||
"dance_hall",
|
||||
"dog_park",
|
||||
"event_venue",
|
||||
"ferris_wheel",
|
||||
"garden",
|
||||
"hiking_area",
|
||||
"historical_landmark",
|
||||
"internet_cafe",
|
||||
"karaoke",
|
||||
"marina",
|
||||
"movie_rental",
|
||||
"movie_theater",
|
||||
"national_park",
|
||||
"night_club",
|
||||
"observation_deck",
|
||||
"off_roading_area",
|
||||
"opera_house",
|
||||
"park",
|
||||
"philharmonic_hall",
|
||||
"picnic_ground",
|
||||
"planetarium",
|
||||
"plaza",
|
||||
"roller_coaster",
|
||||
"skateboard_park",
|
||||
"state_park",
|
||||
"tourist_attraction",
|
||||
"video_arcade",
|
||||
"visitor_center",
|
||||
"water_park",
|
||||
"wedding_venue",
|
||||
"wildlife_park",
|
||||
"wildlife_refuge",
|
||||
"zoo"
|
||||
],
|
||||
"Facilities": [
|
||||
"public_bath",
|
||||
"public_bathroom",
|
||||
"stable"
|
||||
],
|
||||
"Finance": [
|
||||
"accounting",
|
||||
"atm",
|
||||
"bank"
|
||||
],
|
||||
"Food and Drink": [
|
||||
"acai_shop",
|
||||
"afghani_restaurant",
|
||||
"african_restaurant",
|
||||
"american_restaurant",
|
||||
"asian_restaurant",
|
||||
"bagel_shop",
|
||||
"bakery",
|
||||
"bar",
|
||||
"bar_and_grill",
|
||||
"barbecue_restaurant",
|
||||
"brazilian_restaurant",
|
||||
"breakfast_restaurant",
|
||||
"brunch_restaurant",
|
||||
"buffet_restaurant",
|
||||
"cafe",
|
||||
"cafeteria",
|
||||
"candy_store",
|
||||
"cat_cafe",
|
||||
"chinese_restaurant",
|
||||
"chocolate_factory",
|
||||
"chocolate_shop",
|
||||
"coffee_shop",
|
||||
"confectionery",
|
||||
"deli",
|
||||
"dessert_restaurant",
|
||||
"dessert_shop",
|
||||
"diner",
|
||||
"dog_cafe",
|
||||
"donut_shop",
|
||||
"fast_food_restaurant",
|
||||
"fine_dining_restaurant",
|
||||
"food_court",
|
||||
"french_restaurant",
|
||||
"greek_restaurant",
|
||||
"hamburger_restaurant",
|
||||
"ice_cream_shop",
|
||||
"indian_restaurant",
|
||||
"indonesian_restaurant",
|
||||
"italian_restaurant",
|
||||
"japanese_restaurant",
|
||||
"juice_shop",
|
||||
"korean_restaurant",
|
||||
"lebanese_restaurant",
|
||||
"meal_delivery",
|
||||
"meal_takeaway",
|
||||
"mediterranean_restaurant",
|
||||
"mexican_restaurant",
|
||||
"middle_eastern_restaurant",
|
||||
"pizza_restaurant",
|
||||
"pub",
|
||||
"ramen_restaurant",
|
||||
"restaurant",
|
||||
"sandwich_shop",
|
||||
"seafood_restaurant",
|
||||
"spanish_restaurant",
|
||||
"steak_house",
|
||||
"sushi_restaurant",
|
||||
"tea_house",
|
||||
"thai_restaurant",
|
||||
"turkish_restaurant",
|
||||
"vegan_restaurant",
|
||||
"vegetarian_restaurant",
|
||||
"vietnamese_restaurant",
|
||||
"wine_bar"
|
||||
],
|
||||
"Geographical Areas": [
|
||||
"administrative_area_level_1",
|
||||
"administrative_area_level_2",
|
||||
"country",
|
||||
"locality",
|
||||
"postal_code",
|
||||
"school_district"
|
||||
],
|
||||
"Government": [
|
||||
"city_hall",
|
||||
"courthouse",
|
||||
"embassy",
|
||||
"fire_station",
|
||||
"government_office",
|
||||
"police",
|
||||
"post_office"
|
||||
],
|
||||
"Health and Wellness": [
|
||||
"chiropractor",
|
||||
"dental_clinic",
|
||||
"dentist",
|
||||
"doctor",
|
||||
"drugstore",
|
||||
"hospital",
|
||||
"massage",
|
||||
"medical_lab",
|
||||
"pharmacy",
|
||||
"physiotherapist",
|
||||
"sauna",
|
||||
"skin_care_clinic",
|
||||
"spa",
|
||||
"tanning_studio",
|
||||
"wellness_center",
|
||||
"yoga_studio"
|
||||
],
|
||||
"Housing": [
|
||||
"apartment_building",
|
||||
"apartment_complex",
|
||||
"condominium_complex",
|
||||
"housing_complex"
|
||||
],
|
||||
"Lodging": [
|
||||
"bed_and_breakfast",
|
||||
"budget_japanese_inn",
|
||||
"campground",
|
||||
"camping_cabin",
|
||||
"cottage",
|
||||
"extended_stay_hotel",
|
||||
"farmstay",
|
||||
"guest_house",
|
||||
"hostel",
|
||||
"hotel",
|
||||
"inn",
|
||||
"japanese_inn",
|
||||
"lodging",
|
||||
"mobile_home_park",
|
||||
"motel",
|
||||
"private_guest_room",
|
||||
"resort_hotel",
|
||||
"rv_park"
|
||||
],
|
||||
"Natural Features": [
|
||||
"beach"
|
||||
],
|
||||
"Places of Worship": [
|
||||
"church",
|
||||
"hindu_temple",
|
||||
"mosque",
|
||||
"synagogue"
|
||||
],
|
||||
"Services": [
|
||||
"astrologer",
|
||||
"barber_shop",
|
||||
"beautician",
|
||||
"beauty_salon",
|
||||
"body_art_service",
|
||||
"catering_service",
|
||||
"cemetery",
|
||||
"child_care_agency",
|
||||
"consultant",
|
||||
"courier_service",
|
||||
"electrician",
|
||||
"florist",
|
||||
"food_delivery",
|
||||
"foot_care",
|
||||
"funeral_home",
|
||||
"hair_care",
|
||||
"hair_salon",
|
||||
"insurance_agency",
|
||||
"laundry",
|
||||
"lawyer",
|
||||
"locksmith",
|
||||
"makeup_artist",
|
||||
"moving_company",
|
||||
"nail_salon",
|
||||
"painter",
|
||||
"plumber",
|
||||
"psychic",
|
||||
"real_estate_agency",
|
||||
"roofing_contractor",
|
||||
"storage",
|
||||
"summer_camp_organizer",
|
||||
"tailor",
|
||||
"telecommunications_service_provider",
|
||||
"tour_agency",
|
||||
"tourist_information_center",
|
||||
"travel_agency",
|
||||
"veterinary_care"
|
||||
],
|
||||
"Shopping": [
|
||||
"asian_grocery_store",
|
||||
"auto_parts_store",
|
||||
"bicycle_store",
|
||||
"book_store",
|
||||
"butcher_shop",
|
||||
"cell_phone_store",
|
||||
"clothing_store",
|
||||
"convenience_store",
|
||||
"department_store",
|
||||
"discount_store",
|
||||
"electronics_store",
|
||||
"food_store",
|
||||
"furniture_store",
|
||||
"gift_shop",
|
||||
"grocery_store",
|
||||
"hardware_store",
|
||||
"home_improvement_store",
|
||||
"jewelry_store",
|
||||
"market",
|
||||
"pet_store",
|
||||
"shoe_store",
|
||||
"shopping_mall",
|
||||
"sporting_goods_store",
|
||||
"store",
|
||||
"supermarket",
|
||||
"warehouse_store",
|
||||
"wholesaler"
|
||||
],
|
||||
"Sports": [
|
||||
"arena",
|
||||
"athletic_field",
|
||||
"fishing_charter",
|
||||
"fishing_pond",
|
||||
"fitness_center",
|
||||
"golf_course",
|
||||
"gym",
|
||||
"ice_skating_rink",
|
||||
"playground",
|
||||
"ski_resort",
|
||||
"sports_activity_location",
|
||||
"sports_club",
|
||||
"sports_coaching",
|
||||
"sports_complex",
|
||||
"stadium",
|
||||
"swimming_pool"
|
||||
],
|
||||
"Transportation": [
|
||||
"airport",
|
||||
"airstrip",
|
||||
"bus_station",
|
||||
"bus_stop",
|
||||
"ferry_terminal",
|
||||
"heliport",
|
||||
"international_airport",
|
||||
"light_rail_station",
|
||||
"park_and_ride",
|
||||
"subway_station",
|
||||
"taxi_stand",
|
||||
"train_station",
|
||||
"transit_depot",
|
||||
"transit_station",
|
||||
"truck_stop"
|
||||
]
|
||||
}
|
||||
|
||||
# Kinds of fields:
|
||||
FIELD_MASK_BASIC_INFO = [
|
||||
"nextPageToken",
|
||||
"places.id",
|
||||
"places.name",
|
||||
"places.displayName",
|
||||
"places.formattedAddress",
|
||||
"places.location",
|
||||
"places.googleMapsUri",
|
||||
"places.photos",
|
||||
"places.primaryType",
|
||||
"places.types"
|
||||
]
|
||||
FIELD_MASK_BUSINESS_LEADS = [
|
||||
"nextPageToken",
|
||||
"places.id",
|
||||
"places.name",
|
||||
"places.displayName",
|
||||
"places.businessStatus",
|
||||
"places.formattedAddress",
|
||||
"places.postalAddress",
|
||||
"places.location"
|
||||
"places.googleMapsUri",
|
||||
"places.photos",
|
||||
"places.primaryType",
|
||||
"places.types",
|
||||
"places.regularOpeningHours",
|
||||
"places.regularSecondaryOpeningHours",
|
||||
"places.rating",
|
||||
"places.userRatingCount",
|
||||
"places.websiteUri",
|
||||
"places.internationalPhoneNumber",
|
||||
"places.priceLevel",
|
||||
"places.priceRange"
|
||||
]
|
||||
|
||||
# ┳┳ ┏┓ ┏•┓
|
||||
# ┃┃┏┏┓┏┓ ┃┃┏┓┏┓╋┓┃┏┓
|
||||
# ┗┛┛┗ ┛ ┣┛┛ ┗┛┛┗┗┗
|
||||
|
||||
async def get_user_profile(
|
||||
self,
|
||||
tokens: GoogleAuthTokens,
|
||||
user_id: str = "me",
|
||||
) -> GoogleApiResponse:
|
||||
|
||||
"""
|
||||
To get the details of the user that has logged in.
|
||||
DOCUMENTATION:
|
||||
1. https://developers.google.com/gmail/api/reference/rest/v1/users/getProfile
|
||||
2. https://developers.google.com/people/api/rest/v1/people/get
|
||||
3. https://developers.google.com/people/api/rest/v1/people#Person
|
||||
:param tokens: The object that holds the access token to the service.
|
||||
:param user_id: The id of the user for which this service must be run. Typically, the e-mail id itself or "me".
|
||||
:return: A structured response where the list of labels will be in the 'data' variable.
|
||||
"""
|
||||
|
||||
# Ensure that the tokens are valid:
|
||||
await tokens.arefresh(
|
||||
http_client=self._http_client,
|
||||
client_id=self._client_id,
|
||||
client_secret=self._client_secret,
|
||||
force_refresh=False
|
||||
)
|
||||
|
||||
# Make the GMail API call:
|
||||
if not self._debug_only_errors: self._printer("Getting User Profile.")
|
||||
gmail_api_response = await self.get(
|
||||
url=f"https://gmail.googleapis.com/gmail/v1/users/{user_id}/profile",
|
||||
headers={"Authorization": f"Bearer {tokens.accessToken}"}
|
||||
)
|
||||
|
||||
# If the call was successful:
|
||||
if gmail_api_response.httpCode in [200]:
|
||||
gmail_api_response.success = True
|
||||
gmail_api_response.data = await gmail_api_response.get_json()
|
||||
gmail_api_response.data["displayName"] = None
|
||||
gmail_api_response.data["displayPictureUrl"] = None
|
||||
|
||||
# If the call failed:
|
||||
else:
|
||||
self._printer(
|
||||
gmail_api_response.action,
|
||||
gmail_api_response.method,
|
||||
gmail_api_response.httpCode,
|
||||
)
|
||||
return gmail_api_response
|
||||
|
||||
# Make the People API call:
|
||||
if not self._debug_only_errors: self._printer("Getting User Profile.")
|
||||
people_api_response = await self.get(
|
||||
url=f"https://people.googleapis.com/v1/people/me?personFields=names,photos,birthdays,phoneNumbers,genders,emailAddresses,addresses",
|
||||
headers={"Authorization": f"Bearer {tokens.accessToken}"}
|
||||
)
|
||||
|
||||
# If the call was successful:
|
||||
if people_api_response.httpCode in [200]:
|
||||
people_api_response.success = True
|
||||
people_api_response.data = await people_api_response.get_json()
|
||||
for item in people_api_response.data.get("names", []):
|
||||
if item["metadata"]["primary"]:
|
||||
gmail_api_response.data["displayName"] = item.get("displayName")
|
||||
for item in people_api_response.data.get("photos", []):
|
||||
if item["metadata"]["primary"]:
|
||||
gmail_api_response.data["displayPictureUrl"] = item.get("url")
|
||||
|
||||
# If the call failed:
|
||||
else:
|
||||
self._printer(
|
||||
people_api_response.action,
|
||||
people_api_response.method,
|
||||
people_api_response.httpCode,
|
||||
)
|
||||
|
||||
# Done here:
|
||||
return gmail_api_response
|
||||
|
||||
# ┏┓ •
|
||||
# ┃┃┏┓┏┓┏┓┏┓┏┓╋┓┏┓┏
|
||||
# ┣┛┛ ┗┛┣┛┗ ┛ ┗┗┗ ┛
|
||||
# ┛
|
||||
|
||||
@property
|
||||
def primary_types(self):
|
||||
return list(self.PLACE_TYPES.keys())
|
||||
|
||||
def types_for(self, primary_type: str):
|
||||
return self.PLACE_TYPES.get(primary_type)
|
||||
|
||||
# async def _nearby_radius_search(
|
||||
# self,
|
||||
# tokens: GoogleAuthTokens,
|
||||
# latitude: float,
|
||||
# longitude: float,
|
||||
# radius: float,
|
||||
# max_count: int = 100,
|
||||
# next_page_token: str = None,
|
||||
# ) -> GoogleApiResponse:
|
||||
|
||||
async def nearby_radius_search(
|
||||
self,
|
||||
tokens: GoogleAuthTokens,
|
||||
latitude: float,
|
||||
longitude: float,
|
||||
radius: float,
|
||||
included_primary_types: List[str] = None,
|
||||
included_types: List[str] = None,
|
||||
excluded_primary_types: List[str] = None,
|
||||
excluded_types: List[str] = None,
|
||||
field_mask: List[str] = None,
|
||||
max_count: int = 100,
|
||||
next_page_token: str = None,
|
||||
) -> GoogleApiResponse:
|
||||
|
||||
"""
|
||||
https://developers.google.com/maps/documentation/places/web-service/nearby-search
|
||||
"""
|
||||
|
||||
# Ensure that the tokens are valid:
|
||||
await tokens.arefresh(
|
||||
http_client = self._http_client,
|
||||
client_id = self._client_id,
|
||||
client_secret = self._client_secret,
|
||||
force_refresh = False
|
||||
)
|
||||
|
||||
# Create the headers:
|
||||
request_headers = {"Authorization": f"Bearer {tokens.accessToken}"}
|
||||
if field_mask: request_headers["X-Goog-FieldMask"] = ",".join(field_mask)
|
||||
|
||||
# Start creating the JSON payload based on the inputs:
|
||||
request_json = {
|
||||
"maxResultCount": max_count,
|
||||
"locationRestriction": {
|
||||
"circle": {
|
||||
"center": {
|
||||
"latitude": latitude,
|
||||
"longitude": longitude
|
||||
},
|
||||
"radius": radius
|
||||
}
|
||||
}
|
||||
}
|
||||
if included_primary_types: request_json["includedPrimaryTypes"] = included_primary_types
|
||||
if included_types: request_json["includedTypes"] = included_types
|
||||
if excluded_primary_types: request_json["excludedPrimaryTypes"] = excluded_primary_types
|
||||
if excluded_types: request_json["excludedTypes"] = excluded_types
|
||||
|
||||
# Make the API call:
|
||||
if not self._debug_only_errors: self._printer("Listing Nearby (Radius) Places.")
|
||||
api_response = await self.post(
|
||||
url = f"https://places.googleapis.com/v1/places:searchNearby",
|
||||
headers = request_headers,
|
||||
json = request_json
|
||||
)
|
||||
|
||||
# If the call was successful:
|
||||
if api_response.httpCode in [200]:
|
||||
api_response.success = True
|
||||
api_response.data = await api_response.get_json()
|
||||
|
||||
# Done here:
|
||||
return api_response
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MAIN PROGRAM ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Create an HTTP client:
|
||||
test_client = httpx.AsyncClient(
|
||||
limits = httpx.Limits(
|
||||
max_connections = 100, # ............ Maximum number of connections allowed in the pool.
|
||||
max_keepalive_connections = 50, # ... Maximum number of connections that can be kept alive.
|
||||
),
|
||||
timeout = httpx.Timeout(
|
||||
connect = 2.5, # ... Shorter connection timeout.
|
||||
read = 2.5, # ...... Like what EasyEcom gives.
|
||||
write = 10.0, # .... Time to wait for sending data.
|
||||
pool = 120.0 # ..... Time to wait for a free connection from the pool.
|
||||
)
|
||||
)
|
||||
|
||||
# Read the secrets that give you access to the app:
|
||||
# secrets_file = r"C:\Users\Khushal P Soonderji\Downloads\google_places_test_secret.json"
|
||||
secrets_file = r"/home/python-dev-debug/Downloads/client_secret_349360248417-uuba8eudk75jg1jag212g5obhc1uostk.apps.googleusercontent.com.json"
|
||||
secrets_dict = json.from_file(secrets_file)
|
||||
|
||||
async def main():
|
||||
|
||||
# Create an instance of the client:
|
||||
my_goog = AsyncPlacesClient(
|
||||
service_name = "places",
|
||||
oauth_json = secrets_dict,
|
||||
http_client = test_client,
|
||||
redirect_url = r"https://wtt.ditscentre.in/shopify/test/1",
|
||||
debug = True,
|
||||
debug_prefix = "Places (M) | ",
|
||||
debug_only_errors = False
|
||||
)
|
||||
|
||||
# Request Auth:
|
||||
print("AUTH URL:", await my_goog.get_authorization_url(
|
||||
scopes = SCOPES_PLACES_FULL,
|
||||
state = "Bhopli",
|
||||
approval_prompt = "force"
|
||||
))
|
||||
|
||||
# Get tokens from callback:
|
||||
test_tokens = await my_goog.get_authorization_tokens(
|
||||
scopes = SCOPES_PLACES_FULL,
|
||||
redirect_url = input("Paste the redirect URL here: ")
|
||||
)
|
||||
print("TOKENS:", test_tokens)
|
||||
|
||||
# List out the primary and secondary types:
|
||||
print("PRIMARY TYPES:", my_goog.primary_types)
|
||||
print("'Food and Drink' TYPES:", my_goog.types_for("Food and Drink"))
|
||||
print("'Alien Spaceship' TYPES:", my_goog.types_for("Alien Spaceship"))
|
||||
|
||||
response = await my_goog.get_user_profile(
|
||||
tokens=test_tokens
|
||||
)
|
||||
|
||||
print("SUCCESS:", response.success)
|
||||
print("SUMMARY:", response.to_markdown())
|
||||
print("\n\n---\n\n")
|
||||
print("DATA:", json.to_string(response.data, default=str))
|
||||
if not response.success:
|
||||
print("\n\n---\n\n")
|
||||
|
||||
# Test some feature:
|
||||
response = await my_goog.nearby_radius_search(
|
||||
tokens = test_tokens,
|
||||
latitude = 19.03145183334671,
|
||||
longitude = 72.85437426861148,
|
||||
radius = 1_000.0,
|
||||
field_mask = None,
|
||||
max_count = 5,
|
||||
)
|
||||
print("SUCCESS:", response.success)
|
||||
print("SUMMARY:", response.to_markdown())
|
||||
print("\n\n---\n\n")
|
||||
print("DATA:", json.to_string(response.data, default = str))
|
||||
if not response.success:
|
||||
print("\n\n---\n\n")
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user