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.
Files changed (33) hide show
  1. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/PKG-INFO +1 -1
  2. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/client.py +2 -2
  3. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/pyproject.toml +1 -1
  4. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_linkedin.py +19 -1
  5. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/.gitignore +0 -0
  6. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/README.md +0 -0
  7. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/__init__.py +0 -0
  8. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/_errors.py +0 -0
  9. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/_types.py +0 -0
  10. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/physical_mail.py +0 -0
  11. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/oneshot/x402.py +0 -0
  12. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/__init__.py +0 -0
  13. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/conftest.py +0 -0
  14. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_access_token.py +0 -0
  15. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_balance.py +0 -0
  16. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_browser.py +0 -0
  17. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_budgets.py +0 -0
  18. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_charge_amount.py +0 -0
  19. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_compute.py +0 -0
  20. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_domains.py +0 -0
  21. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_email_payload.py +0 -0
  22. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_emergency_error.py +0 -0
  23. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_max_cost_header.py +0 -0
  24. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_payment_rejection.py +0 -0
  25. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_phones_pending.py +0 -0
  26. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_physical_mail.py +0 -0
  27. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_poll_backoff.py +0 -0
  28. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_request_id.py +0 -0
  29. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_tag_receipt_value.py +0 -0
  30. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_top_up_credits.py +0 -0
  31. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_wait_false.py +0 -0
  32. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/tests/test_x402.py +0 -0
  33. {oneshot_python-0.29.0 → oneshot_python-0.29.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: oneshot-python
3
- Version: 0.29.0
3
+ Version: 0.29.1
4
4
  Summary: Core Python SDK for the OneShot API — HTTP client with x402 payment handling — 45 tools
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -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.0"
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 (keeps ownership; may narrow, never widen, the grant). Free."""
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.0"
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": "grant_widening_not_allowed"}, False),
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