afp-sdk 0.6.0__tar.gz → 0.6.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 (72) hide show
  1. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/CHANGELOG.md +8 -1
  2. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/PKG-INFO +5 -3
  3. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/README.md +4 -2
  4. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/schemas.py +12 -3
  5. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/validators.py +15 -15
  6. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/pyproject.toml +1 -1
  7. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_validators.py +21 -11
  8. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/uv.lock +1 -1
  9. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/.env.template +0 -0
  10. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/.envrc +0 -0
  11. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/LICENSE +0 -0
  12. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/__init__.py +0 -0
  13. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/afp.py +0 -0
  14. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/__init__.py +0 -0
  15. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/admin.py +0 -0
  16. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/base.py +0 -0
  17. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/margin_account.py +0 -0
  18. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/product.py +0 -0
  19. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/api/trading.py +0 -0
  20. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/auth.py +0 -0
  21. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/__init__.py +0 -0
  22. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/admin_facet.py +0 -0
  23. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/clearing_facet.py +0 -0
  24. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/erc20.py +0 -0
  25. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/facade.py +0 -0
  26. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/final_settlement_facet.py +0 -0
  27. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/margin_account.py +0 -0
  28. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/margin_account_facet.py +0 -0
  29. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/margin_account_registry.py +0 -0
  30. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/mark_price_tracker_facet.py +0 -0
  31. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/oracle_provider.py +0 -0
  32. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/product_registry.py +0 -0
  33. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/product_registry_facet.py +0 -0
  34. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/system_viewer.py +0 -0
  35. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/bindings/types.py +0 -0
  36. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/config.py +0 -0
  37. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/constants.py +0 -0
  38. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/decorators.py +0 -0
  39. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/dtos.py +0 -0
  40. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/enums.py +0 -0
  41. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/exceptions.py +0 -0
  42. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/exchange.py +0 -0
  43. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/hashing.py +0 -0
  44. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/ipfs.py +0 -0
  45. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreiaw34o6l3rmatabzbds2i2myazdw2yolevcpsoyd2i2g3ms7wa2eq.json +0 -0
  46. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreibnfg6nq74dvpkre5rakkccij7iadp5rxpim7omsatjnrpmj3y7v4.json +0 -0
  47. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreicgr6dfo5yduixjkcifghiulskfegwojvuwodtouvivl362zndhxe.json +0 -0
  48. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreicheoypx6synljushh7mq2572iyhlolf4nake2p5dwobgnj3r5eua.json +0 -0
  49. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreid35a67db4sqh4fs6boddyt2xvscbqy6nqvsp5jjur56qhkw4ixre.json +0 -0
  50. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreidzs7okcpqiss6ztftltyptqwnw5e5opsy5yntospekjha4kpykaa.json +0 -0
  51. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreifcec2km7hxwq6oqzjlspni2mgipetjb7pqtaewh2efislzoctboi.json +0 -0
  52. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreihn3oiaxffe4e2w7pwtreadpw3obfd7gqlogbcxm56jc2hzfvco74.json +0 -0
  53. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/json-schemas/bafyreihur3dzwhja6uxsbcw6eeoj3xmmc4e3zkmyzpot5v5dleevxe5zam.json +0 -0
  54. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/py.typed +0 -0
  55. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/afp/types.py +0 -0
  56. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/devenv.lock +0 -0
  57. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/devenv.nix +0 -0
  58. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/devenv.yaml +0 -0
  59. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/examples/cancel_order.py +0 -0
  60. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/examples/create_product.py +0 -0
  61. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/examples/execute_trade.py +0 -0
  62. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/examples/prediction-product-example.json +0 -0
  63. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/__init__.py +0 -0
  64. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/assets/test.key +0 -0
  65. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_afp.py +0 -0
  66. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_base_api.py +0 -0
  67. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_decorators.py +0 -0
  68. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_exchange_client.py +0 -0
  69. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_hashing.py +0 -0
  70. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_product_api.py +0 -0
  71. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_schemas.py +0 -0
  72. {afp_sdk-0.6.0 → afp_sdk-0.6.1}/tests/test_signing.py +0 -0
@@ -1,4 +1,10 @@
1
- ## [v0.6.0] - 2026-01-22
1
+ ## [v0.6.1] - 2026-02-03
2
+
3
+ ### Changed
4
+
5
+ - Fix incomplete template variable validation in product specifications ([#54](https://github.com/autonity/afp-sdk/pull/54))
6
+
7
+ ## [v0.6.0] - 2026-01-28
2
8
 
3
9
  ### Added
4
10
 
@@ -102,6 +108,7 @@
102
108
 
103
109
  _First public release for Forecastathon._
104
110
 
111
+ [v0.6.1]: https://github.com/autonity/afp-sdk/releases/tag/v0.6.1
105
112
  [v0.6.0]: https://github.com/autonity/afp-sdk/releases/tag/v0.6.0
106
113
  [v0.5.4]: https://github.com/autonity/afp-sdk/releases/tag/v0.5.4
107
114
  [v0.5.3]: https://github.com/autonity/afp-sdk/releases/tag/v0.5.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afp-sdk
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Autonomous Futures Protocol Python SDK
5
5
  Keywords: autonity,web3,trading,crypto,prediction,forecast,markets
6
6
  License-Expression: MIT
@@ -256,8 +256,10 @@ tx = product.register(
256
256
  )
257
257
  ```
258
258
 
259
- See further code examples in the [examples](./examples/) directory.
259
+ See further code examples in the
260
+ [examples](https://github.com/autonity/afp-sdk/tree/master/examples/) directory.
260
261
 
261
262
  ## Development
262
263
 
263
- See [DEVELOPMENT.md](./DEVELOPMENT.md) for developer documentation.
264
+ See [DEVELOPMENT.md](https://github.com/autonity/afp-sdk/blob/master/DEVELOPMENT.md)
265
+ for developer documentation.
@@ -227,8 +227,10 @@ tx = product.register(
227
227
  )
228
228
  ```
229
229
 
230
- See further code examples in the [examples](./examples/) directory.
230
+ See further code examples in the
231
+ [examples](https://github.com/autonity/afp-sdk/tree/master/examples/) directory.
231
232
 
232
233
  ## Development
233
234
 
234
- See [DEVELOPMENT.md](./DEVELOPMENT.md) for developer documentation.
235
+ See [DEVELOPMENT.md](https://github.com/autonity/afp-sdk/blob/master/DEVELOPMENT.md)
236
+ for developer documentation.
@@ -1,6 +1,7 @@
1
1
  """AFP data structures."""
2
2
 
3
3
  from decimal import Decimal
4
+ from itertools import chain
4
5
  from typing import Annotated, Any, ClassVar, Literal, Self
5
6
 
6
7
  from pydantic import AfterValidator, BeforeValidator, Field, model_validator
@@ -321,9 +322,17 @@ class PredictionProduct(Model):
321
322
  self.product.min_price,
322
323
  self.product.max_price,
323
324
  )
324
- validators.validate_outcome_space_conditions(
325
- self.outcome_space.base_case.condition,
326
- [case.condition for case in self.outcome_space.edge_cases],
325
+ validators.validate_outcome_space_template_variables(
326
+ [
327
+ self.outcome_space.base_case.condition,
328
+ self.outcome_space.base_case.fsp_resolution,
329
+ ]
330
+ + list(
331
+ chain.from_iterable(
332
+ [edge_case.condition, edge_case.fsp_resolution]
333
+ for edge_case in self.outcome_space.edge_cases
334
+ )
335
+ ),
327
336
  self.outcome_point.model_dump(),
328
337
  )
329
338
  if isinstance(self.outcome_space, OutcomeSpaceTimeSeries) and isinstance(
@@ -3,7 +3,7 @@ from datetime import date, datetime, timedelta
3
3
  from decimal import Decimal
4
4
  from functools import reduce
5
5
  from operator import getitem
6
- from typing import Any
6
+ from typing import Any, Iterable
7
7
 
8
8
  import requests
9
9
  from binascii import Error
@@ -178,23 +178,23 @@ def validate_oracle_fallback_fsp(
178
178
  )
179
179
 
180
180
 
181
- def validate_outcome_space_conditions(
182
- base_case_condition: str,
183
- edge_case_conditions: list[str],
184
- outcome_point_dict: dict[Any, Any],
181
+ def validate_outcome_space_template_variables(
182
+ values: Iterable[str], outcome_point_dict: dict[Any, Any]
185
183
  ) -> None:
186
- conditions = [base_case_condition] + edge_case_conditions
187
- schemas = ["BaseCaseResolution"] + [
188
- f"EdgeCase[{i}]" for i in range(len(edge_case_conditions))
189
- ]
190
- for condition, schema in zip(conditions, schemas):
191
- for variable in re.findall(r"{(.+?)}", condition):
192
- parts = variable.split(".")
184
+ for value in values:
185
+ for variable in re.findall(r"{(.*?)}", value):
193
186
  try:
194
- reduce(getitem, parts, outcome_point_dict)
195
- except KeyError:
187
+ referred_value = reduce(
188
+ getitem, variable.split("."), outcome_point_dict
189
+ )
190
+ except (TypeError, KeyError):
191
+ raise ValueError(
192
+ f"OutcomeSpace: Invalid template variable '{variable}'"
193
+ )
194
+ if isinstance(referred_value, dict) or isinstance(referred_value, list): # type: ignore
196
195
  raise ValueError(
197
- f"{schema}: condition: Invalid template variable '{variable}'"
196
+ f"OutcomeSpace: Template variable '{variable}' "
197
+ "should not refer to a nested object or list"
198
198
  )
199
199
 
200
200
 
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "afp-sdk"
7
- version = "0.6.0"
7
+ version = "0.6.1"
8
8
  description = "Autonomous Futures Protocol Python SDK"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -110,7 +110,7 @@ def test_validate_price_limits__error():
110
110
  validators.validate_price_limits(Decimal("0.11"), Decimal("0.10"))
111
111
 
112
112
 
113
- def test_validate_outcome_space_conditions__pass():
113
+ def test_validate_outcome_space_template_variables__pass():
114
114
  dct = {
115
115
  "a": {
116
116
  "b": {
@@ -119,15 +119,29 @@ def test_validate_outcome_space_conditions__pass():
119
119
  },
120
120
  },
121
121
  }
122
- base_case_condition = "Reference to {a.b.c}"
123
- edge_case_conditions = ["And to {a.b.d} as well"]
124
122
 
125
- validators.validate_outcome_space_conditions(
126
- base_case_condition, edge_case_conditions, dct
123
+ validators.validate_outcome_space_template_variables(
124
+ [
125
+ "Reference to {a.b.c} should pass",
126
+ "And to {a.b.d} as well",
127
+ "So as having no template variable",
128
+ ],
129
+ dct,
127
130
  )
128
131
 
129
132
 
130
- def test_validate_outcome_space_conditions__error():
133
+ @pytest.mark.parametrize(
134
+ "value",
135
+ [
136
+ "{a.b.c} and {a.b.e}",
137
+ "{c}",
138
+ "{a.b.c.d}",
139
+ "{a.b}",
140
+ "{}",
141
+ ],
142
+ ids=str,
143
+ )
144
+ def test_validate_outcome_space_tempate_variables__error(value):
131
145
  dct = {
132
146
  "a": {
133
147
  "b": {
@@ -136,13 +150,9 @@ def test_validate_outcome_space_conditions__error():
136
150
  },
137
151
  },
138
152
  }
139
- base_case_condition = "Reference to {a.b.e}"
140
- edge_case_conditions = []
141
153
 
142
154
  with pytest.raises(ValueError):
143
- validators.validate_outcome_space_conditions(
144
- base_case_condition, edge_case_conditions, dct
145
- )
155
+ validators.validate_outcome_space_template_variables([value], dct)
146
156
 
147
157
 
148
158
  @pytest.mark.parametrize(
@@ -13,7 +13,7 @@ wheels = [
13
13
 
14
14
  [[package]]
15
15
  name = "afp-sdk"
16
- version = "0.6.0"
16
+ version = "0.6.1"
17
17
  source = { editable = "." }
18
18
  dependencies = [
19
19
  { name = "dag-cbor" },
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