blitz-api-py 0.1.0__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.
Files changed (40) hide show
  1. blitz_api/__init__.py +65 -0
  2. blitz_api/_base_client.py +191 -0
  3. blitz_api/_client.py +13 -0
  4. blitz_api/_client_async.py +143 -0
  5. blitz_api/_client_sync.py +145 -0
  6. blitz_api/_compat.py +26 -0
  7. blitz_api/_constants.py +36 -0
  8. blitz_api/_exceptions.py +113 -0
  9. blitz_api/_pagination_async.py +128 -0
  10. blitz_api/_pagination_base.py +52 -0
  11. blitz_api/_pagination_sync.py +130 -0
  12. blitz_api/_rate_limit.py +14 -0
  13. blitz_api/_rate_limit_async.py +67 -0
  14. blitz_api/_rate_limit_sync.py +69 -0
  15. blitz_api/_version.py +1 -0
  16. blitz_api/py.typed +0 -0
  17. blitz_api/resources/__init__.py +27 -0
  18. blitz_api/resources/_async/__init__.py +1 -0
  19. blitz_api/resources/_async/account.py +27 -0
  20. blitz_api/resources/_async/enrichment.py +116 -0
  21. blitz_api/resources/_async/search.py +153 -0
  22. blitz_api/resources/_async/utils.py +43 -0
  23. blitz_api/resources/_sync/__init__.py +3 -0
  24. blitz_api/resources/_sync/account.py +29 -0
  25. blitz_api/resources/_sync/enrichment.py +118 -0
  26. blitz_api/resources/_sync/search.py +155 -0
  27. blitz_api/resources/_sync/utils.py +45 -0
  28. blitz_api/types/__init__.py +108 -0
  29. blitz_api/types/_models.py +23 -0
  30. blitz_api/types/account.py +27 -0
  31. blitz_api/types/enrichment.py +76 -0
  32. blitz_api/types/enums.py +633 -0
  33. blitz_api/types/filters.py +130 -0
  34. blitz_api/types/search.py +36 -0
  35. blitz_api/types/shared.py +119 -0
  36. blitz_api/types/utils.py +35 -0
  37. blitz_api_py-0.1.0.dist-info/METADATA +220 -0
  38. blitz_api_py-0.1.0.dist-info/RECORD +40 -0
  39. blitz_api_py-0.1.0.dist-info/WHEEL +4 -0
  40. blitz_api_py-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,116 @@
1
+ """The Enrichment resource: ``client.enrichment``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from ..._compat import TimeoutParam
8
+ from ...types.enrichment import (
9
+ CompanyEnrichmentResponse,
10
+ DomainToLinkedinResponse,
11
+ EmailEnrichmentResponse,
12
+ EmailToPersonResponse,
13
+ LinkedinToDomainResponse,
14
+ PhoneEnrichmentResponse,
15
+ PhoneToPersonResponse,
16
+ )
17
+
18
+ if TYPE_CHECKING:
19
+ from ..._client import AsyncBlitzAPI
20
+
21
+ _EMAIL = "/v2/enrichment/email"
22
+ _PHONE = "/v2/enrichment/phone"
23
+ _EMAIL_TO_PERSON = "/v2/enrichment/email-to-person"
24
+ _PHONE_TO_PERSON = "/v2/enrichment/phone-to-person"
25
+ _COMPANY = "/v2/enrichment/company"
26
+ _DOMAIN_TO_LINKEDIN = "/v2/enrichment/domain-to-linkedin"
27
+ _LINKEDIN_TO_DOMAIN = "/v2/enrichment/linkedin-to-domain"
28
+
29
+
30
+ class AsyncEnrichmentResource:
31
+ def __init__(self, client: AsyncBlitzAPI) -> None:
32
+ self._client = client
33
+
34
+ async def email(
35
+ self, *, person_linkedin_url: str, timeout: TimeoutParam = None
36
+ ) -> EmailEnrichmentResponse:
37
+ """Find a verified work email from a LinkedIn profile URL."""
38
+ return await self._client._request(
39
+ "POST",
40
+ _EMAIL,
41
+ body={"person_linkedin_url": person_linkedin_url},
42
+ cast_to=EmailEnrichmentResponse,
43
+ timeout=timeout,
44
+ )
45
+
46
+ async def phone(
47
+ self, *, person_linkedin_url: str, timeout: TimeoutParam = None
48
+ ) -> PhoneEnrichmentResponse:
49
+ """Find a phone number from a LinkedIn profile URL (US only)."""
50
+ return await self._client._request(
51
+ "POST",
52
+ _PHONE,
53
+ body={"person_linkedin_url": person_linkedin_url},
54
+ cast_to=PhoneEnrichmentResponse,
55
+ timeout=timeout,
56
+ )
57
+
58
+ async def email_to_person(
59
+ self, *, email: str, timeout: TimeoutParam = None
60
+ ) -> EmailToPersonResponse:
61
+ """Resolve a work email to a full person profile."""
62
+ return await self._client._request(
63
+ "POST",
64
+ _EMAIL_TO_PERSON,
65
+ body={"email": email},
66
+ cast_to=EmailToPersonResponse,
67
+ timeout=timeout,
68
+ )
69
+
70
+ async def phone_to_person(
71
+ self, *, phone: str, timeout: TimeoutParam = None
72
+ ) -> PhoneToPersonResponse:
73
+ """Resolve a phone number to a full person profile."""
74
+ return await self._client._request(
75
+ "POST",
76
+ _PHONE_TO_PERSON,
77
+ body={"phone": phone},
78
+ cast_to=PhoneToPersonResponse,
79
+ timeout=timeout,
80
+ )
81
+
82
+ async def company(
83
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
84
+ ) -> CompanyEnrichmentResponse:
85
+ """Resolve a company LinkedIn URL to a full company profile."""
86
+ return await self._client._request(
87
+ "POST",
88
+ _COMPANY,
89
+ body={"company_linkedin_url": company_linkedin_url},
90
+ cast_to=CompanyEnrichmentResponse,
91
+ timeout=timeout,
92
+ )
93
+
94
+ async def domain_to_linkedin(
95
+ self, *, domain: str, timeout: TimeoutParam = None
96
+ ) -> DomainToLinkedinResponse:
97
+ """Resolve a website domain to a company LinkedIn URL."""
98
+ return await self._client._request(
99
+ "POST",
100
+ _DOMAIN_TO_LINKEDIN,
101
+ body={"domain": domain},
102
+ cast_to=DomainToLinkedinResponse,
103
+ timeout=timeout,
104
+ )
105
+
106
+ async def linkedin_to_domain(
107
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
108
+ ) -> LinkedinToDomainResponse:
109
+ """Resolve a company LinkedIn URL to its email domain."""
110
+ return await self._client._request(
111
+ "POST",
112
+ _LINKEDIN_TO_DOMAIN,
113
+ body={"company_linkedin_url": company_linkedin_url},
114
+ cast_to=LinkedinToDomainResponse,
115
+ timeout=timeout,
116
+ )
@@ -0,0 +1,153 @@
1
+ """The Search resource: ``client.search``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from ..._compat import TimeoutParam
8
+ from ..._pagination_async import AsyncCursorPage, AsyncPageNumberPage
9
+ from ...types.filters import (
10
+ CascadeTier,
11
+ CompanyFilter,
12
+ ContinentValue,
13
+ JobFunctionValue,
14
+ JobLevelValue,
15
+ PeopleFilter,
16
+ SalesRegionValue,
17
+ )
18
+ from ...types.search import WaterfallIcpResponse
19
+ from ...types.shared import Company, Person
20
+
21
+ if TYPE_CHECKING:
22
+ from ..._client import AsyncBlitzAPI
23
+
24
+ _PEOPLE = "/v2/search/people"
25
+ _COMPANIES = "/v2/search/companies"
26
+ _EMPLOYEE_FINDER = "/v2/search/employee-finder"
27
+ _WATERFALL = "/v2/search/waterfall-icp-keyword"
28
+
29
+
30
+ def _drop_none(**kwargs: Any) -> dict[str, Any]:
31
+ """Build a request body keeping only the arguments the caller provided."""
32
+ return {key: value for key, value in kwargs.items() if value is not None}
33
+
34
+
35
+ def _employee_finder_body(
36
+ *,
37
+ company_linkedin_url: str,
38
+ country_code: list[str] | None,
39
+ continent: list[ContinentValue] | None,
40
+ sales_region: list[SalesRegionValue] | None,
41
+ job_level: list[JobLevelValue] | None,
42
+ job_function: list[JobFunctionValue] | None,
43
+ min_connections_count: int | None,
44
+ max_results: int | None,
45
+ page: int | None,
46
+ ) -> dict[str, Any]:
47
+ return _drop_none(
48
+ company_linkedin_url=company_linkedin_url,
49
+ country_code=country_code,
50
+ continent=continent,
51
+ sales_region=sales_region,
52
+ job_level=job_level,
53
+ job_function=job_function,
54
+ min_connections_count=min_connections_count,
55
+ max_results=max_results,
56
+ page=page,
57
+ )
58
+
59
+
60
+ class AsyncSearchResource:
61
+ def __init__(self, client: AsyncBlitzAPI) -> None:
62
+ self._client = client
63
+
64
+ async def people(
65
+ self,
66
+ *,
67
+ company: CompanyFilter | None = None,
68
+ people: PeopleFilter | None = None,
69
+ max_results: int | None = None,
70
+ cursor: str | None = None,
71
+ timeout: TimeoutParam = None,
72
+ ) -> AsyncCursorPage[Person]:
73
+ """Search people across many companies, combining company and persona filters.
74
+
75
+ Auto-paginates over every matching person when the result is iterated; use
76
+ ``.iter_pages()`` or the ``cursor=`` arg for manual control.
77
+ """
78
+ body = _drop_none(company=company, people=people, max_results=max_results, cursor=cursor)
79
+ return await self._client._request(
80
+ "POST", _PEOPLE, body=body, cast_to=AsyncCursorPage[Person], timeout=timeout
81
+ )
82
+
83
+ async def companies(
84
+ self,
85
+ *,
86
+ company: CompanyFilter | None = None,
87
+ max_results: int | None = None,
88
+ cursor: str | None = None,
89
+ timeout: TimeoutParam = None,
90
+ ) -> AsyncCursorPage[Company]:
91
+ """Find companies matching ICP filters (industry, size, HQ, revenue, ...).
92
+
93
+ Auto-paginates over every matching company; use ``.iter_pages()`` or ``cursor=``
94
+ for manual control.
95
+ """
96
+ body = _drop_none(company=company, max_results=max_results, cursor=cursor)
97
+ return await self._client._request(
98
+ "POST", _COMPANIES, body=body, cast_to=AsyncCursorPage[Company], timeout=timeout
99
+ )
100
+
101
+ async def employee_finder(
102
+ self,
103
+ *,
104
+ company_linkedin_url: str,
105
+ country_code: list[str] | None = None,
106
+ continent: list[ContinentValue] | None = None,
107
+ sales_region: list[SalesRegionValue] | None = None,
108
+ job_level: list[JobLevelValue] | None = None,
109
+ job_function: list[JobFunctionValue] | None = None,
110
+ min_connections_count: int | None = None,
111
+ max_results: int | None = None,
112
+ page: int | None = None,
113
+ timeout: TimeoutParam = None,
114
+ ) -> AsyncPageNumberPage[Person]:
115
+ """Search employees at a single company, with page-based pagination.
116
+
117
+ Auto-paginates over every matching employee; use ``.iter_pages()`` or ``page=``
118
+ for manual control.
119
+ """
120
+ body = _employee_finder_body(
121
+ company_linkedin_url=company_linkedin_url,
122
+ country_code=country_code,
123
+ continent=continent,
124
+ sales_region=sales_region,
125
+ job_level=job_level,
126
+ job_function=job_function,
127
+ min_connections_count=min_connections_count,
128
+ max_results=max_results,
129
+ page=page,
130
+ )
131
+ return await self._client._request(
132
+ "POST",
133
+ _EMPLOYEE_FINDER,
134
+ body=body,
135
+ cast_to=AsyncPageNumberPage[Person],
136
+ timeout=timeout,
137
+ )
138
+
139
+ async def waterfall_icp(
140
+ self,
141
+ *,
142
+ company_linkedin_url: str,
143
+ cascade: list[CascadeTier],
144
+ max_results: int | None = None,
145
+ timeout: TimeoutParam = None,
146
+ ) -> WaterfallIcpResponse:
147
+ """Find the best decision-maker at a company via a prioritized cascade."""
148
+ body = _drop_none(
149
+ company_linkedin_url=company_linkedin_url, cascade=cascade, max_results=max_results
150
+ )
151
+ return await self._client._request(
152
+ "POST", _WATERFALL, body=body, cast_to=WaterfallIcpResponse, timeout=timeout
153
+ )
@@ -0,0 +1,43 @@
1
+ """The Utilities resource: ``client.utils``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from ..._compat import TimeoutParam
8
+ from ...types.utils import CompanyEmploymentDistributionResponse, CurrentDateResponse
9
+
10
+ if TYPE_CHECKING:
11
+ from ..._client import AsyncBlitzAPI
12
+
13
+ _CURRENT_DATE = "/v2/utils/current-date"
14
+ _EMPLOYMENT_DISTRIBUTION = "/v2/utils/company-employment-distribution"
15
+
16
+
17
+ class AsyncUtilsResource:
18
+ def __init__(self, client: AsyncBlitzAPI) -> None:
19
+ self._client = client
20
+
21
+ async def current_date(
22
+ self, *, region: str, timeout: TimeoutParam = None
23
+ ) -> CurrentDateResponse:
24
+ """Get the current server date/time for an IANA timezone (e.g. ``America/New_York``)."""
25
+ return await self._client._request(
26
+ "POST",
27
+ _CURRENT_DATE,
28
+ body={"region": region},
29
+ cast_to=CurrentDateResponse,
30
+ timeout=timeout,
31
+ )
32
+
33
+ async def company_employment_distribution(
34
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
35
+ ) -> CompanyEmploymentDistributionResponse:
36
+ """Get a company's employee count broken down by country."""
37
+ return await self._client._request(
38
+ "POST",
39
+ _EMPLOYMENT_DISTRIBUTION,
40
+ body={"company_linkedin_url": company_linkedin_url},
41
+ cast_to=CompanyEmploymentDistributionResponse,
42
+ timeout=timeout,
43
+ )
@@ -0,0 +1,3 @@
1
+ # This file is @generated by scripts/gen_sync.py from src/blitz_api/resources/_async/__init__.py.
2
+ # Do not edit by hand — edit the async source and run `python scripts/gen_sync.py`.
3
+ """Blitz API resource classes, grouped by the API's OpenAPI tags."""
@@ -0,0 +1,29 @@
1
+ # This file is @generated by scripts/gen_sync.py from src/blitz_api/resources/_async/account.py.
2
+ # Do not edit by hand — edit the async source and run `python scripts/gen_sync.py`.
3
+ """The Account resource: ``client.account``."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from ..._compat import TimeoutParam
10
+ from ...types.account import KeyInfo
11
+
12
+ if TYPE_CHECKING:
13
+ from ..._client import BlitzAPI
14
+
15
+ _KEY_INFO_PATH = "/v2/account/key-info"
16
+
17
+
18
+ class AccountResource:
19
+ def __init__(self, client: BlitzAPI) -> None:
20
+ self._client = client
21
+
22
+ def key_info(self, *, timeout: TimeoutParam = None) -> KeyInfo:
23
+ """Check the API key's validity, credit balance, and rate limit.
24
+
25
+ A cheap health check to run before a batch job.
26
+ """
27
+ return self._client._request(
28
+ "GET", _KEY_INFO_PATH, body=None, cast_to=KeyInfo, timeout=timeout
29
+ )
@@ -0,0 +1,118 @@
1
+ # This file is @generated by scripts/gen_sync.py from src/blitz_api/resources/_async/enrichment.py.
2
+ # Do not edit by hand — edit the async source and run `python scripts/gen_sync.py`.
3
+ """The Enrichment resource: ``client.enrichment``."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from ..._compat import TimeoutParam
10
+ from ...types.enrichment import (
11
+ CompanyEnrichmentResponse,
12
+ DomainToLinkedinResponse,
13
+ EmailEnrichmentResponse,
14
+ EmailToPersonResponse,
15
+ LinkedinToDomainResponse,
16
+ PhoneEnrichmentResponse,
17
+ PhoneToPersonResponse,
18
+ )
19
+
20
+ if TYPE_CHECKING:
21
+ from ..._client import BlitzAPI
22
+
23
+ _EMAIL = "/v2/enrichment/email"
24
+ _PHONE = "/v2/enrichment/phone"
25
+ _EMAIL_TO_PERSON = "/v2/enrichment/email-to-person"
26
+ _PHONE_TO_PERSON = "/v2/enrichment/phone-to-person"
27
+ _COMPANY = "/v2/enrichment/company"
28
+ _DOMAIN_TO_LINKEDIN = "/v2/enrichment/domain-to-linkedin"
29
+ _LINKEDIN_TO_DOMAIN = "/v2/enrichment/linkedin-to-domain"
30
+
31
+
32
+ class EnrichmentResource:
33
+ def __init__(self, client: BlitzAPI) -> None:
34
+ self._client = client
35
+
36
+ def email(
37
+ self, *, person_linkedin_url: str, timeout: TimeoutParam = None
38
+ ) -> EmailEnrichmentResponse:
39
+ """Find a verified work email from a LinkedIn profile URL."""
40
+ return self._client._request(
41
+ "POST",
42
+ _EMAIL,
43
+ body={"person_linkedin_url": person_linkedin_url},
44
+ cast_to=EmailEnrichmentResponse,
45
+ timeout=timeout,
46
+ )
47
+
48
+ def phone(
49
+ self, *, person_linkedin_url: str, timeout: TimeoutParam = None
50
+ ) -> PhoneEnrichmentResponse:
51
+ """Find a phone number from a LinkedIn profile URL (US only)."""
52
+ return self._client._request(
53
+ "POST",
54
+ _PHONE,
55
+ body={"person_linkedin_url": person_linkedin_url},
56
+ cast_to=PhoneEnrichmentResponse,
57
+ timeout=timeout,
58
+ )
59
+
60
+ def email_to_person(
61
+ self, *, email: str, timeout: TimeoutParam = None
62
+ ) -> EmailToPersonResponse:
63
+ """Resolve a work email to a full person profile."""
64
+ return self._client._request(
65
+ "POST",
66
+ _EMAIL_TO_PERSON,
67
+ body={"email": email},
68
+ cast_to=EmailToPersonResponse,
69
+ timeout=timeout,
70
+ )
71
+
72
+ def phone_to_person(
73
+ self, *, phone: str, timeout: TimeoutParam = None
74
+ ) -> PhoneToPersonResponse:
75
+ """Resolve a phone number to a full person profile."""
76
+ return self._client._request(
77
+ "POST",
78
+ _PHONE_TO_PERSON,
79
+ body={"phone": phone},
80
+ cast_to=PhoneToPersonResponse,
81
+ timeout=timeout,
82
+ )
83
+
84
+ def company(
85
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
86
+ ) -> CompanyEnrichmentResponse:
87
+ """Resolve a company LinkedIn URL to a full company profile."""
88
+ return self._client._request(
89
+ "POST",
90
+ _COMPANY,
91
+ body={"company_linkedin_url": company_linkedin_url},
92
+ cast_to=CompanyEnrichmentResponse,
93
+ timeout=timeout,
94
+ )
95
+
96
+ def domain_to_linkedin(
97
+ self, *, domain: str, timeout: TimeoutParam = None
98
+ ) -> DomainToLinkedinResponse:
99
+ """Resolve a website domain to a company LinkedIn URL."""
100
+ return self._client._request(
101
+ "POST",
102
+ _DOMAIN_TO_LINKEDIN,
103
+ body={"domain": domain},
104
+ cast_to=DomainToLinkedinResponse,
105
+ timeout=timeout,
106
+ )
107
+
108
+ def linkedin_to_domain(
109
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
110
+ ) -> LinkedinToDomainResponse:
111
+ """Resolve a company LinkedIn URL to its email domain."""
112
+ return self._client._request(
113
+ "POST",
114
+ _LINKEDIN_TO_DOMAIN,
115
+ body={"company_linkedin_url": company_linkedin_url},
116
+ cast_to=LinkedinToDomainResponse,
117
+ timeout=timeout,
118
+ )
@@ -0,0 +1,155 @@
1
+ # This file is @generated by scripts/gen_sync.py from src/blitz_api/resources/_async/search.py.
2
+ # Do not edit by hand — edit the async source and run `python scripts/gen_sync.py`.
3
+ """The Search resource: ``client.search``."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from ..._compat import TimeoutParam
10
+ from ..._pagination_sync import CursorPage, PageNumberPage
11
+ from ...types.filters import (
12
+ CascadeTier,
13
+ CompanyFilter,
14
+ ContinentValue,
15
+ JobFunctionValue,
16
+ JobLevelValue,
17
+ PeopleFilter,
18
+ SalesRegionValue,
19
+ )
20
+ from ...types.search import WaterfallIcpResponse
21
+ from ...types.shared import Company, Person
22
+
23
+ if TYPE_CHECKING:
24
+ from ..._client import BlitzAPI
25
+
26
+ _PEOPLE = "/v2/search/people"
27
+ _COMPANIES = "/v2/search/companies"
28
+ _EMPLOYEE_FINDER = "/v2/search/employee-finder"
29
+ _WATERFALL = "/v2/search/waterfall-icp-keyword"
30
+
31
+
32
+ def _drop_none(**kwargs: Any) -> dict[str, Any]:
33
+ """Build a request body keeping only the arguments the caller provided."""
34
+ return {key: value for key, value in kwargs.items() if value is not None}
35
+
36
+
37
+ def _employee_finder_body(
38
+ *,
39
+ company_linkedin_url: str,
40
+ country_code: list[str] | None,
41
+ continent: list[ContinentValue] | None,
42
+ sales_region: list[SalesRegionValue] | None,
43
+ job_level: list[JobLevelValue] | None,
44
+ job_function: list[JobFunctionValue] | None,
45
+ min_connections_count: int | None,
46
+ max_results: int | None,
47
+ page: int | None,
48
+ ) -> dict[str, Any]:
49
+ return _drop_none(
50
+ company_linkedin_url=company_linkedin_url,
51
+ country_code=country_code,
52
+ continent=continent,
53
+ sales_region=sales_region,
54
+ job_level=job_level,
55
+ job_function=job_function,
56
+ min_connections_count=min_connections_count,
57
+ max_results=max_results,
58
+ page=page,
59
+ )
60
+
61
+
62
+ class SearchResource:
63
+ def __init__(self, client: BlitzAPI) -> None:
64
+ self._client = client
65
+
66
+ def people(
67
+ self,
68
+ *,
69
+ company: CompanyFilter | None = None,
70
+ people: PeopleFilter | None = None,
71
+ max_results: int | None = None,
72
+ cursor: str | None = None,
73
+ timeout: TimeoutParam = None,
74
+ ) -> CursorPage[Person]:
75
+ """Search people across many companies, combining company and persona filters.
76
+
77
+ Auto-paginates over every matching person when the result is iterated; use
78
+ ``.iter_pages()`` or the ``cursor=`` arg for manual control.
79
+ """
80
+ body = _drop_none(company=company, people=people, max_results=max_results, cursor=cursor)
81
+ return self._client._request(
82
+ "POST", _PEOPLE, body=body, cast_to=CursorPage[Person], timeout=timeout
83
+ )
84
+
85
+ def companies(
86
+ self,
87
+ *,
88
+ company: CompanyFilter | None = None,
89
+ max_results: int | None = None,
90
+ cursor: str | None = None,
91
+ timeout: TimeoutParam = None,
92
+ ) -> CursorPage[Company]:
93
+ """Find companies matching ICP filters (industry, size, HQ, revenue, ...).
94
+
95
+ Auto-paginates over every matching company; use ``.iter_pages()`` or ``cursor=``
96
+ for manual control.
97
+ """
98
+ body = _drop_none(company=company, max_results=max_results, cursor=cursor)
99
+ return self._client._request(
100
+ "POST", _COMPANIES, body=body, cast_to=CursorPage[Company], timeout=timeout
101
+ )
102
+
103
+ def employee_finder(
104
+ self,
105
+ *,
106
+ company_linkedin_url: str,
107
+ country_code: list[str] | None = None,
108
+ continent: list[ContinentValue] | None = None,
109
+ sales_region: list[SalesRegionValue] | None = None,
110
+ job_level: list[JobLevelValue] | None = None,
111
+ job_function: list[JobFunctionValue] | None = None,
112
+ min_connections_count: int | None = None,
113
+ max_results: int | None = None,
114
+ page: int | None = None,
115
+ timeout: TimeoutParam = None,
116
+ ) -> PageNumberPage[Person]:
117
+ """Search employees at a single company, with page-based pagination.
118
+
119
+ Auto-paginates over every matching employee; use ``.iter_pages()`` or ``page=``
120
+ for manual control.
121
+ """
122
+ body = _employee_finder_body(
123
+ company_linkedin_url=company_linkedin_url,
124
+ country_code=country_code,
125
+ continent=continent,
126
+ sales_region=sales_region,
127
+ job_level=job_level,
128
+ job_function=job_function,
129
+ min_connections_count=min_connections_count,
130
+ max_results=max_results,
131
+ page=page,
132
+ )
133
+ return self._client._request(
134
+ "POST",
135
+ _EMPLOYEE_FINDER,
136
+ body=body,
137
+ cast_to=PageNumberPage[Person],
138
+ timeout=timeout,
139
+ )
140
+
141
+ def waterfall_icp(
142
+ self,
143
+ *,
144
+ company_linkedin_url: str,
145
+ cascade: list[CascadeTier],
146
+ max_results: int | None = None,
147
+ timeout: TimeoutParam = None,
148
+ ) -> WaterfallIcpResponse:
149
+ """Find the best decision-maker at a company via a prioritized cascade."""
150
+ body = _drop_none(
151
+ company_linkedin_url=company_linkedin_url, cascade=cascade, max_results=max_results
152
+ )
153
+ return self._client._request(
154
+ "POST", _WATERFALL, body=body, cast_to=WaterfallIcpResponse, timeout=timeout
155
+ )
@@ -0,0 +1,45 @@
1
+ # This file is @generated by scripts/gen_sync.py from src/blitz_api/resources/_async/utils.py.
2
+ # Do not edit by hand — edit the async source and run `python scripts/gen_sync.py`.
3
+ """The Utilities resource: ``client.utils``."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from ..._compat import TimeoutParam
10
+ from ...types.utils import CompanyEmploymentDistributionResponse, CurrentDateResponse
11
+
12
+ if TYPE_CHECKING:
13
+ from ..._client import BlitzAPI
14
+
15
+ _CURRENT_DATE = "/v2/utils/current-date"
16
+ _EMPLOYMENT_DISTRIBUTION = "/v2/utils/company-employment-distribution"
17
+
18
+
19
+ class UtilsResource:
20
+ def __init__(self, client: BlitzAPI) -> None:
21
+ self._client = client
22
+
23
+ def current_date(
24
+ self, *, region: str, timeout: TimeoutParam = None
25
+ ) -> CurrentDateResponse:
26
+ """Get the current server date/time for an IANA timezone (e.g. ``America/New_York``)."""
27
+ return self._client._request(
28
+ "POST",
29
+ _CURRENT_DATE,
30
+ body={"region": region},
31
+ cast_to=CurrentDateResponse,
32
+ timeout=timeout,
33
+ )
34
+
35
+ def company_employment_distribution(
36
+ self, *, company_linkedin_url: str, timeout: TimeoutParam = None
37
+ ) -> CompanyEmploymentDistributionResponse:
38
+ """Get a company's employee count broken down by country."""
39
+ return self._client._request(
40
+ "POST",
41
+ _EMPLOYMENT_DISTRIBUTION,
42
+ body={"company_linkedin_url": company_linkedin_url},
43
+ cast_to=CompanyEmploymentDistributionResponse,
44
+ timeout=timeout,
45
+ )