oneshot-python 0.29.0__tar.gz → 0.29.1__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.29.0 → oneshot_python-0.29.1}/PKG-INFO +1 -1
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/client.py +2 -2
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/pyproject.toml +1 -1
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_linkedin.py +19 -1
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/.gitignore +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/README.md +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/__init__.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/_errors.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/_types.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/physical_mail.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/x402.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/__init__.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/conftest.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_access_token.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_balance.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_browser.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_budgets.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_charge_amount.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_compute.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_domains.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_email_payload.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_emergency_error.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_max_cost_header.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_payment_rejection.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_phones_pending.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_physical_mail.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_poll_backoff.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_request_id.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_tag_receipt_value.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_top_up_credits.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_wait_false.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_x402.py +0 -0
- {oneshot_python-0.29.0 → oneshot_python-0.29.1}/uv.lock +0 -0
|
@@ -57,7 +57,7 @@ try:
|
|
|
57
57
|
|
|
58
58
|
SDK_VERSION = _pkg_version("oneshot-python")
|
|
59
59
|
except Exception: # pragma: no cover - editable/source runs without dist metadata
|
|
60
|
-
SDK_VERSION = "0.29.
|
|
60
|
+
SDK_VERSION = "0.29.1"
|
|
61
61
|
|
|
62
62
|
# ---------------------------------------------------------------------------
|
|
63
63
|
# Environment configuration
|
|
@@ -1454,7 +1454,7 @@ class OneShotClient:
|
|
|
1454
1454
|
return await self.acall_free_get(f"/v1/tools/linkedin/accounts/{quote(account_id, safe='')}")
|
|
1455
1455
|
|
|
1456
1456
|
def reconnect_linkedin_account(self, account_id: str, *, requested_actions: Optional[list[str]] = None, success_redirect_url: Optional[str] = None, failure_redirect_url: Optional[str] = None) -> dict:
|
|
1457
|
-
"""Hosted reconnect link for an existing account (
|
|
1457
|
+
"""Hosted reconnect link for an existing account (preserves ownership and history; replaces the grant after fresh hosted authentication). Free."""
|
|
1458
1458
|
return self.call_free_post(f"/v1/tools/linkedin/accounts/{quote(account_id, safe='')}/reconnect", _linkedin_connect_payload(requested_actions, success_redirect_url, failure_redirect_url), scope="write")
|
|
1459
1459
|
|
|
1460
1460
|
async def areconnect_linkedin_account(self, account_id: str, *, requested_actions: Optional[list[str]] = None, success_redirect_url: Optional[str] = None, failure_redirect_url: Optional[str] = None) -> dict:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "oneshot-python"
|
|
3
|
-
version = "0.29.
|
|
3
|
+
version = "0.29.1"
|
|
4
4
|
description = "Core Python SDK for the OneShot API — HTTP client with x402 payment handling — 45 tools"
|
|
5
5
|
readme = {text = "Core Python SDK for the OneShot API", content-type = "text/plain"}
|
|
6
6
|
license = "MIT"
|
|
@@ -75,7 +75,7 @@ def test_idempotency_key_header_is_set_on_paid_requests():
|
|
|
75
75
|
@pytest.mark.parametrize("asynchronous", [False, True])
|
|
76
76
|
@pytest.mark.parametrize("status,body,typed", [
|
|
77
77
|
(409, {"error": "connect_required", "details": {"next_action": "connect"}}, True),
|
|
78
|
-
(409, {"error": "
|
|
78
|
+
(409, {"error": "account_revoked"}, False),
|
|
79
79
|
(502, {"error": "linkedin_link_unavailable"}, False),
|
|
80
80
|
(401, {"error": "connect_required"}, False),
|
|
81
81
|
(409, ["connect_required"], False),
|
|
@@ -169,3 +169,21 @@ async def test_invitation_preserves_unrelated_http_errors(status, body):
|
|
|
169
169
|
with pytest.raises(httpx.HTTPStatusError) as caught:
|
|
170
170
|
await client.alinkedin_invite('account', 'target')
|
|
171
171
|
assert caught.value is error
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@pytest.mark.parametrize('asynchronous', [False, True])
|
|
175
|
+
def test_reconnect_sends_complete_upgrade_grant(asynchronous):
|
|
176
|
+
from unittest.mock import Mock, AsyncMock
|
|
177
|
+
import asyncio
|
|
178
|
+
from oneshot import OneShotClient
|
|
179
|
+
client = object.__new__(OneShotClient)
|
|
180
|
+
actions = ['read', 'reply', 'view_profile', 'invite']
|
|
181
|
+
result = {'intent_id': 'upgrade', 'type': 'reconnect', 'status': 'pending'}
|
|
182
|
+
if asynchronous:
|
|
183
|
+
client.acall_free_post = AsyncMock(return_value=result)
|
|
184
|
+
assert asyncio.run(client.areconnect_linkedin_account('account/id', requested_actions=actions)) == result
|
|
185
|
+
client.acall_free_post.assert_awaited_once_with('/v1/tools/linkedin/accounts/account%2Fid/reconnect', {'requested_actions': actions}, scope='write')
|
|
186
|
+
else:
|
|
187
|
+
client.call_free_post = Mock(return_value=result)
|
|
188
|
+
assert client.reconnect_linkedin_account('account/id', requested_actions=actions) == result
|
|
189
|
+
client.call_free_post.assert_called_once_with('/v1/tools/linkedin/accounts/account%2Fid/reconnect', {'requested_actions': actions}, scope='write')
|
|
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
|