55
66
77FiltersLike = Union [BusinessFilters , Mapping [str , Any ], None ]
8+ EnrichmentsLike = Optional [Union [
9+ dict [str , Union [dict [str , Any ], None , bool ]],
10+ list [str ],
11+ str ,
12+ ]]
813
914
1015class BusinessesAPI :
1116 def __init__ (self , client : OutscraperClient ) -> None :
1217 self ._client = client
1318
1419 def search (self , * , filters : FiltersLike = None , limit : int = 10 , cursor : Optional [str ] = None , include_total : bool = False ,
15- fields : Optional [list [str ]] = None , query : str = '' ) -> BusinessSearchResult :
20+ fields : Optional [list [str ]] = None , enrichments : EnrichmentsLike = None , query : str = '' ) -> BusinessSearchResult :
1621 '''
1722 Retrieve business records with optional enrichment data.
1823
@@ -30,6 +35,19 @@ def search(self, *, filters: FiltersLike = None, limit: int = 10, cursor: Option
3035 include_total (bool): Whether to include the total count of matching records in the response. This could increase response time.
3136 Default: False.
3237 fields (list[str] | None): List of fields to include in the response. If not specified, all fields will be returned.
38+ enrichments (dict | list[str] | str | None): Optional enrichments to apply.
39+ Preferred format is dict with per-enrichment params:
40+ {
41+ "contacts_n_leads": {
42+ "contacts_per_company": 3,
43+ "emails_per_contact": 1,
44+ },
45+ "company_insights": {},
46+ }
47+ Backward-compatible formats are also supported:
48+ - ["contacts_n_leads", "company_insights"]
49+ - "contacts_n_leads"
50+ In those forms, each enrichment is sent with empty params.
3351 query (str): natural language search.
3452
3553 Returns:
@@ -57,6 +75,11 @@ def search(self, *, filters: FiltersLike = None, limit: int = 10, cursor: Option
5775 if fields :
5876 payload ['fields' ] = list (fields )
5977
78+ normalized_enrichments = self ._normalize_enrichments (enrichments = enrichments )
79+
80+ if normalized_enrichments :
81+ payload ['enrichments' ] = normalized_enrichments
82+
6083 if query :
6184 payload ['query' ] = query
6285
@@ -74,7 +97,8 @@ def search(self, *, filters: FiltersLike = None, limit: int = 10, cursor: Option
7497 )
7598
7699 def iter_search (self , * , filters : FiltersLike = None , limit : int = 10 , start_cursor : Optional [str ] = None ,
77- include_total : bool = False , fields : Optional [list [str ]] = None ) -> Iterator [dict ]:
100+ include_total : bool = False , fields : Optional [list [str ]] = None ,
101+ enrichments : EnrichmentsLike = None , query : str = '' ) -> Iterator [dict ]:
78102 '''
79103 Iterate over businesses across all pages (auto-pagination).
80104
@@ -91,6 +115,9 @@ def iter_search(self, *, filters: FiltersLike = None, limit: int = 10, start_cur
91115 include_total (bool): Passed to `search()` (if supported by API).
92116 Default: False.
93117 fields (list[str] | None): Passed to `search()`.
118+ enrichments (dict | list[str] | str | None): Passed to `search()`.
119+ Supports the same formats as `search()`.
120+ query (str): Passed to `search()`.
94121
95122 Yields:
96123 item (dict): Each business record from all pages.
@@ -105,7 +132,9 @@ def iter_search(self, *, filters: FiltersLike = None, limit: int = 10, start_cur
105132 limit = limit ,
106133 cursor = cursor ,
107134 include_total = include_total ,
108- fields = fields )
135+ fields = fields ,
136+ enrichments = enrichments ,
137+ query = query )
109138
110139 for item in business_search_result .items :
111140 yield item
@@ -149,3 +178,50 @@ def get(self, business_id: str, *, fields: Optional[list[str]] = None) -> dict:
149178 raise Exception (f'Unexpected response for /businesses/{ business_id } : { type (data )} ' )
150179
151180 return data
181+
182+ def _normalize_enrichments (self , enrichments : EnrichmentsLike = None ) -> dict [str , dict [str , Any ]]:
183+ normalized_enrichments = {}
184+
185+ if enrichments is None :
186+ return normalized_enrichments
187+
188+ if isinstance (enrichments , str ):
189+ if not enrichments :
190+ raise ValueError ('enrichment name must be a non-empty string' )
191+ normalized_enrichments [enrichments ] = {}
192+
193+ elif isinstance (enrichments , dict ):
194+ for name , params in enrichments .items ():
195+ if not isinstance (name , str ) or not name :
196+ raise ValueError ('enrichment name must be a non-empty string' )
197+
198+ if params is None or params is True :
199+ params = {}
200+ elif params is False :
201+ raise ValueError (f'enrichment "{ name } " cannot be False; omit it instead' )
202+
203+ if not isinstance (params , dict ):
204+ raise ValueError (f'params for enrichment "{ name } " must be a dict, None or True' )
205+
206+ normalized_enrichments [name ] = dict (params )
207+
208+ elif isinstance (enrichments , list ):
209+ for name in enrichments :
210+ if not isinstance (name , str ) or not name :
211+ raise ValueError ('enrichment name must be a non-empty string' )
212+ normalized_enrichments [name ] = {}
213+ else :
214+ raise ValueError ('enrichments must be a dict, list[str], string, or None' )
215+
216+ contacts_n_leads = normalized_enrichments .get ('contacts_n_leads' , {})
217+ if 'contacts_per_company' in contacts_n_leads :
218+ contacts_per_company = contacts_n_leads ['contacts_per_company' ]
219+ if not isinstance (contacts_per_company , int ) or contacts_per_company < 1 :
220+ raise ValueError ('contacts_per_company must be an int >= 1' )
221+
222+ if 'emails_per_contact' in contacts_n_leads :
223+ emails_per_contact = contacts_n_leads ['emails_per_contact' ]
224+ if not isinstance (emails_per_contact , int ) or emails_per_contact < 1 :
225+ raise ValueError ('emails_per_contact must be an int >= 1' )
226+
227+ return normalized_enrichments
0 commit comments