oneshot-python 0.12.1__tar.gz → 0.14.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.
Files changed (20) hide show
  1. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/PKG-INFO +1 -1
  2. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/oneshot/client.py +36 -8
  3. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/pyproject.toml +1 -1
  4. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_tag_receipt_value.py +36 -2
  5. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/uv.lock +1 -1
  6. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/.gitignore +0 -0
  7. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/README.md +0 -0
  8. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/oneshot/__init__.py +0 -0
  9. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/oneshot/_errors.py +0 -0
  10. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/oneshot/_types.py +0 -0
  11. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/oneshot/x402.py +0 -0
  12. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/__init__.py +0 -0
  13. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_balance.py +0 -0
  14. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_compute.py +0 -0
  15. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_email_payload.py +0 -0
  16. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_emergency_error.py +0 -0
  17. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_max_cost_header.py +0 -0
  18. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_phones_pending.py +0 -0
  19. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_request_id.py +0 -0
  20. {oneshot_python-0.12.1 → oneshot_python-0.14.0}/tests/test_x402.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oneshot-python
3
- Version: 0.12.1
3
+ Version: 0.14.0
4
4
  Summary: Core Python SDK for the OneShot API — HTTP client with x402 payment handling
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -828,6 +828,22 @@ class OneShotClient:
828
828
  """Enrich a person's profile from LinkedIn URL, email, or name. Async."""
829
829
  return await self.acall_tool("/v1/tools/enrich/profile", kwargs)
830
830
 
831
+ def company_search(self, **kwargs: Any) -> Any:
832
+ """Search for companies by name, domain, industry, location, size, etc. Blocking."""
833
+ return self.call_tool("/v1/tools/research/company", kwargs)
834
+
835
+ async def acompany_search(self, **kwargs: Any) -> Any:
836
+ """Search for companies by name, domain, industry, location, size, etc. Async."""
837
+ return await self.acall_tool("/v1/tools/research/company", kwargs)
838
+
839
+ def enrich_company(self, **kwargs: Any) -> Any:
840
+ """Enrich a company from domain, name, LinkedIn URL, or ticker. Blocking."""
841
+ return self.call_tool("/v1/tools/enrich/company", kwargs)
842
+
843
+ async def aenrich_company(self, **kwargs: Any) -> Any:
844
+ """Enrich a company from domain, name, LinkedIn URL, or ticker. Async."""
845
+ return await self.acall_tool("/v1/tools/enrich/company", kwargs)
846
+
831
847
  def find_email(self, company_domain: str, *, full_name: Optional[str] = None, first_name: Optional[str] = None, last_name: Optional[str] = None, **kwargs: Any) -> Any:
832
848
  """Find a person's email address. Blocking."""
833
849
  payload: dict[str, Any] = {"company_domain": company_domain, **kwargs}
@@ -948,32 +964,44 @@ class OneShotClient:
948
964
 
949
965
  def tag_receipt_value(
950
966
  self,
951
- receipt_id: str,
952
- value_tag: dict[str, Any],
967
+ receipt_id: Optional[str] = None,
968
+ value_tag: Optional[dict[str, Any]] = None,
969
+ *,
970
+ request_id: Optional[str] = None,
953
971
  ) -> dict:
954
972
  """Tag a receipt with a value for RoCS computation. Blocking.
955
973
 
974
+ Identify the receipt by ``receipt_id`` (``rcpt_…``) or, equivalently, by
975
+ the ``request_id`` returned from the originating tool call — the API
976
+ resolves a ``request_id`` via the receipt's ``job_id``, so you can tag
977
+ value without a prior receipts lookup.
978
+
956
979
  ``value_tag`` shape: ``{"type": ..., "amount": ..., "label": ...}``.
957
980
  ``type`` must be one of ``revenue``, ``lead``, ``conversion``,
958
981
  ``savings``, ``engagement``. Tags are stored as ``pending`` until a
959
982
  judge service confirms them against inbound signals.
960
983
  """
961
984
  return asyncio.get_event_loop().run_until_complete(
962
- self.atag_receipt_value(receipt_id, value_tag)
985
+ self.atag_receipt_value(receipt_id, value_tag, request_id=request_id)
963
986
  )
964
987
 
965
988
  async def atag_receipt_value(
966
989
  self,
967
- receipt_id: str,
968
- value_tag: dict[str, Any],
990
+ receipt_id: Optional[str] = None,
991
+ value_tag: Optional[dict[str, Any]] = None,
992
+ *,
993
+ request_id: Optional[str] = None,
969
994
  ) -> dict:
970
995
  """Tag a receipt with a value for RoCS computation. Async."""
971
- if not receipt_id:
972
- raise ValidationError("receipt_id is required", "receipt_id")
996
+ target = receipt_id or request_id
997
+ if not target:
998
+ raise ValidationError(
999
+ "receipt_id or request_id is required", "receipt_id"
1000
+ )
973
1001
  if not isinstance(value_tag, dict) or not value_tag.get("type"):
974
1002
  raise ValidationError("value_tag.type is required", "value_tag.type")
975
1003
  return await self.acall_free_patch(
976
- f"/v1/analytics/receipts/{receipt_id}/value",
1004
+ f"/v1/analytics/receipts/{target}/value",
977
1005
  value_tag,
978
1006
  )
979
1007
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oneshot-python"
3
- version = "0.12.1"
3
+ version = "0.14.0"
4
4
  description = "Core Python SDK for the OneShot API — HTTP client with x402 payment handling"
5
5
  readme = {text = "Core Python SDK for the OneShot API", content-type = "text/plain"}
6
6
  license = "MIT"
@@ -70,18 +70,52 @@ async def test_accepts_minimal_valid_tag_with_just_type():
70
70
  mock.assert_awaited_once()
71
71
 
72
72
 
73
+ # ── Resolving by request_id (== job_id) instead of receipt_id ────────────
74
+
75
+ @pytest.mark.asyncio
76
+ async def test_tags_by_request_id():
77
+ # A request_id from the original tool call resolves server-side via job_id.
78
+ c, mock = _client_with_mocked_patch()
79
+ tag = {"type": "lead", "amount": 1}
80
+ await c.atag_receipt_value(value_tag=tag, request_id="0cbb87ee-1f2a-4c3d-9e8b-7a6f5d4c3b2a")
81
+ mock.assert_awaited_once_with(
82
+ "/v1/analytics/receipts/0cbb87ee-1f2a-4c3d-9e8b-7a6f5d4c3b2a/value", tag
83
+ )
84
+
85
+
86
+ @pytest.mark.asyncio
87
+ async def test_receipt_id_preferred_over_request_id():
88
+ c, mock = _client_with_mocked_patch()
89
+ tag = {"type": "revenue", "amount": 2}
90
+ await c.atag_receipt_value("rcpt_01HX", tag, request_id="some-uuid")
91
+ mock.assert_awaited_once_with("/v1/analytics/receipts/rcpt_01HX/value", tag)
92
+
93
+
94
+ @pytest.mark.asyncio
95
+ async def test_raises_when_neither_id_provided():
96
+ c, _ = _client_with_mocked_patch()
97
+ with pytest.raises(ValidationError) as excinfo:
98
+ await c.atag_receipt_value(value_tag={"type": "revenue", "amount": 1})
99
+ assert excinfo.value.field == "receipt_id"
100
+
101
+
73
102
  def test_sync_wrapper_delegates_to_async(monkeypatch):
74
103
  # The blocking ``tag_receipt_value`` should call through to the async
75
104
  # version via the event loop, matching every other tool method.
76
105
  c = OneShotClient(TEST_PRIVATE_KEY)
77
106
  called: dict = {}
78
107
 
79
- async def fake_async(receipt_id, value_tag):
108
+ async def fake_async(receipt_id=None, value_tag=None, *, request_id=None):
80
109
  called["receipt_id"] = receipt_id
81
110
  called["value_tag"] = value_tag
111
+ called["request_id"] = request_id
82
112
  return {"ok": True}
83
113
 
84
114
  c.atag_receipt_value = fake_async # type: ignore[method-assign]
85
115
  result = c.tag_receipt_value("rcpt_01HX", {"type": "savings", "amount": 12})
86
116
  assert result == {"ok": True}
87
- assert called == {"receipt_id": "rcpt_01HX", "value_tag": {"type": "savings", "amount": 12}}
117
+ assert called == {
118
+ "receipt_id": "rcpt_01HX",
119
+ "value_tag": {"type": "savings", "amount": 12},
120
+ "request_id": None,
121
+ }
@@ -549,7 +549,7 @@ wheels = [
549
549
 
550
550
  [[package]]
551
551
  name = "oneshot-python"
552
- version = "0.9.0"
552
+ version = "0.14.0"
553
553
  source = { editable = "." }
554
554
  dependencies = [
555
555
  { name = "eth-account" },