dhisana 0.0.1.dev248__py3-none-any.whl → 0.0.1.dev250__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.
@@ -1287,62 +1287,131 @@ def fill_in_company_properties(company_data: dict) -> dict:
1287
1287
  company_data: Raw company data from Apollo API
1288
1288
 
1289
1289
  Returns:
1290
- Dictionary with standardized company properties
1290
+ Dictionary matching the SmartList `Account` schema shape.
1291
1291
  """
1292
- company_properties = {}
1292
+ def _parse_keywords(value: Any) -> List[Any]:
1293
+ if value is None:
1294
+ return []
1295
+ if isinstance(value, list):
1296
+ return value
1297
+ if isinstance(value, str):
1298
+ text = value.strip()
1299
+ if not text:
1300
+ return []
1301
+ if "," in text:
1302
+ return [part.strip() for part in text.split(",") if part.strip()]
1303
+ return [text]
1304
+ return [value]
1305
+
1306
+ def _parse_compact_number(value: Any) -> Optional[float]:
1307
+ if value is None:
1308
+ return None
1309
+ if isinstance(value, (int, float)):
1310
+ return float(value)
1311
+ text = str(value).strip()
1312
+ if not text:
1313
+ return None
1314
+ text = text.replace("$", "").replace(",", "").strip()
1315
+ multiplier = 1.0
1316
+ suffix = text[-1:].upper()
1317
+ if suffix in ("K", "M", "B"):
1318
+ multiplier = {"K": 1e3, "M": 1e6, "B": 1e9}[suffix]
1319
+ text = text[:-1].strip()
1320
+ try:
1321
+ return float(text) * multiplier
1322
+ except ValueError:
1323
+ return None
1293
1324
 
1294
- # Basic company information
1295
- company_properties["organization_name"] = company_data.get("name", "")
1296
- company_properties["primary_domain"] = company_data.get("primary_domain", "")
1297
- company_properties["website_url"] = company_data.get("website_url", "")
1298
- company_properties["organization_linkedin_url"] = company_data.get("linkedin_url", "")
1299
-
1300
- # Location information
1301
- company_properties["organization_city"] = company_data.get("city", "")
1302
- company_properties["organization_state"] = company_data.get("state", "")
1303
- company_properties["organization_country"] = company_data.get("country", "")
1304
-
1305
- # Create a combined location string
1306
- location_parts = [
1307
- company_data.get("city", ""),
1308
- company_data.get("state", ""),
1309
- company_data.get("country", "")
1310
- ]
1311
- company_properties["organization_location"] = ", ".join([part for part in location_parts if part])
1312
-
1313
- # Company size and financial info
1314
- company_properties["employee_count"] = company_data.get("estimated_num_employees", 0)
1315
- company_properties["annual_revenue"] = company_data.get("annual_revenue", 0)
1316
-
1317
- # Industry and business info
1318
- company_properties["industry"] = company_data.get("industry", "")
1319
- company_properties["keywords"] = ", ".join(company_data.get("keywords", []))
1320
- company_properties["description"] = company_data.get("description", "")
1321
-
1322
- # Funding and growth
1323
- company_properties["founded_year"] = company_data.get("founded_year", "")
1324
- company_properties["funding_stage"] = company_data.get("latest_funding_stage", "")
1325
- company_properties["total_funding"] = company_data.get("total_funding", 0)
1326
-
1327
- # Technology stack
1328
- tech_stack = company_data.get("technology_names", [])
1329
- if tech_stack:
1330
- company_properties["technology_stack"] = ", ".join(tech_stack)
1331
-
1332
- # Apollo-specific IDs
1333
- company_properties["apollo_organization_id"] = company_data.get("id", "")
1334
-
1335
- # Additional metadata
1336
- company_properties["phone"] = company_data.get("phone", "")
1337
- company_properties["facebook_url"] = company_data.get("facebook_url", "")
1338
- company_properties["twitter_url"] = company_data.get("twitter_url", "")
1339
-
1340
- # Store raw data for reference
1341
- company_properties["additional_properties"] = {
1342
- "apollo_organization_data": json.dumps(cleanup_properties(company_data))
1325
+ annual_revenue = (
1326
+ company_data.get("organization_revenue")
1327
+ if company_data.get("organization_revenue") is not None
1328
+ else company_data.get("annual_revenue")
1329
+ )
1330
+ annual_revenue = _parse_compact_number(annual_revenue)
1331
+ if annual_revenue is None:
1332
+ annual_revenue = _parse_compact_number(company_data.get("organization_revenue_printed"))
1333
+
1334
+ company_size = company_data.get("estimated_num_employees")
1335
+ if company_size is not None:
1336
+ try:
1337
+ company_size = int(company_size)
1338
+ except (TypeError, ValueError):
1339
+ company_size = None
1340
+
1341
+ founded_year = company_data.get("founded_year")
1342
+ if founded_year is not None:
1343
+ try:
1344
+ founded_year = int(founded_year)
1345
+ except (TypeError, ValueError):
1346
+ founded_year = None
1347
+
1348
+ primary_phone = company_data.get("primary_phone")
1349
+ primary_phone_number = None
1350
+ if isinstance(primary_phone, dict):
1351
+ primary_phone_number = primary_phone.get("number") or primary_phone.get(
1352
+ "sanitized_number"
1353
+ )
1354
+
1355
+ phone = (
1356
+ primary_phone_number
1357
+ or company_data.get("phone")
1358
+ or company_data.get("primary_phone_number")
1359
+ or company_data.get("sanitized_phone")
1360
+ )
1361
+
1362
+ industry = company_data.get("industry")
1363
+ if not industry and isinstance(company_data.get("industries"), list):
1364
+ industries = [str(x).strip() for x in company_data["industries"] if str(x).strip()]
1365
+ industry = industries[0] if industries else None
1366
+
1367
+ billing_street = (
1368
+ company_data.get("street_address")
1369
+ or company_data.get("billing_street")
1370
+ or company_data.get("address")
1371
+ or company_data.get("raw_address")
1372
+ )
1373
+
1374
+ account: Dict[str, Any] = {
1375
+ "name": company_data.get("name"),
1376
+ "domain": company_data.get("primary_domain"),
1377
+ "website": company_data.get("website_url"),
1378
+ "phone": phone,
1379
+ "fax": company_data.get("fax") or company_data.get("fax_number"),
1380
+ "industry": industry,
1381
+ "company_size": company_size,
1382
+ "founded_year": founded_year,
1383
+ "annual_revenue": annual_revenue,
1384
+ "type": company_data.get("type") or company_data.get("organization_type"),
1385
+ "ownership": company_data.get("ownership"),
1386
+ "organization_linkedin_url": company_data.get("linkedin_url"),
1387
+ "billing_street": billing_street,
1388
+ "billing_city": company_data.get("city"),
1389
+ "billing_state": company_data.get("state"),
1390
+ "billing_zip": company_data.get("postal_code")
1391
+ or company_data.get("zip")
1392
+ or company_data.get("zipcode"),
1393
+ "billing_country": company_data.get("country"),
1394
+ "description": company_data.get("description"),
1395
+ "keywords": _parse_keywords(company_data.get("keywords")),
1396
+ "tags": [],
1397
+ "notes": [],
1398
+ "additional_properties": {
1399
+ "apollo_organization_id": company_data.get("id"),
1400
+ "facebook_url": company_data.get("facebook_url"),
1401
+ "twitter_url": company_data.get("twitter_url"),
1402
+ "funding_stage": company_data.get("latest_funding_stage"),
1403
+ "total_funding": company_data.get("total_funding"),
1404
+ "technology_names": company_data.get("technology_names"),
1405
+ "primary_phone": primary_phone if isinstance(primary_phone, dict) else None,
1406
+ "raw_address": company_data.get("raw_address"),
1407
+ "organization_revenue_printed": company_data.get("organization_revenue_printed"),
1408
+ "apollo_organization_data": json.dumps(cleanup_properties(company_data)),
1409
+ },
1410
+ "research_summary": None,
1411
+ "enchrichment_status": None,
1343
1412
  }
1344
1413
 
1345
- return company_properties
1414
+ return account
1346
1415
 
1347
1416
 
1348
1417
  @assistant_tool
@@ -1485,7 +1554,7 @@ async def search_companies_with_apollo_page(
1485
1554
  # -----------------------------------
1486
1555
  else:
1487
1556
  dynamic_payload = {}
1488
-
1557
+
1489
1558
  # Only add fields if they have values (Apollo doesn't like empty arrays)
1490
1559
  if query.organization_locations:
1491
1560
  dynamic_payload["organization_locations"] = query.organization_locations
@@ -1505,19 +1574,37 @@ async def search_companies_with_apollo_page(
1505
1574
  dynamic_payload["organization_num_employees_ranges"] = employee_ranges
1506
1575
 
1507
1576
  # Add optional parameters only if they have values
1577
+ def _normalize_string_list(value: Any) -> List[str]:
1578
+ if value is None:
1579
+ return []
1580
+ if isinstance(value, str):
1581
+ return [part.strip() for part in value.split(",") if part.strip()]
1582
+ if isinstance(value, list):
1583
+ normalized: List[str] = []
1584
+ for item in value:
1585
+ if item is None:
1586
+ continue
1587
+ text = str(item).strip()
1588
+ if not text:
1589
+ continue
1590
+ normalized.extend([part.strip() for part in text.split(",") if part.strip()])
1591
+ return normalized
1592
+ text = str(value).strip()
1593
+ return [text] if text else []
1594
+
1508
1595
  if query.q_keywords:
1509
- # Split comma-separated keywords into an array for company search
1510
- if isinstance(query.q_keywords, str):
1511
- keyword_tags = [tag.strip() for tag in query.q_keywords.split(",") if tag.strip()]
1512
- else:
1513
- keyword_tags = query.q_keywords
1514
-
1515
- if query.q_organization_keyword_tags:
1516
- dynamic_payload["q_organization_keyword_tags"] = keyword_tags
1517
-
1518
- if query.q_not_organization_keyword_tags:
1519
- dynamic_payload["q_not_organization_keyword_tags"] = query.q_not_organization_keyword_tags
1520
-
1596
+ keywords = _normalize_string_list(query.q_keywords)
1597
+ if keywords:
1598
+ dynamic_payload["q_keywords"] = " ".join(keywords)
1599
+
1600
+ org_keyword_tags = _normalize_string_list(query.q_organization_keyword_tags)
1601
+ if org_keyword_tags:
1602
+ dynamic_payload["q_organization_keyword_tags"] = org_keyword_tags
1603
+
1604
+ not_org_keyword_tags = _normalize_string_list(query.q_not_organization_keyword_tags)
1605
+ if not_org_keyword_tags:
1606
+ dynamic_payload["q_not_organization_keyword_tags"] = not_org_keyword_tags
1607
+
1521
1608
  if query.q_organization_domains:
1522
1609
  dynamic_payload["q_organization_domains_list"] = query.q_organization_domains
1523
1610
  if query.revenue_range_min is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev248
3
+ Version: 0.0.1.dev250
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=i3PVY3vhiGUOTQ_GAOPXCwDyUcqkiV3DrCgo2ozRSeQ,66705
15
+ dhisana/utils/apollo_tools.py,sha256=1b9FaL_3spQKUsOP1k8-kD1kcFxCkG4KJHoN71SjOkU,69796
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
@@ -95,8 +95,8 @@ dhisana/workflow/agent.py,sha256=esv7_i_XuMkV2j1nz_UlsHov_m6X5WZZiZm_tG4OBHU,565
95
95
  dhisana/workflow/flow.py,sha256=xWE3qQbM7j2B3FH8XnY3zOL_QXX4LbTW4ArndnEYJE0,1638
96
96
  dhisana/workflow/task.py,sha256=HlWz9mtrwLYByoSnePOemBUBrMEcj7KbgNjEE1oF5wo,1830
97
97
  dhisana/workflow/test.py,sha256=E7lRnXK0PguTNzyasHytLzTJdkqIPxG5_4qk4hMEeKc,3399
98
- dhisana-0.0.1.dev248.dist-info/METADATA,sha256=B6n7vZSB3JheNeY9GWQ8DMaAGE9TKG9hzPyRILaq-xA,1190
99
- dhisana-0.0.1.dev248.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
- dhisana-0.0.1.dev248.dist-info/entry_points.txt,sha256=jujxteZmNI9EkEaK-pOCoWuBujU8TCevdkfl9ZcKHek,49
101
- dhisana-0.0.1.dev248.dist-info/top_level.txt,sha256=NETTHt6YifG_P7XtRHbQiXZlgSFk9Qh9aR-ng1XTf4s,8
102
- dhisana-0.0.1.dev248.dist-info/RECORD,,
98
+ dhisana-0.0.1.dev250.dist-info/METADATA,sha256=9bsRxPnqegnPfRGa6sOVugYzcUOSwK1JNSz3SUdzusk,1190
99
+ dhisana-0.0.1.dev250.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
+ dhisana-0.0.1.dev250.dist-info/entry_points.txt,sha256=jujxteZmNI9EkEaK-pOCoWuBujU8TCevdkfl9ZcKHek,49
101
+ dhisana-0.0.1.dev250.dist-info/top_level.txt,sha256=NETTHt6YifG_P7XtRHbQiXZlgSFk9Qh9aR-ng1XTf4s,8
102
+ dhisana-0.0.1.dev250.dist-info/RECORD,,