dhisana 0.0.1.dev265__tar.gz → 0.0.1.dev266__tar.gz

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.
Files changed (121) hide show
  1. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/PKG-INFO +1 -1
  2. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/setup.py +1 -1
  3. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/email_provider.py +3 -0
  4. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/mailgun_tools.py +10 -7
  5. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/sendgrid_tools.py +12 -8
  6. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/PKG-INFO +1 -1
  7. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/README.md +0 -0
  8. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/pyproject.toml +0 -0
  9. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/setup.cfg +0 -0
  10. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/__init__.py +0 -0
  11. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/cli/__init__.py +0 -0
  12. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/cli/cli.py +0 -0
  13. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/cli/datasets.py +0 -0
  14. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/cli/models.py +0 -0
  15. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/cli/predictions.py +0 -0
  16. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/schemas/__init__.py +0 -0
  17. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/schemas/common.py +0 -0
  18. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/schemas/sales.py +0 -0
  19. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/ui/__init__.py +0 -0
  20. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/ui/components.py +0 -0
  21. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/__init__.py +0 -0
  22. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/add_mapping.py +0 -0
  23. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/agent_tools.py +0 -0
  24. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/apollo_tools.py +0 -0
  25. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/assistant_tool_tag.py +0 -0
  26. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/built_with_api_tools.py +0 -0
  27. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/cache_output_tools.py +0 -0
  28. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/cache_output_tools_local.py +0 -0
  29. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/check_email_validity_tools.py +0 -0
  30. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/check_for_intent_signal.py +0 -0
  31. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/check_linkedin_url_validity.py +0 -0
  32. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/clay_tools.py +0 -0
  33. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/clean_properties.py +0 -0
  34. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/company_utils.py +0 -0
  35. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/compose_salesnav_query.py +0 -0
  36. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/compose_search_query.py +0 -0
  37. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/compose_three_step_workflow.py +0 -0
  38. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/composite_tools.py +0 -0
  39. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/dataframe_tools.py +0 -0
  40. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/domain_parser.py +0 -0
  41. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/email_body_utils.py +0 -0
  42. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/email_parse_helpers.py +0 -0
  43. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/enrich_lead_information.py +0 -0
  44. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/extract_email_content_for_llm.py +0 -0
  45. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/fetch_openai_config.py +0 -0
  46. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/field_validators.py +0 -0
  47. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/g2_tools.py +0 -0
  48. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_content.py +0 -0
  49. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_custom_message.py +0 -0
  50. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_email.py +0 -0
  51. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_email_response.py +0 -0
  52. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_flow.py +0 -0
  53. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_leads_salesnav.py +0 -0
  54. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_linkedin_connect_message.py +0 -0
  55. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_linkedin_response_message.py +0 -0
  56. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/generate_structured_output_internal.py +0 -0
  57. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/google_custom_search.py +0 -0
  58. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/google_oauth_tools.py +0 -0
  59. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/google_workspace_tools.py +0 -0
  60. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/hubspot_clearbit.py +0 -0
  61. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/hubspot_crm_tools.py +0 -0
  62. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/instantly_tools.py +0 -0
  63. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/linkedin_crawler.py +0 -0
  64. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/lusha_tools.py +0 -0
  65. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/mailreach_tools.py +0 -0
  66. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/microsoft365_tools.py +0 -0
  67. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openai_assistant_and_file_utils.py +0 -0
  68. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openai_helpers.py +0 -0
  69. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openapi_spec_to_tools.py +0 -0
  70. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openapi_tool/__init__.py +0 -0
  71. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openapi_tool/api_models.py +0 -0
  72. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openapi_tool/convert_openai_spec_to_tool.py +0 -0
  73. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/openapi_tool/openapi_tool.py +0 -0
  74. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/parse_linkedin_messages_txt.py +0 -0
  75. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/profile.py +0 -0
  76. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/proxy_curl_tools.py +0 -0
  77. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/proxycurl_search_leads.py +0 -0
  78. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/python_function_to_tools.py +0 -0
  79. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/research_lead.py +0 -0
  80. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/sales_navigator_crawler.py +0 -0
  81. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/salesforce_crm_tools.py +0 -0
  82. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/search_router.py +0 -0
  83. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/search_router_jobs.py +0 -0
  84. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serarch_router_local_business.py +0 -0
  85. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serpapi_additional_tools.py +0 -0
  86. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serpapi_google_jobs.py +0 -0
  87. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serpapi_google_search.py +0 -0
  88. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serpapi_local_business_search.py +0 -0
  89. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serpapi_search_tools.py +0 -0
  90. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serperdev_google_jobs.py +0 -0
  91. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serperdev_local_business.py +0 -0
  92. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/serperdev_search.py +0 -0
  93. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/smtp_email_tools.py +0 -0
  94. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/test_connect.py +0 -0
  95. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/trasform_json.py +0 -0
  96. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/web_download_parse_tools.py +0 -0
  97. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/workflow_code_model.py +0 -0
  98. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/utils/zoominfo_tools.py +0 -0
  99. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/workflow/__init__.py +0 -0
  100. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/workflow/agent.py +0 -0
  101. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/workflow/flow.py +0 -0
  102. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/workflow/task.py +0 -0
  103. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana/workflow/test.py +0 -0
  104. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/SOURCES.txt +0 -0
  105. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/dependency_links.txt +0 -0
  106. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/entry_points.txt +0 -0
  107. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/requires.txt +0 -0
  108. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/src/dhisana.egg-info/top_level.txt +0 -0
  109. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_agent_tools.py +0 -0
  110. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_apollo_company_search.py +0 -0
  111. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_apollo_lead_search.py +0 -0
  112. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_connectivity.py +0 -0
  113. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_email_body_utils.py +0 -0
  114. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_google_document.py +0 -0
  115. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_hubspot_call_logs.py +0 -0
  116. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_linkedin_serper.py +0 -0
  117. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_mailreach.py +0 -0
  118. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_mcp_connectivity.py +0 -0
  119. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_proxycurl_get_company_search_id.py +0 -0
  120. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_proxycurl_job_count.py +0 -0
  121. {dhisana-0.0.1.dev265 → dhisana-0.0.1.dev266}/tests/test_structured_output_with_mcp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev265
3
+ Version: 0.0.1.dev266
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
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='dhisana',
5
- version='0.0.1-dev265',
5
+ version='0.0.1-dev266',
6
6
  description='A Python SDK for Dhisana AI Platform',
7
7
  author='Admin',
8
8
  author_email='contact@dhisana.ai',
@@ -124,9 +124,12 @@ async def send_email_async(
124
124
 
125
125
  Returns whatever the underlying provider helper returns:
126
126
 
127
+ * Mailgun → str (message-id from Mailgun)
128
+ * SendGrid → str (X-Message-Id from SendGrid)
127
129
  * SMTP → str (Message-ID)
128
130
  * Microsoft 365 → str (message-id)
129
131
  * Google Workspace → str (message-id)
132
+ * Google OAuth → str (message-id)
130
133
  """
131
134
  # ------------------------------------------------------------------ #
132
135
  # 1) Try the preferred providers in order
@@ -1,4 +1,3 @@
1
- import asyncio
2
1
  import logging
3
2
  import os
4
3
  from typing import Optional, List, Dict
@@ -21,7 +20,7 @@ def get_mailgun_notify_key(tool_config: Optional[List[Dict]] = None) -> str:
21
20
  if tool_config:
22
21
  cfg = next((item for item in tool_config if item.get("name") == "mailgun"), None)
23
22
  if cfg:
24
- cfg_map = {i["name"]: i["value"] for i in cfg.get("configuration", []) if i}
23
+ cfg_map = {i.get("name"): i.get("value") for i in cfg.get("configuration", []) if i}
25
24
  key = cfg_map.get("apiKey")
26
25
  key = key or os.getenv("MAILGUN_NOTIFY_KEY")
27
26
  if not key:
@@ -43,7 +42,7 @@ def get_mailgun_notify_domain(tool_config: Optional[List[Dict]] = None) -> str:
43
42
  if tool_config:
44
43
  cfg = next((item for item in tool_config if item.get("name") == "mailgun"), None)
45
44
  if cfg:
46
- cfg_map = {i["name"]: i["value"] for i in cfg.get("configuration", []) if i}
45
+ cfg_map = {i.get("name"): i.get("value") for i in cfg.get("configuration", []) if i}
47
46
  domain = cfg_map.get("domain") or cfg_map.get("notifyDomain")
48
47
  domain = domain or os.getenv("MAILGUN_DOMAIN") or os.getenv("MAILGUN_NOTIFY_DOMAIN")
49
48
  if not domain:
@@ -96,11 +95,15 @@ async def send_email_with_mailgun(
96
95
  # Try to return JSON payload if available
97
96
  try:
98
97
  return await response.json()
99
- except Exception:
98
+ except Exception as parse_ex:
99
+ logging.debug(f"Could not parse Mailgun response as JSON: {parse_ex}")
100
100
  return await response.text()
101
- except Exception as ex:
101
+ except (aiohttp.ClientError, ValueError) as ex:
102
102
  logging.warning(f"Error sending email via Mailgun: {ex}")
103
103
  return {"error": str(ex)}
104
+ except Exception as ex:
105
+ logging.exception(f"Unexpected error sending email via Mailgun: {ex}")
106
+ raise
104
107
 
105
108
 
106
109
  async def send_email_using_mailgun_async(
@@ -147,10 +150,10 @@ async def send_email_using_mailgun_async(
147
150
  raise RuntimeError(f"Mailgun send failed: {detail}")
148
151
  try:
149
152
  payload = await response.json()
150
- except Exception:
153
+ except Exception as parse_ex:
154
+ logging.debug(f"Could not parse Mailgun response as JSON: {parse_ex}")
151
155
  payload = {"message": await response.text()}
152
156
 
153
157
  # Normalise return value akin to other providers
154
158
  msg_id = payload.get("id") if isinstance(payload, dict) else None
155
- await asyncio.sleep(20)
156
159
  return msg_id or str(payload)
@@ -119,13 +119,17 @@ async def send_email_with_sendgrid(
119
119
  headers=headers,
120
120
  json=payload,
121
121
  ) as response:
122
- # SendGrid returns 202 Accepted on success with empty body
122
+ # SendGrid returns 202 Accepted on success with empty body but includes X-Message-Id header
123
123
  if response.status == 202:
124
- return {"status": 202, "message": "accepted"}
124
+ message_id = response.headers.get("X-Message-Id")
125
+ if not message_id:
126
+ logging.warning("SendGrid did not return X-Message-Id header")
127
+ return {"status": 202, "message": "accepted", "message_id": message_id}
125
128
  # On error, try to parse JSON for helpful message
126
129
  try:
127
130
  err = await response.json()
128
- except Exception:
131
+ except Exception as parse_ex:
132
+ logging.debug(f"Could not parse SendGrid error as JSON: {parse_ex}")
129
133
  err = {"text": await response.text()}
130
134
  return {"error": err, "status": response.status}
131
135
  except Exception as ex:
@@ -139,12 +143,8 @@ async def send_email_using_sendgrid_async(
139
143
  ) -> str:
140
144
  """
141
145
  Provider-style wrapper for SendGrid using SendEmailContext.
142
- Returns an opaque token since SendGrid does not return a message id.
146
+ Returns the message ID from SendGrid's X-Message-Id response header.
143
147
  """
144
- plain_body, html_body, _ = body_variants(
145
- ctx.body,
146
- getattr(ctx, "body_format", None),
147
- )
148
148
  result = await send_email_with_sendgrid(
149
149
  sender=f"{ctx.sender_name} <{ctx.sender_email}>",
150
150
  recipients=[ctx.recipient],
@@ -156,6 +156,10 @@ async def send_email_using_sendgrid_async(
156
156
  )
157
157
  # Normalise output to a string id-like value
158
158
  if isinstance(result, dict) and result.get("status") == 202:
159
+ message_id = result.get("message_id")
160
+ if message_id:
161
+ return message_id
162
+ # Fallback if header wasn't present (shouldn't happen)
159
163
  return f"sent:{ctx.sender_email}:{ctx.recipient}:{ctx.subject}"
160
164
  if isinstance(result, dict) and "error" in result:
161
165
  raise RuntimeError(f"SendGrid send failed: {result['error']}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev265
3
+ Version: 0.0.1.dev266
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
File without changes
File without changes