getanyapi 0.46.2__tar.gz → 0.47.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.
- {getanyapi-0.46.2 → getanyapi-0.47.0}/PKG-INFO +1 -1
- {getanyapi-0.46.2 → getanyapi-0.47.0}/pyproject.toml +1 -1
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/__init__.py +3 -1
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/types.py +16 -1
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_envelope.py +24 -0
- getanyapi-0.47.0/tests/test_not_found_reason.py +44 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/.gitignore +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/README.md +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_account.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_async_client.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_client.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_errors.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_idempotency.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_pagination.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/_transport.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/discovery_types.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/__init__.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/ahrefs.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/airbnb.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/alibaba.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/amazon.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/apollo.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/appstore.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/bluesky.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/booking.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/capterra.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/chatgpt.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/coinmarketcap.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/company.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/company_enrichment.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/company_search.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/congress.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/dexscreener.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/douyin.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/ebay.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/email.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/email_finding.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/email_verification.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/facebook.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/fiverr.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/g2.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/gemini.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/github.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/glassdoor.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/google.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/google_ads.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/google_finance.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/google_shopping.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/hackernews.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/indeed.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/instagram.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/job_search.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/linkedin.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/maps.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/mobile_phone.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/naver.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/nextdoor.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/people_search.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/perplexity.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/person.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/person_enrichment.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/pinterest.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/playstore.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/polymarket.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/realtor.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/reddit.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/redfin.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/rednote.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/sec.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/semrush.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/seo.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/snapchat.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/social.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/spotify.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/substack.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/technographics.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/threads.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/tiktok.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/tiktok_shop.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/tripadvisor.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/trustpilot.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/truthsocial.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/twitter.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/upwork.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/walmart.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/web.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/weibo.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/yahoo_finance.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/yelp.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/youtube.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/zhihu.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/platforms/zillow.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/src/getanyapi/py.typed +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/conftest.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_account.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_client.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_durable_requests.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_errors.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_fixture_roundtrip.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_fixture_sweep.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_pagination.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/tests/test_transport.py +0 -0
- {getanyapi-0.46.2 → getanyapi-0.47.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: getanyapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.47.0
|
|
4
4
|
Summary: Official typed Python SDK for AnyAPI: any API, one wallet, USD, no subscriptions.
|
|
5
5
|
Project-URL: Homepage, https://getanyapi.com
|
|
6
6
|
Project-URL: Documentation, https://getanyapi.com/docs
|
|
@@ -44,6 +44,7 @@ from .types import (
|
|
|
44
44
|
HighlightField,
|
|
45
45
|
LaneHealth,
|
|
46
46
|
LinearPricingOffer,
|
|
47
|
+
NotFoundReason,
|
|
47
48
|
Output,
|
|
48
49
|
OutputFound,
|
|
49
50
|
OutputNotFound,
|
|
@@ -54,7 +55,7 @@ from .types import (
|
|
|
54
55
|
unwrap,
|
|
55
56
|
)
|
|
56
57
|
|
|
57
|
-
__version__ = "0.
|
|
58
|
+
__version__ = "0.47.0"
|
|
58
59
|
|
|
59
60
|
__all__ = [
|
|
60
61
|
# clients + top-level functions
|
|
@@ -68,6 +69,7 @@ __all__ = [
|
|
|
68
69
|
"Output",
|
|
69
70
|
"OutputFound",
|
|
70
71
|
"OutputNotFound",
|
|
72
|
+
"NotFoundReason",
|
|
71
73
|
"Balance",
|
|
72
74
|
"AccountProfile",
|
|
73
75
|
"CatalogEntry",
|
|
@@ -68,11 +68,26 @@ class OutputFound(BaseModel, Generic[T]):
|
|
|
68
68
|
data: T
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
# Why a call answered ``found: false``. The gateway publishes this list as the
|
|
72
|
+
# ``reason`` enum on every found-data output schema, so the runtime names the same
|
|
73
|
+
# words; ``tests/test_not_found_reason.py`` holds the two together once the live
|
|
74
|
+
# OpenAPI carries the field. ``not_found``: the source states the target does not
|
|
75
|
+
# exist, or returned nothing for it. ``suspended``: the platform has suspended the
|
|
76
|
+
# account.
|
|
77
|
+
NotFoundReason = Literal["not_found", "suspended"]
|
|
78
|
+
NOT_FOUND_REASONS: tuple[str, ...] = ("not_found", "suspended")
|
|
79
|
+
|
|
80
|
+
|
|
71
81
|
class OutputNotFound(BaseModel):
|
|
72
|
-
"""The ``found: false`` branch: no matching entity, ``data`` is None.
|
|
82
|
+
"""The ``found: false`` branch: no matching entity, ``data`` is None.
|
|
83
|
+
|
|
84
|
+
``reason`` says why; it is absent only on a response from a gateway older
|
|
85
|
+
than the field.
|
|
86
|
+
"""
|
|
73
87
|
|
|
74
88
|
found: Literal[False]
|
|
75
89
|
data: None = None
|
|
90
|
+
reason: NotFoundReason | None = None
|
|
76
91
|
|
|
77
92
|
|
|
78
93
|
# Output[T] is the discriminated union on `found`.
|
|
@@ -51,6 +51,30 @@ def test_not_found_envelope() -> None:
|
|
|
51
51
|
assert result.hint is None
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def test_not_found_envelope_carries_its_reason() -> None:
|
|
55
|
+
result = RunResult[dict[str, Any]].model_validate(
|
|
56
|
+
{
|
|
57
|
+
"output": {"found": False, "data": None, "reason": "suspended"},
|
|
58
|
+
"provider": "AnyAPI",
|
|
59
|
+
"costUsd": 0.0,
|
|
60
|
+
"items": 0,
|
|
61
|
+
"replayed": False,
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
assert isinstance(result.output, OutputNotFound)
|
|
65
|
+
assert result.output.reason == "suspended"
|
|
66
|
+
with pytest.raises(ValidationError):
|
|
67
|
+
RunResult[dict[str, Any]].model_validate(
|
|
68
|
+
{
|
|
69
|
+
"output": {"found": False, "data": None, "reason": "UserUnavailable"},
|
|
70
|
+
"provider": "AnyAPI",
|
|
71
|
+
"costUsd": 0.0,
|
|
72
|
+
"items": 0,
|
|
73
|
+
"replayed": False,
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
54
78
|
def test_unwrap_returns_data_when_found() -> None:
|
|
55
79
|
result = RunResult[dict[str, Any]].model_validate(
|
|
56
80
|
{
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""The runtime's reason words are a copy of the enum the gateway publishes.
|
|
2
|
+
|
|
3
|
+
Every ``/v1/run/*`` operation in the committed OpenAPI snapshot that declares a
|
|
4
|
+
``reason`` enum on its output must declare exactly ``NOT_FOUND_REASONS``, in
|
|
5
|
+
order. Until the snapshot carries the field (it is refreshed from the live
|
|
6
|
+
gateway after deploy) there is nothing to compare.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from getanyapi.types import NOT_FOUND_REASONS
|
|
16
|
+
|
|
17
|
+
_OPENAPI = Path(__file__).resolve().parents[3] / "openapi.json"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _published_reason_enums() -> list[list[str]]:
|
|
21
|
+
document: dict[str, Any] = json.loads(_OPENAPI.read_text())
|
|
22
|
+
enums: list[list[str]] = []
|
|
23
|
+
for path, operations in document["paths"].items():
|
|
24
|
+
if not path.startswith("/v1/run/"):
|
|
25
|
+
continue
|
|
26
|
+
schema = (
|
|
27
|
+
operations.get("post", {})
|
|
28
|
+
.get("responses", {})
|
|
29
|
+
.get("200", {})
|
|
30
|
+
.get("content", {})
|
|
31
|
+
.get("application/json", {})
|
|
32
|
+
.get("schema", {})
|
|
33
|
+
)
|
|
34
|
+
output = schema.get("properties", {}).get("output", {})
|
|
35
|
+
for branch in output.get("anyOf", [output]):
|
|
36
|
+
reason = branch.get("properties", {}).get("reason", {})
|
|
37
|
+
if isinstance(reason.get("enum"), list):
|
|
38
|
+
enums.append(list(reason["enum"]))
|
|
39
|
+
return enums
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_reason_words_match_the_published_enum() -> None:
|
|
43
|
+
for published in _published_reason_enums():
|
|
44
|
+
assert published == list(NOT_FOUND_REASONS)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|