dhisana 0.0.1.dev86__tar.gz → 0.0.1.dev231__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.
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/PKG-INFO +5 -2
- dhisana-0.0.1.dev231/README.md +257 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/setup.py +5 -2
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/schemas/common.py +32 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/schemas/sales.py +221 -23
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/add_mapping.py +72 -63
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/apollo_tools.py +739 -109
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/built_with_api_tools.py +4 -2
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/cache_output_tools.py +23 -23
- dhisana-0.0.1.dev231/src/dhisana/utils/check_email_validity_tools.py +717 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/check_for_intent_signal.py +1 -2
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/check_linkedin_url_validity.py +34 -8
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/clay_tools.py +3 -2
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/clean_properties.py +3 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/compose_salesnav_query.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/compose_search_query.py +7 -3
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/composite_tools.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/dataframe_tools.py +2 -2
- dhisana-0.0.1.dev231/src/dhisana/utils/email_body_utils.py +72 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/email_provider.py +375 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/enrich_lead_information.py +917 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/fetch_openai_config.py +129 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/field_validators.py +1 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/g2_tools.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/generate_content.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/generate_email.py +20 -10
- dhisana-0.0.1.dev231/src/dhisana/utils/generate_email_response.py +465 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/generate_flow.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/generate_linkedin_connect_message.py +19 -6
- dhisana-0.0.1.dev231/src/dhisana/utils/generate_linkedin_response_message.py +317 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/generate_structured_output_internal.py +462 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/google_custom_search.py +267 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/google_oauth_tools.py +675 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/google_workspace_tools.py +340 -17
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/hubspot_clearbit.py +3 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/hubspot_crm_tools.py +771 -167
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/instantly_tools.py +3 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/lusha_tools.py +10 -7
- dhisana-0.0.1.dev231/src/dhisana/utils/mailgun_tools.py +150 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/microsoft365_tools.py +407 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/openai_assistant_and_file_utils.py +267 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openai_helpers.py +19 -16
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/parse_linkedin_messages_txt.py +2 -3
- dhisana-0.0.1.dev231/src/dhisana/utils/profile.py +37 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/proxy_curl_tools.py +430 -195
- dhisana-0.0.1.dev231/src/dhisana/utils/proxycurl_search_leads.py +426 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/research_lead.py +176 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/sales_navigator_crawler.py +1 -6
- dhisana-0.0.1.dev231/src/dhisana/utils/salesforce_crm_tools.py +477 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/search_router.py +131 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/search_router_jobs.py +51 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/sendgrid_tools.py +152 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serarch_router_local_business.py +75 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serpapi_additional_tools.py +290 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serpapi_google_jobs.py +117 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serpapi_google_search.py +188 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serpapi_local_business_search.py +129 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/serpapi_search_tools.py +363 -432
- dhisana-0.0.1.dev231/src/dhisana/utils/serperdev_google_jobs.py +125 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serperdev_local_business.py +154 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/serperdev_search.py +233 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/smtp_email_tools.py +483 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/test_connect.py +1669 -0
- dhisana-0.0.1.dev231/src/dhisana/utils/trasform_json.py +173 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/web_download_parse_tools.py +0 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/zoominfo_tools.py +2 -3
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/workflow/test.py +1 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/PKG-INFO +5 -2
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/SOURCES.txt +31 -1
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/requires.txt +3 -0
- dhisana-0.0.1.dev231/tests/test_apollo_company_search.py +216 -0
- dhisana-0.0.1.dev231/tests/test_apollo_lead_search.py +119 -0
- dhisana-0.0.1.dev231/tests/test_connectivity.py +102 -0
- dhisana-0.0.1.dev231/tests/test_email_body_utils.py +23 -0
- dhisana-0.0.1.dev231/tests/test_google_document.py +119 -0
- dhisana-0.0.1.dev231/tests/test_hubspot_call_logs.py +79 -0
- dhisana-0.0.1.dev231/tests/test_linkedin_serper.py +55 -0
- dhisana-0.0.1.dev231/tests/test_mcp_connectivity.py +28 -0
- dhisana-0.0.1.dev231/tests/test_proxycurl_get_company_search_id.py +170 -0
- dhisana-0.0.1.dev231/tests/test_proxycurl_job_count.py +61 -0
- dhisana-0.0.1.dev231/tests/test_structured_output_with_mcp.py +56 -0
- dhisana-0.0.1.dev86/README.md +0 -141
- dhisana-0.0.1.dev86/src/dhisana/utils/check_email_validity_tools.py +0 -719
- dhisana-0.0.1.dev86/src/dhisana/utils/enrich_lead_information.py +0 -433
- dhisana-0.0.1.dev86/src/dhisana/utils/generate_email_response.py +0 -208
- dhisana-0.0.1.dev86/src/dhisana/utils/generate_linkedin_response_message.py +0 -226
- dhisana-0.0.1.dev86/src/dhisana/utils/generate_structured_output_internal.py +0 -256
- dhisana-0.0.1.dev86/src/dhisana/utils/google_custom_search.py +0 -161
- dhisana-0.0.1.dev86/src/dhisana/utils/openai_assistant_and_file_utils.py +0 -323
- dhisana-0.0.1.dev86/src/dhisana/utils/research_lead.py +0 -123
- dhisana-0.0.1.dev86/src/dhisana/utils/salesforce_crm_tools.py +0 -204
- dhisana-0.0.1.dev86/src/dhisana/utils/sendgrid_tools.py +0 -117
- dhisana-0.0.1.dev86/src/dhisana/utils/test_connect.py +0 -344
- dhisana-0.0.1.dev86/src/dhisana/utils/trasform_json.py +0 -94
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/pyproject.toml +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/setup.cfg +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/cli/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/cli/cli.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/cli/datasets.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/cli/models.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/cli/predictions.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/schemas/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/ui/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/ui/components.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/agent_tools.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/assistant_tool_tag.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/cache_output_tools_local.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/company_utils.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/compose_three_step_workflow.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/domain_parser.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/email_parse_helpers.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/extract_email_content_for_llm.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/generate_leads_salesnav.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/linkedin_crawler.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openapi_spec_to_tools.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openapi_tool/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openapi_tool/api_models.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openapi_tool/convert_openai_spec_to_tool.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/openapi_tool/openapi_tool.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/python_function_to_tools.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/utils/workflow_code_model.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/workflow/__init__.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/workflow/agent.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/workflow/flow.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana/workflow/task.py +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/dependency_links.txt +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/entry_points.txt +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/src/dhisana.egg-info/top_level.txt +0 -0
- {dhisana-0.0.1.dev86 → dhisana-0.0.1.dev231}/tests/test_agent_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: dhisana
|
|
3
|
-
Version: 0.0.1.
|
|
3
|
+
Version: 0.0.1.dev231
|
|
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
|
|
@@ -30,6 +30,9 @@ Requires-Dist: hubspot-api-client
|
|
|
30
30
|
Requires-Dist: tldextract
|
|
31
31
|
Requires-Dist: pyperclip
|
|
32
32
|
Requires-Dist: azure-storage-blob
|
|
33
|
+
Requires-Dist: email_validator
|
|
34
|
+
Requires-Dist: fqdn
|
|
35
|
+
Requires-Dist: json_repair
|
|
33
36
|
Dynamic: author
|
|
34
37
|
Dynamic: author-email
|
|
35
38
|
Dynamic: classifier
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Dhisana Python SDK
|
|
2
|
+
|
|
3
|
+
A Python SDK for interacting with Dhisana AI services.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install dhisana
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from dhisana.utils.agent_tools import (
|
|
15
|
+
search_google_maps,
|
|
16
|
+
enrich_people_with_apollo,
|
|
17
|
+
search_google,
|
|
18
|
+
search_google_jobs,
|
|
19
|
+
search_google_news,
|
|
20
|
+
get_html_content_from_url,
|
|
21
|
+
parse_html_content,
|
|
22
|
+
extract_image_links,
|
|
23
|
+
extract_head_section_from_html_content,
|
|
24
|
+
get_email_if_exists,
|
|
25
|
+
search_crunchbase,
|
|
26
|
+
search_people_with_apollo,
|
|
27
|
+
search_companies_with_apollo,
|
|
28
|
+
enrich_company_with_apollo,
|
|
29
|
+
get_job_postings_from_apollo
|
|
30
|
+
)
|
|
31
|
+
# Your code here
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Steps to Create and Publish the Package
|
|
35
|
+
|
|
36
|
+
### Ensure you have the latest versions of setuptools and wheel
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install --upgrade setuptools wheel
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Build the Package
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Upload to PyPI
|
|
49
|
+
|
|
50
|
+
First, install twine:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install --upgrade build twine
|
|
54
|
+
python -m build
|
|
55
|
+
pip install twine
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Then upload your package (you'll need a PyPI account)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
twine upload dist/\*
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Install the Package Locally for Testing
|
|
65
|
+
|
|
66
|
+
You can install the package locally to test it before uploading:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install -e .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The -e flag installs the package in editable mode, which is useful during development.
|
|
73
|
+
|
|
74
|
+
## Run Tests
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install pytest
|
|
78
|
+
pytest tests/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Using the Package in Other Projects
|
|
82
|
+
|
|
83
|
+
Once your package is published to PyPI, other users can install it using:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install dhisana
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
They can then import your SDK as:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
from dhisana.utils.agent_tools import (
|
|
93
|
+
search_google_maps,
|
|
94
|
+
enrich_people_with_apollo,
|
|
95
|
+
search_google,
|
|
96
|
+
search_google_jobs,
|
|
97
|
+
search_google_news,
|
|
98
|
+
get_html_content_from_url,
|
|
99
|
+
parse_html_content,
|
|
100
|
+
extract_image_links,
|
|
101
|
+
extract_head_section_from_html_content,
|
|
102
|
+
get_email_if_exists,
|
|
103
|
+
search_crunchbase,
|
|
104
|
+
search_people_with_apollo,
|
|
105
|
+
search_companies_with_apollo,
|
|
106
|
+
enrich_company_with_apollo,
|
|
107
|
+
get_job_postings_from_apollo
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Use the functionalities provided by your SDK
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### To use locally
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install -e /path/to/other/project
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### To use CLI
|
|
120
|
+
|
|
121
|
+
You can use the CLI provided by the Dhisana AI SDK. To see the available commands and options, use:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
dhisana --help
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This will display:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
Usage: dhisana [OPTIONS] COMMAND [ARGS]...
|
|
131
|
+
|
|
132
|
+
Dhisana AI SDK CLI.
|
|
133
|
+
|
|
134
|
+
Options:
|
|
135
|
+
--help Show this message and exit.
|
|
136
|
+
|
|
137
|
+
Commands:
|
|
138
|
+
dataset-cli Commands for managing datasets.
|
|
139
|
+
model-cli Commands for managing models.
|
|
140
|
+
prediction-cli Commands for running predictions.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Proxycurl Job Leads Example
|
|
144
|
+
|
|
145
|
+
Set `PROXY_CURL_API_KEY` in your environment before running functions that call Proxycurl.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
export PROXY_CURL_API_KEY=your_api_key
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Example usage to search for SDR roles and retrieve hiring manager leads:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import asyncio
|
|
155
|
+
from dhisana.utils.proxy_curl_tools import find_leads_by_job_openings_proxy_curl
|
|
156
|
+
|
|
157
|
+
async def main():
|
|
158
|
+
leads = await find_leads_by_job_openings_proxy_curl(
|
|
159
|
+
{"job_title": "SDR", "location": "United States"},
|
|
160
|
+
hiring_manager_roles=["VP of Sales", "Head of Sales"],
|
|
161
|
+
)
|
|
162
|
+
print(leads)
|
|
163
|
+
|
|
164
|
+
asyncio.run(main())
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Proxycurl Job Search Example
|
|
168
|
+
|
|
169
|
+
Use `proxycurl_job_search` to list jobs posted by a company. Parameters mirror
|
|
170
|
+
Proxycurl's job search endpoint.
|
|
171
|
+
|
|
172
|
+
### Parameters
|
|
173
|
+
|
|
174
|
+
- `job_type` – one of `full-time`, `part-time`, `contract`, `internship`,
|
|
175
|
+
`temporary`, `volunteer`, or `anything`.
|
|
176
|
+
- `experience_level` – `internship`, `entry_level`, `associate`,
|
|
177
|
+
`mid_senior_level`, `director`, or `anything`.
|
|
178
|
+
- `when` – posted time such as `yesterday`, `past-week`, `past-month`, or
|
|
179
|
+
`anytime`.
|
|
180
|
+
- `flexibility` – `remote`, `on-site`, `hybrid`, or `anything`.
|
|
181
|
+
- `geo_id` – location identifier, e.g. `92000000` for worldwide.
|
|
182
|
+
- `keyword` – keyword to match in the job title.
|
|
183
|
+
- `search_id` – company search identifier from the Company Profile API.
|
|
184
|
+
|
|
185
|
+
Example usage:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
import asyncio
|
|
189
|
+
from dhisana.utils.proxycurl_search_leads import JobSearchParams, proxycurl_job_search
|
|
190
|
+
|
|
191
|
+
async def main():
|
|
192
|
+
jobs = await proxycurl_job_search(
|
|
193
|
+
JobSearchParams(
|
|
194
|
+
search_id="2790400",
|
|
195
|
+
keyword="engineer",
|
|
196
|
+
job_type="full-time",
|
|
197
|
+
experience_level="mid_senior_level",
|
|
198
|
+
when="past-month",
|
|
199
|
+
flexibility="remote",
|
|
200
|
+
geo_id=92000000,
|
|
201
|
+
),
|
|
202
|
+
max_entries=2,
|
|
203
|
+
)
|
|
204
|
+
print(jobs)
|
|
205
|
+
|
|
206
|
+
asyncio.run(main())
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Proxycurl Get Company Search ID Example
|
|
210
|
+
|
|
211
|
+
Use `proxycurl_get_company_search_id` to retrieve a company's search ID, which is required for other Proxycurl operations like job searches. This function calls Proxycurl's Company Profile endpoint.
|
|
212
|
+
|
|
213
|
+
### Function Parameters
|
|
214
|
+
|
|
215
|
+
- `company_url` – LinkedIn company profile URL (e.g., `https://www.linkedin.com/company/microsoft/`)
|
|
216
|
+
- `tool_config` – Optional tool configuration containing API key
|
|
217
|
+
|
|
218
|
+
### Return Value
|
|
219
|
+
|
|
220
|
+
Returns a dictionary with:
|
|
221
|
+
|
|
222
|
+
- `search_id` – The company's search ID (required for job operations)
|
|
223
|
+
- `name` – Company name
|
|
224
|
+
- `linkedin_internal_id` – LinkedIn's internal company ID
|
|
225
|
+
- `industry` – Company industry
|
|
226
|
+
- `company_url` – The original URL provided
|
|
227
|
+
- `error` – Error message (if any errors occurred)
|
|
228
|
+
|
|
229
|
+
Example usage:
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
import asyncio
|
|
233
|
+
from dhisana.utils.proxycurl_search_leads import (
|
|
234
|
+
proxycurl_get_company_search_id,
|
|
235
|
+
proxycurl_job_count,
|
|
236
|
+
JobSearchParams
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
async def main():
|
|
240
|
+
# Get company search ID
|
|
241
|
+
company_result = await proxycurl_get_company_search_id(
|
|
242
|
+
"https://www.linkedin.com/company/microsoft/"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
if company_result.get("search_id"):
|
|
246
|
+
print(f"Company: {company_result['name']}")
|
|
247
|
+
print(f"Search ID: {company_result['search_id']}")
|
|
248
|
+
|
|
249
|
+
# Use the search ID for job operations
|
|
250
|
+
job_params = JobSearchParams(search_id=company_result["search_id"])
|
|
251
|
+
job_count = await proxycurl_job_count(job_params)
|
|
252
|
+
print(f"Total jobs: {job_count.get('count', 0)}")
|
|
253
|
+
else:
|
|
254
|
+
print(f"Error: {company_result.get('error')}")
|
|
255
|
+
|
|
256
|
+
asyncio.run(main())
|
|
257
|
+
```
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='dhisana',
|
|
5
|
-
version='0.0.1-
|
|
5
|
+
version='0.0.1-dev231',
|
|
6
6
|
description='A Python SDK for Dhisana AI Platform',
|
|
7
7
|
author='Admin',
|
|
8
8
|
author_email='contact@dhisana.ai',
|
|
@@ -29,7 +29,10 @@ setup(
|
|
|
29
29
|
'hubspot-api-client',
|
|
30
30
|
'tldextract',
|
|
31
31
|
'pyperclip',
|
|
32
|
-
'azure-storage-blob'
|
|
32
|
+
'azure-storage-blob',
|
|
33
|
+
'email_validator',
|
|
34
|
+
'fqdn',
|
|
35
|
+
'json_repair'
|
|
33
36
|
],
|
|
34
37
|
entry_points={
|
|
35
38
|
'console_scripts': [
|
|
@@ -363,3 +363,35 @@ class Integration(IntegrationBase):
|
|
|
363
363
|
|
|
364
364
|
Integration.model_rebuild()
|
|
365
365
|
IntegrationUpdate.model_rebuild()
|
|
366
|
+
|
|
367
|
+
class BodyFormat(str, Enum):
|
|
368
|
+
AUTO = "auto"
|
|
369
|
+
HTML = "html"
|
|
370
|
+
TEXT = "text"
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class SendEmailContext(BaseModel):
|
|
374
|
+
recipient: str
|
|
375
|
+
subject: str
|
|
376
|
+
body: str
|
|
377
|
+
sender_name: str
|
|
378
|
+
sender_email: str
|
|
379
|
+
labels: Optional[List[str]]
|
|
380
|
+
body_format: BodyFormat = BodyFormat.AUTO
|
|
381
|
+
|
|
382
|
+
class QueryEmailContext(BaseModel):
|
|
383
|
+
start_time: str
|
|
384
|
+
end_time: str
|
|
385
|
+
sender_email: str
|
|
386
|
+
unread_only: bool = True
|
|
387
|
+
labels: Optional[List[str]] = None
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class ReplyEmailContext(BaseModel):
|
|
391
|
+
message_id: str
|
|
392
|
+
reply_body: str
|
|
393
|
+
sender_email: str
|
|
394
|
+
sender_name: str
|
|
395
|
+
mark_as_read: str = "True"
|
|
396
|
+
add_labels: Optional[List[str]] = None
|
|
397
|
+
reply_body_format: BodyFormat = BodyFormat.AUTO
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
1
3
|
from uuid import UUID
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
4
|
+
from pydantic import BaseModel, Field, field_validator
|
|
3
5
|
from typing import List, Optional, Dict, Any
|
|
4
6
|
from enum import Enum
|
|
5
7
|
from typing import Optional, List, Dict, Literal
|
|
6
8
|
|
|
7
|
-
from dhisana.schemas.common import User
|
|
8
9
|
|
|
9
10
|
# -----------------------------
|
|
10
11
|
# Lead-List-Specific Schemas
|
|
11
12
|
# -----------------------------
|
|
12
13
|
|
|
13
14
|
class Lead(BaseModel):
|
|
14
|
-
id: Optional[
|
|
15
|
+
id: Optional[UUID] = None
|
|
15
16
|
full_name: Optional[str] = None
|
|
16
17
|
first_name: Optional[str] = None
|
|
17
18
|
last_name: Optional[str] = None
|
|
18
19
|
email: Optional[str] = None
|
|
19
20
|
user_linkedin_url: Optional[str] = None
|
|
20
21
|
user_linkedin_salesnav_url: Optional[str] = None
|
|
22
|
+
organization_linkedin_url: Optional[str] = None
|
|
23
|
+
organization_linkedin_salesnav_url: Optional[str] = None
|
|
24
|
+
linkedin_follower_count: Optional[int] = None
|
|
21
25
|
primary_domain_of_organization: Optional[str] = None
|
|
26
|
+
twitter_handle: Optional[str] = None
|
|
27
|
+
twitch_handle: Optional[str] = None
|
|
28
|
+
github_handle: Optional[str] = None
|
|
22
29
|
job_title: Optional[str] = None
|
|
23
30
|
phone: Optional[str] = None
|
|
24
31
|
headline: Optional[str] = None
|
|
@@ -26,25 +33,69 @@ class Lead(BaseModel):
|
|
|
26
33
|
organization_name: Optional[str] = None
|
|
27
34
|
organization_website: Optional[str] = None
|
|
28
35
|
summary_about_lead: Optional[str] = None
|
|
36
|
+
|
|
37
|
+
qualification_score: Optional[float] = None
|
|
38
|
+
qualification_reason: Optional[str] = None
|
|
39
|
+
revenue: Optional[str] = None
|
|
40
|
+
company_size: Optional[str] = None
|
|
41
|
+
industry: Optional[str] = None
|
|
42
|
+
|
|
43
|
+
keywords: Optional[Any] = None
|
|
44
|
+
tags: List[str] = []
|
|
45
|
+
notes: List[str] = []
|
|
46
|
+
additional_properties: Optional[Dict[str, Any]] = {}
|
|
29
47
|
workflow_stage: Optional[str] = None
|
|
30
|
-
|
|
31
|
-
engaged:
|
|
48
|
+
|
|
49
|
+
engaged: bool = False
|
|
32
50
|
last_contact: Optional[int] = None
|
|
33
|
-
additional_properties: Optional[Dict[str, str]] = None
|
|
34
51
|
research_summary: Optional[str] = None
|
|
35
52
|
task_ids: Optional[List[str]] = None
|
|
36
|
-
email_validation_status: Optional[
|
|
37
|
-
|
|
38
|
-
] = None
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
email_validation_status: Optional[str] = None
|
|
54
|
+
linkedin_validation_status: Optional[str] = None
|
|
55
|
+
research_status: Optional[str] = None
|
|
56
|
+
enchrichment_status: Optional[str] = None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@field_validator("linkedin_follower_count", mode="before")
|
|
60
|
+
@classmethod
|
|
61
|
+
def parse_linkedin_follower_count(cls, v):
|
|
62
|
+
if v is None or v == "":
|
|
63
|
+
return None
|
|
64
|
+
if isinstance(v, str):
|
|
65
|
+
v = v.strip()
|
|
66
|
+
if v == "":
|
|
67
|
+
return None
|
|
68
|
+
try:
|
|
69
|
+
return int(v)
|
|
70
|
+
except ValueError:
|
|
71
|
+
raise ValueError("linkedin_follower_count must be an integer")
|
|
72
|
+
return v
|
|
73
|
+
|
|
74
|
+
@field_validator("notes", mode="before")
|
|
75
|
+
@classmethod
|
|
76
|
+
def ensure_notes_list(cls, v):
|
|
77
|
+
"""Coerce notes to a list of strings.
|
|
78
|
+
Handles legacy cases where the DB may contain a scalar or JSON string.
|
|
79
|
+
"""
|
|
80
|
+
if v is None:
|
|
81
|
+
return []
|
|
82
|
+
if isinstance(v, list):
|
|
83
|
+
# Ensure all elements are strings
|
|
84
|
+
return [str(item) if not isinstance(item, str) else item for item in v]
|
|
85
|
+
if isinstance(v, str):
|
|
86
|
+
# Try to parse JSON array; if not, wrap as single-note list
|
|
87
|
+
try:
|
|
88
|
+
parsed = json.loads(v)
|
|
89
|
+
if isinstance(parsed, list):
|
|
90
|
+
return [str(item) if not isinstance(item, str) else item for item in parsed]
|
|
91
|
+
except Exception:
|
|
92
|
+
pass
|
|
93
|
+
return [v]
|
|
94
|
+
# Fallback: wrap any other scalar/object as a single string entry
|
|
95
|
+
try:
|
|
96
|
+
return [json.dumps(v)]
|
|
97
|
+
except Exception:
|
|
98
|
+
return [str(v)]
|
|
48
99
|
|
|
49
100
|
|
|
50
101
|
class LeadList(BaseModel):
|
|
@@ -243,6 +294,7 @@ class MessageGenerationInstructions(BaseModel):
|
|
|
243
294
|
"""
|
|
244
295
|
instructions_to_generate_message: Optional[str] = None
|
|
245
296
|
prompt_engineering_guidance: Optional[PromptEngineeringGuidance] = None
|
|
297
|
+
use_cache: Optional[bool] = True
|
|
246
298
|
|
|
247
299
|
class CampaignContext(BaseModel):
|
|
248
300
|
"""
|
|
@@ -272,6 +324,10 @@ class MessageItem(BaseModel):
|
|
|
272
324
|
...,
|
|
273
325
|
description="Unique identifier for the message"
|
|
274
326
|
)
|
|
327
|
+
thread_id: str = Field(
|
|
328
|
+
...,
|
|
329
|
+
description="Unique identifier for the conversation thread"
|
|
330
|
+
)
|
|
275
331
|
sender_name: str = Field(
|
|
276
332
|
...,
|
|
277
333
|
description="Sender's display name (if available)"
|
|
@@ -300,6 +356,7 @@ class MessageItem(BaseModel):
|
|
|
300
356
|
...,
|
|
301
357
|
description="Body of the message in plain text"
|
|
302
358
|
)
|
|
359
|
+
html_body: Optional[str] = None
|
|
303
360
|
|
|
304
361
|
class MessageResponse(BaseModel):
|
|
305
362
|
"""
|
|
@@ -435,14 +492,14 @@ class HubSpotLeadInformation(BaseModel):
|
|
|
435
492
|
organization_name: str = Field("", description="Current Company where lead works")
|
|
436
493
|
organization_website: str = Field("", description="Current Company website of the lead")
|
|
437
494
|
organization_linkedin_url : str = Field("", description="Company LinkedIn URL")
|
|
438
|
-
additional_properties: Optional[Dict[str,
|
|
495
|
+
additional_properties: Optional[Dict[str, Any]] = None
|
|
439
496
|
|
|
440
497
|
class HubSpotCompanyinformation(BaseModel):
|
|
441
498
|
primary_domain_of_organization: str = Field("", description="Primary domain of the organization")
|
|
442
499
|
organization_name: str = Field("", description="Current Company where lead works")
|
|
443
500
|
organization_website: str = Field("", description="Current Company website of the lead")
|
|
444
501
|
organization_linkedin_url : str = Field("", description="Company LinkedIn URL")
|
|
445
|
-
additional_properties: Optional[Dict[str,
|
|
502
|
+
additional_properties: Optional[Dict[str, Any]] = None
|
|
446
503
|
|
|
447
504
|
|
|
448
505
|
# --------------------------------------------------------------------
|
|
@@ -459,6 +516,7 @@ HUBSPOT_TO_LEAD_MAPPING = {
|
|
|
459
516
|
"address": "lead_location", # You can choose "city", "state", etc. if you prefer
|
|
460
517
|
"city": "lead_location",
|
|
461
518
|
"domain": "primary_domain_of_organization",
|
|
519
|
+
"hs_linkedin_url": "user_linkedin_url",
|
|
462
520
|
}
|
|
463
521
|
|
|
464
522
|
class SmartListStatus(str, Enum):
|
|
@@ -478,6 +536,12 @@ class SmartListSourceType(str, Enum):
|
|
|
478
536
|
CSV = "CSV"
|
|
479
537
|
GOOGLE_SHEETS = "GOOGLE_SHEETS"
|
|
480
538
|
CUSTOM_WEBSITE = "CUSTOM_WEBSITE"
|
|
539
|
+
GITHUB = "GITHUB"
|
|
540
|
+
ICP_SEARCH = "ICP_SEARCH"
|
|
541
|
+
LOCAL_BUSINESS = "LOCAL_BUSINESS"
|
|
542
|
+
GOOGLE_JOBS = "GOOGLE_JOBS"
|
|
543
|
+
WEBHOOK = "WEBHOOK"
|
|
544
|
+
GOOGLE_CUSTOM_SITE_SEARCH = "GOOGLE_CUSTOM_SITE_SEARCH"
|
|
481
545
|
|
|
482
546
|
class SourceConfiguration(BaseModel):
|
|
483
547
|
"""
|
|
@@ -494,6 +558,15 @@ class SourceConfiguration(BaseModel):
|
|
|
494
558
|
file_path: Optional[str] = None
|
|
495
559
|
# For Google Sheets
|
|
496
560
|
source_url: Optional[str] = None
|
|
561
|
+
# For Github
|
|
562
|
+
github_search_query: Optional[str] = None
|
|
563
|
+
github_max_repos: Optional[int] = None
|
|
564
|
+
github_max_contributors: Optional[int] = None
|
|
565
|
+
|
|
566
|
+
# Custom website inputs
|
|
567
|
+
custom_instructions_for_doing_pagination: Optional[str] = None
|
|
568
|
+
custom_instructions_for_data_extraction_from_page: Optional[str] = None
|
|
569
|
+
custom_instruction_to_fetch_details_page: Optional[str] = None
|
|
497
570
|
|
|
498
571
|
class SmartListSource(BaseModel):
|
|
499
572
|
"""
|
|
@@ -555,6 +628,8 @@ class SmartListLead(BaseModel):
|
|
|
555
628
|
organization_linkedin_url: Optional[str] = None
|
|
556
629
|
organization_linkedin_salesnav_url: Optional[str] = None
|
|
557
630
|
primary_domain_of_organization: Optional[str] = None
|
|
631
|
+
twitter_handle: Optional[str] = None
|
|
632
|
+
github_handle: Optional[str] = None
|
|
558
633
|
job_title: Optional[str] = None
|
|
559
634
|
phone: Optional[str] = None
|
|
560
635
|
headline: Optional[str] = None
|
|
@@ -562,13 +637,18 @@ class SmartListLead(BaseModel):
|
|
|
562
637
|
organization_name: Optional[str] = None
|
|
563
638
|
organization_website: Optional[str] = None
|
|
564
639
|
summary_about_lead: Optional[str] = None
|
|
565
|
-
keywords: Optional[
|
|
566
|
-
additional_properties: Optional[Dict[str,
|
|
640
|
+
keywords: Optional[Any] = None
|
|
641
|
+
additional_properties: Optional[Dict[str, Any]] = None
|
|
567
642
|
research_summary: Optional[str] = None
|
|
568
643
|
|
|
569
644
|
qualification_score: Optional[float] = None
|
|
570
645
|
qualification_reason: Optional[str] = None
|
|
571
646
|
source: Optional[str] = None
|
|
647
|
+
|
|
648
|
+
email_validation_status: Optional[str] = None
|
|
649
|
+
linkedin_validation_status: Optional[str] = None
|
|
650
|
+
research_status: Optional[str] = None
|
|
651
|
+
enchrichment_status: Optional[str] = None
|
|
572
652
|
|
|
573
653
|
agent_instance_id: Optional[UUID] = None
|
|
574
654
|
organization_id: Optional[UUID] = None
|
|
@@ -576,7 +656,10 @@ class SmartListLead(BaseModel):
|
|
|
576
656
|
created_at: Optional[int] = None
|
|
577
657
|
updated_by: Optional[UUID] = None
|
|
578
658
|
updated_at: Optional[int] = None
|
|
579
|
-
|
|
659
|
+
|
|
660
|
+
revenue: Optional[str] = None
|
|
661
|
+
company_size: Optional[str] = None
|
|
662
|
+
industry: Optional[str] = None
|
|
580
663
|
class Config:
|
|
581
664
|
from_attributes = True
|
|
582
665
|
|
|
@@ -741,3 +824,118 @@ class LeadsQueryFilters(BaseModel):
|
|
|
741
824
|
description="Ranges for organization number of employees."
|
|
742
825
|
)
|
|
743
826
|
|
|
827
|
+
|
|
828
|
+
class CompanyQueryFilters(BaseModel):
|
|
829
|
+
"""
|
|
830
|
+
Defines the filter parameters for querying companies/organizations in the Apollo database.
|
|
831
|
+
All fields are optional and default to None if not specified by user.
|
|
832
|
+
"""
|
|
833
|
+
|
|
834
|
+
# Core company search parameters
|
|
835
|
+
organization_locations: Optional[List[str]] = Field(
|
|
836
|
+
default=None,
|
|
837
|
+
description="List of organization headquarters locations (city, state, country)."
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
organization_num_employees_ranges: Optional[List[str]] = Field(
|
|
841
|
+
default=None,
|
|
842
|
+
description="Employee count ranges, e.g. ['1,10', '11,50', '51,200']. Use specific ranges."
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
min_employees: Optional[int] = Field(
|
|
846
|
+
default=None,
|
|
847
|
+
description="Minimum number of employees (>=1). Internally converted to a numeric range."
|
|
848
|
+
)
|
|
849
|
+
|
|
850
|
+
max_employees: Optional[int] = Field(
|
|
851
|
+
default=None,
|
|
852
|
+
description="Maximum number of employees (<=100000). Internally converted to a numeric range."
|
|
853
|
+
)
|
|
854
|
+
|
|
855
|
+
organization_industries: Optional[List[str]] = Field(
|
|
856
|
+
default=None,
|
|
857
|
+
description="List of organization industries."
|
|
858
|
+
)
|
|
859
|
+
|
|
860
|
+
organization_industry_tag_ids: Optional[List[str]] = Field(
|
|
861
|
+
default=None,
|
|
862
|
+
description="List of industry tag IDs, e.g. ['5567cd4773696439b10b0000']."
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
# Revenue filters
|
|
866
|
+
revenue_range_min: Optional[int] = Field(
|
|
867
|
+
default=None,
|
|
868
|
+
description="Minimum company revenue in USD."
|
|
869
|
+
)
|
|
870
|
+
|
|
871
|
+
revenue_range_max: Optional[int] = Field(
|
|
872
|
+
default=None,
|
|
873
|
+
description="Maximum company revenue in USD."
|
|
874
|
+
)
|
|
875
|
+
|
|
876
|
+
# Funding and growth
|
|
877
|
+
organization_latest_funding_stage_cd: Optional[List[str]] = Field(
|
|
878
|
+
default=None,
|
|
879
|
+
description="List of funding stage codes, e.g. ['2', '3', '10']."
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
# Technology and keywords
|
|
883
|
+
currently_using_any_of_technology_uids: Optional[List[str]] = Field(
|
|
884
|
+
default=None,
|
|
885
|
+
description="Technology UIDs used by the organization, e.g. ['google_font_api']."
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
q_keywords: Optional[str] = Field(
|
|
889
|
+
default=None,
|
|
890
|
+
description="Keywords to search for in company descriptions, names, etc."
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
q_organization_domains: Optional[List[str]] = Field(
|
|
894
|
+
default=None,
|
|
895
|
+
description="Specific company domains to search for, e.g. ['microsoft.com', 'google.com']."
|
|
896
|
+
)
|
|
897
|
+
|
|
898
|
+
# Company-specific filters
|
|
899
|
+
organization_ids: Optional[List[str]] = Field(
|
|
900
|
+
default=None,
|
|
901
|
+
description="Specific Apollo organization IDs to include."
|
|
902
|
+
)
|
|
903
|
+
|
|
904
|
+
not_organization_ids: Optional[List[str]] = Field(
|
|
905
|
+
default=None,
|
|
906
|
+
description="Apollo organization IDs to exclude from results."
|
|
907
|
+
)
|
|
908
|
+
|
|
909
|
+
# Search lists
|
|
910
|
+
q_organization_search_list_id: Optional[str] = Field(
|
|
911
|
+
default=None,
|
|
912
|
+
description="Include only organizations in a specific search list."
|
|
913
|
+
)
|
|
914
|
+
|
|
915
|
+
q_not_organization_search_list_id: Optional[str] = Field(
|
|
916
|
+
default=None,
|
|
917
|
+
description="Exclude organizations in a specific search list."
|
|
918
|
+
)
|
|
919
|
+
|
|
920
|
+
# Sorting
|
|
921
|
+
sort_by_field: Optional[str] = Field(
|
|
922
|
+
default=None,
|
|
923
|
+
description="Sort field, e.g. 'name', 'employee_count', 'last_updated', etc."
|
|
924
|
+
)
|
|
925
|
+
|
|
926
|
+
sort_ascending: Optional[bool] = Field(
|
|
927
|
+
default=None,
|
|
928
|
+
description="Sort ascending (True) or descending (False)."
|
|
929
|
+
)
|
|
930
|
+
|
|
931
|
+
# Additional filters that might be useful
|
|
932
|
+
organization_founded_year_min: Optional[int] = Field(
|
|
933
|
+
default=None,
|
|
934
|
+
description="Minimum founding year for the organization."
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
organization_founded_year_max: Optional[int] = Field(
|
|
938
|
+
default=None,
|
|
939
|
+
description="Maximum founding year for the organization."
|
|
940
|
+
)
|
|
941
|
+
|