oneshot-python 0.38.0__tar.gz → 0.39.0__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.
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/PKG-INFO +1 -1
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/README.md +1 -1
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/client.py +54 -50
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/lookup_manifest.py +245 -127
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/pyproject.toml +1 -1
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_declared_routes.py +4 -4
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_lookup.py +8 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_paid_call_proof.py +1 -1
- oneshot_python-0.39.0/tests/test_person_quote_credits.py +82 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_phones_pending.py +7 -1
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/.gitignore +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/__init__.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/_errors.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/_types.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/lookup.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/physical_mail.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/oneshot/x402.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/__init__.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/conftest.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_access_token.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_approvals.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_balance.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_browser.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_budgets.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_charge_amount.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_compute.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_compute_manifest.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_compute_outputs.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_declared_worker_reads.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_domains.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_domains_signed.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_email_payload.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_emergency_error.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_hunts.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_inbound_voice.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_inbox_notifications.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_linkedin.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_max_cost_header.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_payment_rejection.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_physical_mail.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_poll_backoff.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_request_id.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_signed_job_and_analytics.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_tag_receipt_value.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_top_up_credits.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_update_build.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_wait_false.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/tests/test_x402.py +0 -0
- {oneshot_python-0.38.0 → oneshot_python-0.39.0}/uv.lock +0 -0
|
@@ -244,7 +244,7 @@ except LinkedInConnectRequiredError:
|
|
|
244
244
|
|
|
245
245
|
Account reads stop offering reconnect after confirming upstream deletion.
|
|
246
246
|
Missing accounts are excluded from the active list; `include_revoked=True`
|
|
247
|
-
lets you inspect their `
|
|
247
|
+
lets you inspect their `connection_deleted` status and `reconnect_required=False`.
|
|
248
248
|
Authentication failures and timeouts remain ordinary errors and do not instruct
|
|
249
249
|
the consumer to create a new connection.
|
|
250
250
|
|
|
@@ -60,13 +60,13 @@ try:
|
|
|
60
60
|
|
|
61
61
|
SDK_VERSION = _pkg_version("oneshot-python")
|
|
62
62
|
except Exception: # pragma: no cover - editable/source runs without dist metadata
|
|
63
|
-
SDK_VERSION = "0.
|
|
63
|
+
SDK_VERSION = "0.39.0"
|
|
64
64
|
|
|
65
65
|
_BASE_URL = "https://win.oneshotagent.com"
|
|
66
66
|
_HUNT_BASE_URL = "https://api.soulhunt.ai"
|
|
67
67
|
_ACCESS_TOKEN_RE = re.compile(r"^oneshot_[0-9a-f]{64}$")
|
|
68
68
|
# Endpoints whose admission reads a "submit"-scoped agent proof (same list as the TypeScript SDK).
|
|
69
|
-
_DURABLE_ADMISSION_ENDPOINT = re.compile(r"(
|
|
69
|
+
_DURABLE_ADMISSION_ENDPOINT = re.compile(r"(lookup/person-(profile|email|email-status)|lookup/place-permits|physical-mail/send)$")
|
|
70
70
|
_CHAIN_ID = 8453
|
|
71
71
|
_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
72
72
|
|
|
@@ -2073,37 +2073,37 @@ class OneShotClient:
|
|
|
2073
2073
|
approval_id = kwargs.pop("approval_id", None)
|
|
2074
2074
|
return await self.acall_tool("/v1/tools/sms/send", {"message": message, "to_number": to_number, **kwargs}, approval_id=approval_id)
|
|
2075
2075
|
|
|
2076
|
-
def
|
|
2076
|
+
def person_find(self, **kwargs: Any) -> Any:
|
|
2077
2077
|
"""Search for people by job title, company, etc. Blocking."""
|
|
2078
|
-
return self.call_tool("/v1/tools/
|
|
2078
|
+
return self.call_tool("/v1/tools/find/person", kwargs)
|
|
2079
2079
|
|
|
2080
|
-
async def
|
|
2080
|
+
async def aperson_find(self, **kwargs: Any) -> Any:
|
|
2081
2081
|
"""Search for people by job title, company, etc. Async."""
|
|
2082
|
-
return await self.acall_tool("/v1/tools/
|
|
2082
|
+
return await self.acall_tool("/v1/tools/find/person", kwargs)
|
|
2083
2083
|
|
|
2084
|
-
def
|
|
2084
|
+
def person_profile(self, **kwargs: Any) -> Any:
|
|
2085
2085
|
"""Enrich a person's profile from LinkedIn URL, email, or name. Blocking."""
|
|
2086
|
-
return self.call_tool("/v1/tools/
|
|
2086
|
+
return self.call_tool("/v1/tools/lookup/person-profile", kwargs)
|
|
2087
2087
|
|
|
2088
|
-
async def
|
|
2088
|
+
async def aperson_profile(self, **kwargs: Any) -> Any:
|
|
2089
2089
|
"""Enrich a person's profile from LinkedIn URL, email, or name. Async."""
|
|
2090
|
-
return await self.acall_tool("/v1/tools/
|
|
2090
|
+
return await self.acall_tool("/v1/tools/lookup/person-profile", kwargs)
|
|
2091
2091
|
|
|
2092
|
-
def
|
|
2092
|
+
def company_find(self, **kwargs: Any) -> Any:
|
|
2093
2093
|
"""Search for companies by name, domain, industry, location, size, etc. Blocking."""
|
|
2094
|
-
return self.call_tool("/v1/tools/
|
|
2094
|
+
return self.call_tool("/v1/tools/find/company", kwargs)
|
|
2095
2095
|
|
|
2096
|
-
async def
|
|
2096
|
+
async def acompany_find(self, **kwargs: Any) -> Any:
|
|
2097
2097
|
"""Search for companies by name, domain, industry, location, size, etc. Async."""
|
|
2098
|
-
return await self.acall_tool("/v1/tools/
|
|
2098
|
+
return await self.acall_tool("/v1/tools/find/company", kwargs)
|
|
2099
2099
|
|
|
2100
|
-
def
|
|
2100
|
+
def company_profile(self, **kwargs: Any) -> Any:
|
|
2101
2101
|
"""Enrich a company from domain, name, LinkedIn URL, or ticker. Blocking."""
|
|
2102
|
-
return self.call_tool("/v1/tools/
|
|
2102
|
+
return self.call_tool("/v1/tools/lookup/company-profile", kwargs)
|
|
2103
2103
|
|
|
2104
|
-
async def
|
|
2104
|
+
async def acompany_profile(self, **kwargs: Any) -> Any:
|
|
2105
2105
|
"""Enrich a company from domain, name, LinkedIn URL, or ticker. Async."""
|
|
2106
|
-
return await self.acall_tool("/v1/tools/
|
|
2106
|
+
return await self.acall_tool("/v1/tools/lookup/company-profile", kwargs)
|
|
2107
2107
|
|
|
2108
2108
|
def business_find(self, **kwargs: Any) -> Any:
|
|
2109
2109
|
"""Discover local businesses (restaurants, contractors, practices) by category/keywords x location. Blocking."""
|
|
@@ -2129,7 +2129,7 @@ class OneShotClient:
|
|
|
2129
2129
|
"""Federal Sources Sought / Presolicitation notices (SAM.gov) by NAICS code with the contracting officer's contact. Result carries `data_as_of` (snapshot behind the rows). Async."""
|
|
2130
2130
|
return await self.acall_tool("/v1/tools/find/record-solicitations", {"naics": naics, **kwargs})
|
|
2131
2131
|
|
|
2132
|
-
def
|
|
2132
|
+
def person_email(self, company_domain: str, *, full_name: Optional[str] = None, first_name: Optional[str] = None, last_name: Optional[str] = None, **kwargs: Any) -> Any:
|
|
2133
2133
|
"""Find a person's email address. Blocking."""
|
|
2134
2134
|
payload: dict[str, Any] = {"company_domain": company_domain, **kwargs}
|
|
2135
2135
|
if full_name:
|
|
@@ -2138,9 +2138,9 @@ class OneShotClient:
|
|
|
2138
2138
|
payload["first_name"] = first_name
|
|
2139
2139
|
if last_name:
|
|
2140
2140
|
payload["last_name"] = last_name
|
|
2141
|
-
return self.call_tool("/v1/tools/
|
|
2141
|
+
return self.call_tool("/v1/tools/lookup/person-email", payload)
|
|
2142
2142
|
|
|
2143
|
-
async def
|
|
2143
|
+
async def aperson_email(self, company_domain: str, *, full_name: Optional[str] = None, first_name: Optional[str] = None, last_name: Optional[str] = None, **kwargs: Any) -> Any:
|
|
2144
2144
|
"""Find a person's email address. Async."""
|
|
2145
2145
|
payload: dict[str, Any] = {"company_domain": company_domain, **kwargs}
|
|
2146
2146
|
if full_name:
|
|
@@ -2149,63 +2149,63 @@ class OneShotClient:
|
|
|
2149
2149
|
payload["first_name"] = first_name
|
|
2150
2150
|
if last_name:
|
|
2151
2151
|
payload["last_name"] = last_name
|
|
2152
|
-
return await self.acall_tool("/v1/tools/
|
|
2152
|
+
return await self.acall_tool("/v1/tools/lookup/person-email", payload)
|
|
2153
2153
|
|
|
2154
|
-
def
|
|
2154
|
+
def person_email_status(self, email: str) -> Any:
|
|
2155
2155
|
"""Verify email deliverability. Blocking."""
|
|
2156
|
-
return self.call_tool("/v1/tools/
|
|
2156
|
+
return self.call_tool("/v1/tools/lookup/person-email-status", {"email": email})
|
|
2157
2157
|
|
|
2158
|
-
async def
|
|
2158
|
+
async def aperson_email_status(self, email: str) -> Any:
|
|
2159
2159
|
"""Verify email deliverability. Async."""
|
|
2160
|
-
return await self.acall_tool("/v1/tools/
|
|
2160
|
+
return await self.acall_tool("/v1/tools/lookup/person-email-status", {"email": email})
|
|
2161
2161
|
|
|
2162
|
-
def
|
|
2162
|
+
def person_dossier(self, **kwargs: Any) -> Any:
|
|
2163
2163
|
"""Deep research on a person. Blocking."""
|
|
2164
|
-
return self.call_tool("/v1/tools/
|
|
2164
|
+
return self.call_tool("/v1/tools/lookup/person-dossier", kwargs)
|
|
2165
2165
|
|
|
2166
|
-
async def
|
|
2166
|
+
async def aperson_dossier(self, **kwargs: Any) -> Any:
|
|
2167
2167
|
"""Deep research on a person. Async."""
|
|
2168
|
-
return await self.acall_tool("/v1/tools/
|
|
2168
|
+
return await self.acall_tool("/v1/tools/lookup/person-dossier", kwargs)
|
|
2169
2169
|
|
|
2170
|
-
def
|
|
2170
|
+
def person_social_accounts(self, **kwargs: Any) -> Any:
|
|
2171
2171
|
"""Discover social media profiles. Blocking."""
|
|
2172
|
-
return self.call_tool("/v1/tools/
|
|
2172
|
+
return self.call_tool("/v1/tools/lookup/person-social-accounts", kwargs)
|
|
2173
2173
|
|
|
2174
|
-
async def
|
|
2174
|
+
async def aperson_social_accounts(self, **kwargs: Any) -> Any:
|
|
2175
2175
|
"""Discover social media profiles. Async."""
|
|
2176
|
-
return await self.acall_tool("/v1/tools/
|
|
2176
|
+
return await self.acall_tool("/v1/tools/lookup/person-social-accounts", kwargs)
|
|
2177
2177
|
|
|
2178
|
-
def
|
|
2178
|
+
def person_articles(self, name: str, company: str, **kwargs: Any) -> Any:
|
|
2179
2179
|
"""Find articles by or about a person. Blocking."""
|
|
2180
|
-
return self.call_tool("/v1/tools/
|
|
2180
|
+
return self.call_tool("/v1/tools/lookup/person-articles", {"name": name, "company": company, **kwargs})
|
|
2181
2181
|
|
|
2182
|
-
async def
|
|
2182
|
+
async def aperson_articles(self, name: str, company: str, **kwargs: Any) -> Any:
|
|
2183
2183
|
"""Find articles by or about a person. Async."""
|
|
2184
|
-
return await self.acall_tool("/v1/tools/
|
|
2184
|
+
return await self.acall_tool("/v1/tools/lookup/person-articles", {"name": name, "company": company, **kwargs})
|
|
2185
2185
|
|
|
2186
|
-
def
|
|
2186
|
+
def person_posts(self, social_media_url: str, **kwargs: Any) -> Any:
|
|
2187
2187
|
"""Get recent social posts from a person. Blocking."""
|
|
2188
|
-
return self.call_tool("/v1/tools/
|
|
2188
|
+
return self.call_tool("/v1/tools/lookup/person-posts", {"social_media_url": social_media_url, **kwargs})
|
|
2189
2189
|
|
|
2190
|
-
async def
|
|
2190
|
+
async def aperson_posts(self, social_media_url: str, **kwargs: Any) -> Any:
|
|
2191
2191
|
"""Get recent social posts from a person. Async."""
|
|
2192
|
-
return await self.acall_tool("/v1/tools/
|
|
2192
|
+
return await self.acall_tool("/v1/tools/lookup/person-posts", {"social_media_url": social_media_url, **kwargs})
|
|
2193
2193
|
|
|
2194
2194
|
def person_interests(self, **kwargs: Any) -> Any:
|
|
2195
2195
|
"""Analyze a person's interests from their digital footprint. Blocking."""
|
|
2196
|
-
return self.call_tool("/v1/tools/
|
|
2196
|
+
return self.call_tool("/v1/tools/lookup/person-interests", kwargs)
|
|
2197
2197
|
|
|
2198
2198
|
async def aperson_interests(self, **kwargs: Any) -> Any:
|
|
2199
2199
|
"""Analyze a person's interests from their digital footprint. Async."""
|
|
2200
|
-
return await self.acall_tool("/v1/tools/
|
|
2200
|
+
return await self.acall_tool("/v1/tools/lookup/person-interests", kwargs)
|
|
2201
2201
|
|
|
2202
|
-
def
|
|
2202
|
+
def person_followers(self, social_media_url: str, **kwargs: Any) -> Any:
|
|
2203
2203
|
"""Get a person's social interactions. Blocking."""
|
|
2204
|
-
return self.call_tool("/v1/tools/
|
|
2204
|
+
return self.call_tool("/v1/tools/lookup/person-followers", {"social_media_url": social_media_url, **kwargs})
|
|
2205
2205
|
|
|
2206
|
-
async def
|
|
2206
|
+
async def aperson_followers(self, social_media_url: str, **kwargs: Any) -> Any:
|
|
2207
2207
|
"""Get a person's social interactions. Async."""
|
|
2208
|
-
return await self.acall_tool("/v1/tools/
|
|
2208
|
+
return await self.acall_tool("/v1/tools/lookup/person-followers", {"social_media_url": social_media_url, **kwargs})
|
|
2209
2209
|
|
|
2210
2210
|
def commerce_search(self, query: str, *, limit: int = 10, **kwargs: Any) -> Any:
|
|
2211
2211
|
"""Search for products. Blocking."""
|
|
@@ -2515,8 +2515,8 @@ class OneShotClient:
|
|
|
2515
2515
|
@staticmethod
|
|
2516
2516
|
def _is_phones_pending(result: Any) -> bool:
|
|
2517
2517
|
"""Detects whether a result is awaiting Apollo's async phone-reveal
|
|
2518
|
-
webhook.
|
|
2519
|
-
|
|
2518
|
+
webhook. Accepts legacy flat results and person_dossier's
|
|
2519
|
+
``result.profile.data.phones_pending``.
|
|
2520
2520
|
|
|
2521
2521
|
Mirrors the TS SDK's _isPhonesPending — kept in lockstep so the worker
|
|
2522
2522
|
contract works for both SDKs.
|
|
@@ -2528,6 +2528,10 @@ class OneShotClient:
|
|
|
2528
2528
|
inner = result.get("result")
|
|
2529
2529
|
if isinstance(inner, dict) and inner.get("phones_pending") is True:
|
|
2530
2530
|
return True
|
|
2531
|
+
profile = inner.get("profile") if isinstance(inner, dict) else None
|
|
2532
|
+
data = profile.get("data") if isinstance(profile, dict) else None
|
|
2533
|
+
if isinstance(data, dict) and data.get("phones_pending") is True:
|
|
2534
|
+
return True
|
|
2531
2535
|
return False
|
|
2532
2536
|
|
|
2533
2537
|
async def _poll_for_phones(
|