dhisana 0.0.1.dev219__py3-none-any.whl → 0.0.1.dev220__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ from dhisana.schemas.sales import LeadsQueryFilters, CompanyQueryFilters
11
11
  from dhisana.utils.cache_output_tools import cache_output, retrieve_output
12
12
  from dhisana.utils.assistant_tool_tag import assistant_tool
13
13
  from urllib.parse import urlparse, parse_qs
14
- from typing import Any, Dict, List, Optional, Union
14
+ from typing import Any, Dict, List, Optional, Tuple, Union
15
15
 
16
16
  from dhisana.utils.clean_properties import cleanup_properties
17
17
 
@@ -19,50 +19,81 @@ logging.basicConfig(level=logging.INFO)
19
19
  logger = logging.getLogger(__name__)
20
20
 
21
21
 
22
- def get_apollo_access_token(tool_config: Optional[List[Dict]] = None) -> str:
22
+ def get_apollo_access_token(tool_config: Optional[List[Dict]] = None) -> Tuple[str, bool]:
23
23
  """
24
- Retrieves the APOLLO_API_KEY access token from the provided tool configuration.
24
+ Retrieves an Apollo access token from tool configuration or environment variables.
25
25
 
26
26
  Args:
27
- tool_config (list): A list of dictionaries containing the tool configuration.
28
- Each dictionary should have a "name" key and a "configuration" key,
29
- where "configuration" is a list of dictionaries containing "name" and "value" keys.
27
+ tool_config (list): Optional tool configuration payload provided to the tool.
30
28
 
31
29
  Returns:
32
- str: The APOLLO_API_KEY access token.
30
+ Tuple[str, bool]: A tuple containing the token string and a boolean flag indicating
31
+ whether the token represents an OAuth bearer token (``True``) or an API key (``False``).
33
32
 
34
33
  Raises:
35
34
  ValueError: If the Apollo integration has not been configured.
36
35
  """
37
- APOLLO_API_KEY = None
36
+ token: Optional[str] = None
37
+ is_oauth = False
38
38
 
39
39
  if tool_config:
40
- logger.debug(f"Tool config provided: {tool_config}")
41
40
  apollo_config = next(
42
41
  (item for item in tool_config if item.get("name") == "apollo"), None
43
42
  )
44
43
  if apollo_config:
45
44
  config_map = {
46
- item["name"]: item["value"]
45
+ item["name"]: item.get("value")
47
46
  for item in apollo_config.get("configuration", [])
48
47
  if item
49
48
  }
50
- APOLLO_API_KEY = config_map.get("apiKey")
49
+
50
+ raw_oauth = config_map.get("oauth_tokens")
51
+ if isinstance(raw_oauth, str):
52
+ try:
53
+ raw_oauth = json.loads(raw_oauth)
54
+ except Exception:
55
+ raw_oauth = None
56
+ if isinstance(raw_oauth, dict):
57
+ token = (
58
+ raw_oauth.get("access_token")
59
+ or raw_oauth.get("token")
60
+ )
61
+ if token:
62
+ is_oauth = True
63
+
64
+ if not token:
65
+ direct_access_token = config_map.get("access_token")
66
+ if direct_access_token:
67
+ token = direct_access_token
68
+ is_oauth = True
69
+
70
+ if not token:
71
+ api_key = config_map.get("apiKey") or config_map.get("api_key")
72
+ if api_key:
73
+ token = api_key
74
+ is_oauth = False
51
75
  else:
52
76
  logger.warning("No 'apollo' config item found in tool_config.")
53
- else:
54
- logger.debug("No tool_config provided or it's None.")
55
77
 
56
- # Check environment variable if no key found yet
57
- APOLLO_API_KEY = APOLLO_API_KEY or os.getenv("APOLLO_API_KEY")
78
+ if not token:
79
+ env_oauth_token = os.getenv("APOLLO_ACCESS_TOKEN")
80
+ if env_oauth_token:
81
+ token = env_oauth_token
82
+ is_oauth = True
83
+
84
+ if not token:
85
+ env_api_key = os.getenv("APOLLO_API_KEY")
86
+ if env_api_key:
87
+ token = env_api_key
88
+ is_oauth = False
58
89
 
59
- if not APOLLO_API_KEY:
90
+ if not token:
60
91
  logger.error("Apollo integration is not configured.")
61
92
  raise ValueError(
62
93
  "Apollo integration is not configured. Please configure the connection to Apollo in Integrations."
63
94
  )
64
95
 
65
- return APOLLO_API_KEY
96
+ return token, is_oauth
66
97
 
67
98
 
68
99
  @assistant_tool
@@ -94,16 +125,17 @@ async def enrich_person_info_from_apollo(
94
125
  """
95
126
  logger.info("Entering enrich_person_info_from_apollo")
96
127
 
97
- APOLLO_API_KEY = get_apollo_access_token(tool_config)
128
+ token, is_oauth = get_apollo_access_token(tool_config)
98
129
 
99
130
  if not linkedin_url and not email and not phone:
100
131
  logger.warning("No linkedin_url, email, or phone provided. At least one is required.")
101
132
  return {'error': "At least one of linkedin_url, email, or phone must be provided"}
102
133
 
103
- headers = {
104
- "X-Api-Key": f"{APOLLO_API_KEY}",
105
- "Content-Type": "application/json"
106
- }
134
+ headers = {"Content-Type": "application/json"}
135
+ if is_oauth:
136
+ headers["Authorization"] = f"Bearer {token}"
137
+ else:
138
+ headers["X-Api-Key"] = token
107
139
 
108
140
  data = {}
109
141
  if linkedin_url:
@@ -186,11 +218,12 @@ async def lookup_person_in_apollo_by_name(
186
218
  logger.warning("No full_name provided.")
187
219
  return {'error': "Full name is required"}
188
220
 
189
- APOLLO_API_KEY = get_apollo_access_token(tool_config)
190
- headers = {
191
- "X-Api-Key": f"{APOLLO_API_KEY}",
192
- "Content-Type": "application/json"
193
- }
221
+ token, is_oauth = get_apollo_access_token(tool_config)
222
+ headers = {"Content-Type": "application/json"}
223
+ if is_oauth:
224
+ headers["Authorization"] = f"Bearer {token}"
225
+ else:
226
+ headers["X-Api-Key"] = token
194
227
 
195
228
  # Construct the query payload
196
229
  data = {
@@ -263,18 +296,21 @@ async def enrich_organization_info_from_apollo(
263
296
  """
264
297
  logger.info("Entering enrich_organization_info_from_apollo")
265
298
 
266
- APOLLO_API_KEY = get_apollo_access_token(tool_config)
299
+ token, is_oauth = get_apollo_access_token(tool_config)
267
300
 
268
301
  if not organization_domain:
269
302
  logger.warning("No organization domain provided.")
270
303
  return {'error': "organization domain must be provided"}
271
304
 
272
305
  headers = {
273
- "X-Api-Key": f"{APOLLO_API_KEY}",
274
306
  "Content-Type": "application/json",
275
307
  "Cache-Control": "no-cache",
276
308
  "accept": "application/json"
277
309
  }
310
+ if is_oauth:
311
+ headers["Authorization"] = f"Bearer {token}"
312
+ else:
313
+ headers["X-Api-Key"] = token
278
314
 
279
315
  cached_response = retrieve_output("enrich_organization_info_from_apollo", organization_domain)
280
316
  if cached_response is not None:
@@ -364,12 +400,15 @@ async def search_people_with_apollo(
364
400
  logger.warning("No payload given; returning empty result.")
365
401
  return []
366
402
 
367
- api_key = get_apollo_access_token(tool_config)
403
+ token, is_oauth = get_apollo_access_token(tool_config)
368
404
  headers = {
369
405
  "Cache-Control": "no-cache",
370
406
  "Content-Type": "application/json",
371
- "X-Api-Key": api_key,
372
407
  }
408
+ if is_oauth:
409
+ headers["Authorization"] = f"Bearer {token}"
410
+ else:
411
+ headers["X-Api-Key"] = token
373
412
 
374
413
  url = "https://api.apollo.io/api/v1/mixed_people/search"
375
414
  logger.info(f"Sending payload to Apollo (single page): {json.dumps(dynamic_payload, indent=2)}")
@@ -840,12 +879,15 @@ async def search_leads_with_apollo_page(
840
879
  f" Payload: {json.dumps(page_payload, indent=2)}")
841
880
 
842
881
  # Get the full Apollo API response with pagination metadata
843
- api_key = get_apollo_access_token(tool_config)
882
+ token, is_oauth = get_apollo_access_token(tool_config)
844
883
  headers = {
845
884
  "Cache-Control": "no-cache",
846
885
  "Content-Type": "application/json",
847
- "X-Api-Key": api_key,
848
886
  }
887
+ if is_oauth:
888
+ headers["Authorization"] = f"Bearer {token}"
889
+ else:
890
+ headers["X-Api-Key"] = token
849
891
 
850
892
  url = "https://api.apollo.io/api/v1/mixed_people/search"
851
893
 
@@ -950,17 +992,20 @@ async def get_organization_details_from_apollo(
950
992
  """
951
993
  logger.info("Entering get_organization_details_from_apollo")
952
994
 
953
- APOLLO_API_KEY = get_apollo_access_token(tool_config)
995
+ token, is_oauth = get_apollo_access_token(tool_config)
954
996
  if not organization_id:
955
997
  logger.warning("No organization_id provided.")
956
998
  return {'error': "Organization ID must be provided"}
957
999
 
958
1000
  headers = {
959
- "X-Api-Key": APOLLO_API_KEY,
960
1001
  "Content-Type": "application/json",
961
1002
  "Cache-Control": "no-cache",
962
1003
  "Accept": "application/json"
963
1004
  }
1005
+ if is_oauth:
1006
+ headers["Authorization"] = f"Bearer {token}"
1007
+ else:
1008
+ headers["X-Api-Key"] = token
964
1009
 
965
1010
  cached_response = retrieve_output("get_organization_details_from_apollo", organization_id)
966
1011
  if cached_response is not None:
@@ -1202,12 +1247,15 @@ async def search_companies_with_apollo(
1202
1247
  logger.warning("No payload given; returning empty result.")
1203
1248
  return []
1204
1249
 
1205
- api_key = get_apollo_access_token(tool_config)
1250
+ token, is_oauth = get_apollo_access_token(tool_config)
1206
1251
  headers = {
1207
1252
  "Cache-Control": "no-cache",
1208
1253
  "Content-Type": "application/json",
1209
- "X-Api-Key": api_key,
1210
1254
  }
1255
+ if is_oauth:
1256
+ headers["Authorization"] = f"Bearer {token}"
1257
+ else:
1258
+ headers["X-Api-Key"] = token
1211
1259
 
1212
1260
  url = "https://api.apollo.io/api/v1/organizations/search"
1213
1261
  logger.info(f"Sending payload to Apollo organizations endpoint (single page): {json.dumps(dynamic_payload, indent=2)}")
@@ -1508,12 +1556,15 @@ async def search_companies_with_apollo_page(
1508
1556
  f" Payload: {json.dumps(cleaned_payload, indent=2)}")
1509
1557
 
1510
1558
  # Get the full Apollo API response with pagination metadata
1511
- api_key = get_apollo_access_token(tool_config)
1559
+ token, is_oauth = get_apollo_access_token(tool_config)
1512
1560
  headers = {
1513
1561
  "Cache-Control": "no-cache",
1514
1562
  "Content-Type": "application/json",
1515
- "X-Api-Key": api_key,
1516
1563
  }
1564
+ if is_oauth:
1565
+ headers["Authorization"] = f"Bearer {token}"
1566
+ else:
1567
+ headers["X-Api-Key"] = token
1517
1568
 
1518
1569
  url = "https://api.apollo.io/api/v1/organizations/search"
1519
1570
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev219
3
+ Version: 0.0.1.dev220
4
4
  Summary: A Python SDK for Dhisana AI Platform
5
5
  Home-page: https://github.com/dhisana-ai/dhisana-python-sdk
6
6
  Author: Admin
@@ -12,7 +12,7 @@ dhisana/ui/components.py,sha256=4NXrAyl9tx2wWwoVYyABO-EOGnreGMvql1AkXWajIIo,1431
12
12
  dhisana/utils/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
13
13
  dhisana/utils/add_mapping.py,sha256=oq_QNqag86DhgdwINBRRXNx7SOb8Q9M-V0QLP6pTzr8,13837
14
14
  dhisana/utils/agent_tools.py,sha256=pzBFvfhU4wfSB4zv1eiRzjmnteJnfhC5V32r_v1m38Y,2321
15
- dhisana/utils/apollo_tools.py,sha256=no-PwDVtPfOSDr6eZ-cN5C3C_Yf2SeElft5ksap24Gg,64136
15
+ dhisana/utils/apollo_tools.py,sha256=WSt5SV3ElfYlNjFw6-8FyZ0_6wete5vahoSYPhACcD8,65716
16
16
  dhisana/utils/assistant_tool_tag.py,sha256=rYRl8ubLI7fUUIjg30XTefHBkFgRqNEVC12lF6U6Z-8,119
17
17
  dhisana/utils/built_with_api_tools.py,sha256=TFNGhnPb2vFdveVCpjiCvE1WKe_eK95UPpR0Ha5NgMQ,10260
18
18
  dhisana/utils/cache_output_tools.py,sha256=sSAruvUZn-WAJQ0lB9T1QjSmkm-_14AuxC9xKmcCQ0k,3428
@@ -92,8 +92,8 @@ dhisana/workflow/agent.py,sha256=esv7_i_XuMkV2j1nz_UlsHov_m6X5WZZiZm_tG4OBHU,565
92
92
  dhisana/workflow/flow.py,sha256=xWE3qQbM7j2B3FH8XnY3zOL_QXX4LbTW4ArndnEYJE0,1638
93
93
  dhisana/workflow/task.py,sha256=HlWz9mtrwLYByoSnePOemBUBrMEcj7KbgNjEE1oF5wo,1830
94
94
  dhisana/workflow/test.py,sha256=kwW8jWqSBNcRmoyaxlTuZCMOpGJpTbJQgHI7gSjwdzM,3399
95
- dhisana-0.0.1.dev219.dist-info/METADATA,sha256=T-dWWhSYokCE-P7SB5slEkbuuHfXlpm7lrWGRXiSaV0,1190
96
- dhisana-0.0.1.dev219.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
- dhisana-0.0.1.dev219.dist-info/entry_points.txt,sha256=jujxteZmNI9EkEaK-pOCoWuBujU8TCevdkfl9ZcKHek,49
98
- dhisana-0.0.1.dev219.dist-info/top_level.txt,sha256=NETTHt6YifG_P7XtRHbQiXZlgSFk9Qh9aR-ng1XTf4s,8
99
- dhisana-0.0.1.dev219.dist-info/RECORD,,
95
+ dhisana-0.0.1.dev220.dist-info/METADATA,sha256=HsH4PGLIF-9i_HFv9ODch9lhyl7tdQ48epFKP7TcUXM,1190
96
+ dhisana-0.0.1.dev220.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
+ dhisana-0.0.1.dev220.dist-info/entry_points.txt,sha256=jujxteZmNI9EkEaK-pOCoWuBujU8TCevdkfl9ZcKHek,49
98
+ dhisana-0.0.1.dev220.dist-info/top_level.txt,sha256=NETTHt6YifG_P7XtRHbQiXZlgSFk9Qh9aR-ng1XTf4s,8
99
+ dhisana-0.0.1.dev220.dist-info/RECORD,,