Skip to content

Spot Trade Busts#48

Open
arturbeg wants to merge 2 commits intomainfrom
feat/bustSeq
Open

Spot Trade Busts#48
arturbeg wants to merge 2 commits intomainfrom
feat/bustSeq

Conversation

@arturbeg
Copy link
Collaborator

@arturbeg arturbeg commented Mar 11, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added spot trade bust data retrieval with market and wallet endpoints supporting time-range filtering
    • New client method to fetch spot trade busts for wallet
    • Added async channel support for real-time spot trade bust updates
  • Version Updates

    • OpenAPI specification updated to v2.1.5

@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

This PR introduces spot trade bust functionality to the SDK. New models SpotTradeBust and SpotTradeBustList are added to both async and OpenAPI layers, along with payload models for channel updates. New API endpoints are added to fetch spot trade busts from market and wallet data sources. The OpenAPI document version is updated from 2.1.4 to 2.1.5 across all files.

Changes

Cohort / File(s) Summary
New Core Models
sdk/open_api/models/spot_trade_bust.py, sdk/open_api/models/spot_trade_bust_list.py
Introduces Pydantic v2 models with strict typing, field validators (regex for symbol/qty/price), custom serialization (to_dict, from_dict, to_json, from_json), alias-based field mapping (accountId, counterpartyAccountId, transactionHash), and dynamic property support via additional_properties. Both models use ConfigDict for populate_by_name and validate_assignment.
Async API Payload Models
sdk/async_api/spot_trade_bust.py, sdk/async_api/market_spot_trade_bust_update_payload.py, sdk/async_api/wallet_spot_trade_bust_update_payload.py
Adds async-layer Pydantic models mirroring OpenAPI models with custom serialization helpers, validators for unwrapping unknown JSON properties into additional_properties, and payload containers for channel-based updates with type, timestamp, channel, and data fields.
Market Data API Endpoints
sdk/open_api/api/market_data_api.py
Introduces get_market_spot_trade_busts() method and variants (with_http_info, without_preload_content) with request serializer _get_market_spot_trade_busts_serialize(). Handles GET /market/{symbol}/spotTradeBusts with startTime/endTime query parameters and response mappings for 200/400/500 status codes.
Wallet Data API Endpoints
sdk/open_api/api/wallet_data_api.py
Adds get_wallet_spot_trade_busts() method and variants with serializer _get_wallet_spot_trade_busts_serialize(). Handles GET /wallet/{address}/spotTradeBusts with optional start_time/end_time parameters and consistent response type mapping.
Client-Level Wrapper
sdk/reya_rest_api/client.py
Introduces public get_spot_trade_busts() method on ReyaTradingClient that validates wallet address and delegates to wallet API.
Export and Configuration Updates
sdk/open_api/__init__.py, sdk/open_api/models/__init__.py
Adds SpotTradeBust and SpotTradeBustList to public exports and all lists.
Version Bump — Metadata Only
sdk/open_api/api/order_entry_api.py, sdk/open_api/api/reference_data_api.py, sdk/open_api/api/specs_api.py, sdk/open_api/api_client.py, sdk/open_api/configuration.py, sdk/open_api/exceptions.py, sdk/open_api/rest.py, sdk/open_api/models/*.py (40+ files)
Updates OpenAPI document version from 2.1.4 to 2.1.5 in module docstrings and header comments. No functional code changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • tomdevman

Poem

🐰 Hops with glee through market lanes,
Trade busts tracked in spotless chains,
Models dance with validators true,
APIs bloom—new endpoints grew,
From 2.1.4 to five we've sprung!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Spot Trade Busts' directly describes the main feature addition: new spot trade bust models, API endpoints, and client methods across the SDK.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/bustSeq

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

🤖 SDK Version Check

Version check passed

  • SDK version: ``
  • Specs tag: ``
  • All consistency checks passed

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/open_api/__init__.py (1)

10-17: ⚠️ Potential issue | 🟡 Minor

Bump sdk.open_api.__version__ with this 2.1.5 regen.

The module docstring now reports 2.1.5, but Line 17 still exposes 2.1.4.0. That leaves runtime version reporting out of sync with the generated models and endpoints shipped by this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/open_api/__init__.py` around lines 10 - 17, Update the module-level
__version__ constant to match the regenerated OpenAPI document version; change
__version__ in sdk.open_api.__init__ from "2.1.4.0" to the regenerated version
"2.1.5" (update the __version__ symbol so runtime version reporting matches the
docstring and generated models/endpoints).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk/async_api/market_spot_trade_bust_update_payload.py`:
- Around line 2-10: Replace the typing.List usage with Python 3.12 built-in
generics and clean up unused typing imports: change the type annotation for
MarketSpotTradeBustUpdatePayload.data from List[SpotTradeBust] to
list[SpotTradeBust], remove the now-unused List (and any other unused imports
like Any/Dict/Optional) from the top-of-file imports, and keep the rest of the
model (fields type names and Field(...) usage) unchanged.

In `@sdk/async_api/spot_trade_bust.py`:
- Around line 3-15: The SpotTradeBust Pydantic model exposes snake_case
attributes but lacks a Pydantic v2 config to allow construction using those
names; add a model_config = {"populate_by_name": True} to the SpotTradeBust
class so callers can instantiate with account_id, counterparty_account_id,
transaction_hash (and existing alias fields still function). This change should
be made on the SpotTradeBust class (the BaseModel subclass) alongside the
existing fields (symbol, account_id/accountId alias,
counterparty_account_id/counterpartyAccountId alias,
transaction_hash/transactionHash alias).
- Around line 29-47: The pre-validator unwrap_additional_properties assumes
non-dict inputs implement model_dump and that additional_properties is a dict;
guard by first checking if data is a dict and if not, only try to call
data.model_dump() when hasattr(data, "model_dump"), otherwise return data
unchanged so scalars/None/lists bypass this unwrapping; then ensure
additional_properties = data.get('additional_properties') and if it's None or
not isinstance(additional_properties, dict) set it to {} before merging unknown
keys; also prefer Python "in" checks (e.g., if obj_key not in
known_json_properties) when iterating unknown_object_properties in
unwrap_additional_properties.

In `@sdk/async_api/wallet_spot_trade_bust_update_payload.py`:
- Around line 2-10: The payload model WalletSpotTradeBustUpdatePayload is using
typing.List which triggers UP035; change the data field to use the built-in
generic list[SpotTradeBust] instead of List[SpotTradeBust], update the import
list to remove List (keep Any, Dict, Optional only if used) and ensure the Field
declaration for data remains the same; this replaces the typing generic with
Python 3.12+ built-in generics while leaving the class name, type annotations
(type, timestamp, channel), and SpotTradeBust reference unchanged.

In `@sdk/open_api/api/market_data_api.py`:
- Around line 1218-1225: The generated endpoint stub uses old-style typing
(Union[...]) for the parameter _request_timeout in market_data_api.py; update
the OpenAPI generator template or add a post-processing step so generated
signatures use Python 3.10+ union syntax (e.g., replace Union[...] with the pipe
operator) and stop emitting typing_extensions/typing.List style imports—ensure
the generator produces annotations like None | float | tuple[float, float] for
_request_timeout and that model imports target built-in typing for Python 3.12
compatibility rather than typing_extensions.

In `@sdk/open_api/configuration.py`:
- Around line 496-500: The debug report return currently hard-codes "SDK Package
Version: 2.1.4.0" and uses implicit multi-line string concatenation; update the
return expression in configuration.py to use the canonical
sdk.open_api.__version__ value instead of the literal and collapse the
multi-line strings into a single parenthesized string expression (e.g., return
("Python SDK Debug Report:\nOS: {env}\nPython Version: {pyversion}\nVersion of
the API: 2.1.5\nSDK Package Version: " + sdk.open_api.__version__)). Ensure you
import or reference sdk.open_api.__version__ where this return is defined so the
debug report always reflects the package metadata and removes the Ruff ISC002
warning.

In `@sdk/reya_rest_api/client.py`:
- Around line 708-722: The get_spot_trade_busts wrapper currently hardcodes the
call and prevents callers from using the wallet endpoint's pagination/time
filters; update ReyaTradingClient.get_spot_trade_busts to accept optional
parameters (e.g., start_time, end_time, page, page_size) and forward them to
self.wallet.get_wallet_spot_trade_busts(address=wallet, start_time=start_time,
end_time=end_time, page=page, page_size=page_size), preserving existing behavior
when arguments are None and validating wallet via self.owner_wallet_address as
before.

---

Outside diff comments:
In `@sdk/open_api/__init__.py`:
- Around line 10-17: Update the module-level __version__ constant to match the
regenerated OpenAPI document version; change __version__ in
sdk.open_api.__init__ from "2.1.4.0" to the regenerated version "2.1.5" (update
the __version__ symbol so runtime version reporting matches the docstring and
generated models/endpoints).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4fa2a381-7d42-493b-85c0-159c1f9c5d7a

📥 Commits

Reviewing files that changed from the base of the PR and between a5a97d9 and 8321bc8.

📒 Files selected for processing (58)
  • .openapi-generator/FILES
  • sdk/async_api/market_spot_trade_bust_update_payload.py
  • sdk/async_api/spot_trade_bust.py
  • sdk/async_api/wallet_spot_trade_bust_update_payload.py
  • sdk/open_api/__init__.py
  • sdk/open_api/api/market_data_api.py
  • sdk/open_api/api/order_entry_api.py
  • sdk/open_api/api/reference_data_api.py
  • sdk/open_api/api/specs_api.py
  • sdk/open_api/api/wallet_data_api.py
  • sdk/open_api/api_client.py
  • sdk/open_api/configuration.py
  • sdk/open_api/exceptions.py
  • sdk/open_api/models/__init__.py
  • sdk/open_api/models/account.py
  • sdk/open_api/models/account_balance.py
  • sdk/open_api/models/account_type.py
  • sdk/open_api/models/asset_definition.py
  • sdk/open_api/models/cancel_order_request.py
  • sdk/open_api/models/cancel_order_response.py
  • sdk/open_api/models/candle_history_data.py
  • sdk/open_api/models/create_order_request.py
  • sdk/open_api/models/create_order_response.py
  • sdk/open_api/models/depth.py
  • sdk/open_api/models/depth_type.py
  • sdk/open_api/models/execution_type.py
  • sdk/open_api/models/fee_tier_parameters.py
  • sdk/open_api/models/global_fee_parameters.py
  • sdk/open_api/models/level.py
  • sdk/open_api/models/liquidity_parameters.py
  • sdk/open_api/models/market_definition.py
  • sdk/open_api/models/market_summary.py
  • sdk/open_api/models/mass_cancel_request.py
  • sdk/open_api/models/mass_cancel_response.py
  • sdk/open_api/models/order.py
  • sdk/open_api/models/order_status.py
  • sdk/open_api/models/order_type.py
  • sdk/open_api/models/pagination_meta.py
  • sdk/open_api/models/perp_execution.py
  • sdk/open_api/models/perp_execution_list.py
  • sdk/open_api/models/position.py
  • sdk/open_api/models/price.py
  • sdk/open_api/models/request_error.py
  • sdk/open_api/models/request_error_code.py
  • sdk/open_api/models/server_error.py
  • sdk/open_api/models/server_error_code.py
  • sdk/open_api/models/side.py
  • sdk/open_api/models/spot_execution.py
  • sdk/open_api/models/spot_execution_list.py
  • sdk/open_api/models/spot_market_definition.py
  • sdk/open_api/models/spot_trade_bust.py
  • sdk/open_api/models/spot_trade_bust_list.py
  • sdk/open_api/models/tier_type.py
  • sdk/open_api/models/time_in_force.py
  • sdk/open_api/models/wallet_configuration.py
  • sdk/open_api/rest.py
  • sdk/reya_rest_api/client.py
  • specs

Comment on lines +2 to +10
from typing import Any, List, Dict, Optional
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class MarketSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for market spot trade busts''')
data: List[SpotTradeBust] = Field()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use built-in generics in this new payload model.

Ruff is already flagging UP035 here. With the repo's Python 3.12 baseline, list[SpotTradeBust] should replace List[SpotTradeBust] in new code.

♻️ Minimal cleanup
-from typing import Any, List, Dict, Optional
 from pydantic import BaseModel, Field
 from sdk.async_api.channel_data_message_type import ChannelDataMessageType
 from sdk.async_api.spot_trade_bust import SpotTradeBust
 class MarketSpotTradeBustUpdatePayload(BaseModel): 
   type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
   timestamp: float = Field(description='''Update timestamp (milliseconds)''')
   channel: str = Field(description='''Channel pattern for market spot trade busts''')
-  data: List[SpotTradeBust] = Field()
+  data: list[SpotTradeBust] = Field()

As per coding guidelines, "Require Python 3.12+ for runtime and Python 3.10 for type checking with strict mypy configuration".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from typing import Any, List, Dict, Optional
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class MarketSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for market spot trade busts''')
data: List[SpotTradeBust] = Field()
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class MarketSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for market spot trade busts''')
data: list[SpotTradeBust] = Field()
🧰 Tools
🪛 Ruff (0.15.5)

[warning] 2-2: typing.List is deprecated, use list instead

(UP035)


[warning] 2-2: typing.Dict is deprecated, use dict instead

(UP035)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/async_api/market_spot_trade_bust_update_payload.py` around lines 2 - 10,
Replace the typing.List usage with Python 3.12 built-in generics and clean up
unused typing imports: change the type annotation for
MarketSpotTradeBustUpdatePayload.data from List[SpotTradeBust] to
list[SpotTradeBust], remove the now-unused List (and any other unused imports
like Any/Dict/Optional) from the top-of-file imports, and keep the rest of the
model (fields type names and Field(...) usage) unchanged.

Comment on lines +3 to +15
from pydantic import model_serializer, model_validator, BaseModel, Field
from sdk.async_api.side import Side
class SpotTradeBust(BaseModel):
symbol: str = Field(description='''Trading symbol (e.g., BTCRUSDPERP, WETHRUSD)''')
account_id: int = Field(alias='''accountId''')
counterparty_account_id: int = Field(alias='''counterpartyAccountId''')
qty: str = Field()
side: Side = Field(description='''Order side (B = Buy/Bid, A = Ask/Sell)''')
price: str = Field()
reason: str = Field(description='''Hex-encoded revert reason bytes''')
timestamp: int = Field()
transaction_hash: str = Field(description='''Transaction hash''', alias='''transactionHash''')
additional_properties: Optional[dict[str, Any]] = Field(default=None, exclude=True)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the async spot trade bust file
find . -name "spot_trade_bust.py" -type f

Repository: Reya-Labs/reya-python-sdk

Length of output: 144


🏁 Script executed:

# Now let's examine the async model file to see lines 3-15 and the full file
cat -n sdk/async_api/spot_trade_bust.py | head -50

Repository: Reya-Labs/reya-python-sdk

Length of output: 2819


🏁 Script executed:

# Let's check the OpenAPI counterpart for comparison
cat -n sdk/open_api/models/spot_trade_bust.py | head -80

Repository: Reya-Labs/reya-python-sdk

Length of output: 3737


🏁 Script executed:

# Check if model_config is used elsewhere in the async_api directory
rg "model_config\s*=" sdk/async_api/ -A 2

Repository: Reya-Labs/reya-python-sdk

Length of output: 51


🏁 Script executed:

# Let's verify Pydantic v2 behavior with aliases and populate_by_name
python3 << 'EOF'
from pydantic import BaseModel, Field, ConfigDict

# Test case 1: Without populate_by_name (like the async model)
class ModelWithoutPopulate(BaseModel):
    account_id: int = Field(alias='accountId')

# Test case 2: With populate_by_name (like the OpenAPI model)
class ModelWithPopulate(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    account_id: int = Field(alias='accountId')

print("Test 1: Without populate_by_name")
try:
    m1 = ModelWithoutPopulate(account_id=123)
    print(f"  Success: {m1}")
except Exception as e:
    print(f"  Failed: {type(e).__name__}: {e}")

try:
    m1 = ModelWithoutPopulate(accountId=123)
    print(f"  Success with alias: {m1}")
except Exception as e:
    print(f"  Failed with alias: {type(e).__name__}: {e}")

print("\nTest 2: With populate_by_name")
try:
    m2 = ModelWithPopulate(account_id=123)
    print(f"  Success: {m2}")
except Exception as e:
    print(f"  Failed: {type(e).__name__}: {e}")

try:
    m2 = ModelWithPopulate(accountId=123)
    print(f"  Success with alias: {m2}")
except Exception as e:
    print(f"  Failed with alias: {type(e).__name__}: {e}")
EOF

Repository: Reya-Labs/reya-python-sdk

Length of output: 472


🏁 Script executed:

# Check if there are any existing usages of SpotTradeBust in async_api that might reveal the issue
rg "SpotTradeBust" sdk/async_api/ -B 2 -A 5

Repository: Reya-Labs/reya-python-sdk

Length of output: 2707


🏁 Script executed:

# Check line length to verify it complies with the 120 character limit
python3 << 'EOF'
with open('sdk/async_api/spot_trade_bust.py', 'r') as f:
    lines = f.readlines()
    for i, line in enumerate(lines[2:16], start=3):  # lines 3-15
        line_len = len(line.rstrip('\n'))
        status = "OK" if line_len <= 120 else "EXCEEDS"
        print(f"Line {i}: {line_len:3d} chars {status}")
        if line_len > 120:
            print(f"  Content: {line.rstrip()}")
EOF

Repository: Reya-Labs/reya-python-sdk

Length of output: 369


Add populate_by_name=True to enable snake_case field construction.

This model has aliased fields (accountId, counterpartyAccountId, transactionHash) but lacks populate_by_name in its config, so SpotTradeBust(account_id=..., transaction_hash=...) will fail even though the class exposes snake_case attributes. The OpenAPI counterpart already enables this, creating an inconsistency.

🔧 Suggested fix
-from pydantic import model_serializer, model_validator, BaseModel, Field
+from pydantic import ConfigDict, model_serializer, model_validator, BaseModel, Field
 from sdk.async_api.side import Side
 class SpotTradeBust(BaseModel): 
+  model_config = ConfigDict(populate_by_name=True)
   symbol: str = Field(description='''Trading symbol (e.g., BTCRUSDPERP, WETHRUSD)''')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/async_api/spot_trade_bust.py` around lines 3 - 15, The SpotTradeBust
Pydantic model exposes snake_case attributes but lacks a Pydantic v2 config to
allow construction using those names; add a model_config = {"populate_by_name":
True} to the SpotTradeBust class so callers can instantiate with account_id,
counterparty_account_id, transaction_hash (and existing alias fields still
function). This change should be made on the SpotTradeBust class (the BaseModel
subclass) alongside the existing fields (symbol, account_id/accountId alias,
counterparty_account_id/counterpartyAccountId alias,
transaction_hash/transactionHash alias).

Comment on lines +29 to +47
@model_validator(mode='before')
@classmethod
def unwrap_additional_properties(cls, data):
if not isinstance(data, dict):
data = data.model_dump()
json_properties = list(data.keys())
known_object_properties = ['symbol', 'account_id', 'counterparty_account_id', 'qty', 'side', 'price', 'reason', 'timestamp', 'transaction_hash', 'additional_properties']
unknown_object_properties = [element for element in json_properties if element not in known_object_properties]
# Ignore attempts that validate regular models, only when unknown input is used we add unwrap extensions
if len(unknown_object_properties) == 0:
return data

known_json_properties = ['symbol', 'accountId', 'counterpartyAccountId', 'qty', 'side', 'price', 'reason', 'timestamp', 'transactionHash', 'additionalProperties']
additional_properties = data.get('additional_properties', {})
for obj_key in unknown_object_properties:
if not known_json_properties.__contains__(obj_key):
additional_properties[obj_key] = data.pop(obj_key, None)
data['additional_properties'] = additional_properties
return data
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard the pre-validator against non-model inputs.

unwrap_additional_properties currently assumes every non-dict input has model_dump(). None, scalars, or lists will raise AttributeError, and additional_properties=None will raise TypeError as soon as an unknown key is merged, so malformed payloads bypass normal validation errors.

🔧 Suggested fix
   `@model_validator`(mode='before')
   `@classmethod`
-  def unwrap_additional_properties(cls, data):
-    if not isinstance(data, dict):
-      data = data.model_dump()
+  def unwrap_additional_properties(cls, data: Any) -> Any:
+    if isinstance(data, BaseModel):
+      data = data.model_dump()
+    elif not isinstance(data, dict):
+      return data
     json_properties = list(data.keys())
     known_object_properties = ['symbol', 'account_id', 'counterparty_account_id', 'qty', 'side', 'price', 'reason', 'timestamp', 'transaction_hash', 'additional_properties']
     unknown_object_properties = [element for element in json_properties if element not in known_object_properties]
     # Ignore attempts that validate regular models, only when unknown input is used we add unwrap extensions
     if len(unknown_object_properties) == 0: 
       return data
   
     known_json_properties = ['symbol', 'accountId', 'counterpartyAccountId', 'qty', 'side', 'price', 'reason', 'timestamp', 'transactionHash', 'additionalProperties']
-    additional_properties = data.get('additional_properties', {})
+    additional_properties = data.get('additional_properties') or {}
🧰 Tools
🪛 Ruff (0.15.5)

[warning] 31-31: Missing return type annotation for classmethod unwrap_additional_properties

(ANN206)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/async_api/spot_trade_bust.py` around lines 29 - 47, The pre-validator
unwrap_additional_properties assumes non-dict inputs implement model_dump and
that additional_properties is a dict; guard by first checking if data is a dict
and if not, only try to call data.model_dump() when hasattr(data, "model_dump"),
otherwise return data unchanged so scalars/None/lists bypass this unwrapping;
then ensure additional_properties = data.get('additional_properties') and if
it's None or not isinstance(additional_properties, dict) set it to {} before
merging unknown keys; also prefer Python "in" checks (e.g., if obj_key not in
known_json_properties) when iterating unknown_object_properties in
unwrap_additional_properties.

Comment on lines +2 to +10
from typing import Any, List, Dict, Optional
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class WalletSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for wallet spot trade busts''')
data: List[SpotTradeBust] = Field()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use built-in generics in this new payload model.

Ruff is already flagging UP035 here. With the repo's Python 3.12 baseline, list[SpotTradeBust] should replace List[SpotTradeBust] in new code.

♻️ Minimal cleanup
-from typing import Any, List, Dict, Optional
 from pydantic import BaseModel, Field
 from sdk.async_api.channel_data_message_type import ChannelDataMessageType
 from sdk.async_api.spot_trade_bust import SpotTradeBust
 class WalletSpotTradeBustUpdatePayload(BaseModel): 
   type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
   timestamp: float = Field(description='''Update timestamp (milliseconds)''')
   channel: str = Field(description='''Channel pattern for wallet spot trade busts''')
-  data: List[SpotTradeBust] = Field()
+  data: list[SpotTradeBust] = Field()

As per coding guidelines, "Require Python 3.12+ for runtime and Python 3.10 for type checking with strict mypy configuration".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from typing import Any, List, Dict, Optional
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class WalletSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for wallet spot trade busts''')
data: List[SpotTradeBust] = Field()
from typing import Any, Dict, Optional
from pydantic import BaseModel, Field
from sdk.async_api.channel_data_message_type import ChannelDataMessageType
from sdk.async_api.spot_trade_bust import SpotTradeBust
class WalletSpotTradeBustUpdatePayload(BaseModel):
type: ChannelDataMessageType = Field(description='''Message type for channel data updates''')
timestamp: float = Field(description='''Update timestamp (milliseconds)''')
channel: str = Field(description='''Channel pattern for wallet spot trade busts''')
data: list[SpotTradeBust] = Field()
🧰 Tools
🪛 Ruff (0.15.5)

[warning] 2-2: typing.List is deprecated, use list instead

(UP035)


[warning] 2-2: typing.Dict is deprecated, use dict instead

(UP035)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/async_api/wallet_spot_trade_bust_update_payload.py` around lines 2 - 10,
The payload model WalletSpotTradeBustUpdatePayload is using typing.List which
triggers UP035; change the data field to use the built-in generic
list[SpotTradeBust] instead of List[SpotTradeBust], update the import list to
remove List (keep Any, Dict, Optional only if used) and ensure the Field
declaration for data remains the same; this replaces the typing generic with
Python 3.12+ built-in generics while leaving the class name, type annotations
(type, timestamp, channel), and SpotTradeBust reference unchanged.

Comment on lines +1218 to +1225
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Regenerate these stubs with Python 3.10+ annotations.

The new OpenAPI output is still emitting Union[...] here, and the same generation pass is adding typing_extensions / typing.List-style imports in the new models. In a Python 3.12-targeted repo this just keeps adding avoidable lint debt, so please fix the generator template or post-processing step instead of hand-editing each endpoint.

As per coding guidelines, "Require Python 3.12+ for runtime and Python 3.10 for type checking with strict mypy configuration".

🧰 Tools
🪛 Ruff (0.15.5)

[warning] 1218-1225: Use X | Y for type annotations

Convert to X | Y

(UP007)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/open_api/api/market_data_api.py` around lines 1218 - 1225, The generated
endpoint stub uses old-style typing (Union[...]) for the parameter
_request_timeout in market_data_api.py; update the OpenAPI generator template or
add a post-processing step so generated signatures use Python 3.10+ union syntax
(e.g., replace Union[...] with the pipe operator) and stop emitting
typing_extensions/typing.List style imports—ensure the generator produces
annotations like None | float | tuple[float, float] for _request_timeout and
that model imports target built-in typing for Python 3.12 compatibility rather
than typing_extensions.

Comment on lines 496 to 500
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"Version of the API: 2.1.4\n"\
"Version of the API: 2.1.5\n"\
"SDK Package Version: 2.1.4.0".\
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'SDK Package Version|__version__|^version\s*=|2\.1\.4\.0|2\.1\.5'

Repository: Reya-Labs/reya-python-sdk

Length of output: 8741


Source SDK version from package metadata instead of hard-coding.

Line 500 hard-codes the SDK version as 2.1.4.0, but sdk.open_api.__version__ already provides this as a single source of truth. When the SDK version is bumped in a future release, this debug report will silently report stale version information unless the hard-coded value is updated. Additionally, while touching this block, collapse the multi-line string into a parenthesized expression to clear the Ruff ISC002 implicit string concatenation warning.

🧰 Tools
🪛 Ruff (0.15.5)

[warning] 496-497: Implicitly concatenated string literals over multiple lines

(ISC002)


[warning] 496-501: Use f-string instead of format call

Convert to f-string

(UP032)


[warning] 497-498: Implicitly concatenated string literals over multiple lines

(ISC002)


[warning] 498-499: Implicitly concatenated string literals over multiple lines

(ISC002)


[warning] 499-500: Implicitly concatenated string literals over multiple lines

(ISC002)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/open_api/configuration.py` around lines 496 - 500, The debug report
return currently hard-codes "SDK Package Version: 2.1.4.0" and uses implicit
multi-line string concatenation; update the return expression in
configuration.py to use the canonical sdk.open_api.__version__ value instead of
the literal and collapse the multi-line strings into a single parenthesized
string expression (e.g., return ("Python SDK Debug Report:\nOS: {env}\nPython
Version: {pyversion}\nVersion of the API: 2.1.5\nSDK Package Version: " +
sdk.open_api.__version__)). Ensure you import or reference
sdk.open_api.__version__ where this return is defined so the debug report always
reflects the package metadata and removes the Ruff ISC002 warning.

Comment on lines +708 to +722
async def get_spot_trade_busts(self) -> SpotTradeBustList:
"""
Get spot trade busts (failed spot fills) for the owner wallet asynchronously.

Returns:
Spot trade busts

Raises:
ValueError: If no wallet address is available or API returns an error
"""
wallet = self.owner_wallet_address
if not wallet:
raise ValueError("No wallet address available. Private key must be provided.")

return await self.wallet.get_wallet_spot_trade_busts(address=wallet)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Expose the wallet endpoint's pagination filters here.

sdk/open_api/api/wallet_data_api.py, Lines 1973-2046 already cap this endpoint at 100 results and accept start_time / end_time. This wrapper hardcodes the default page, so callers cannot retrieve older busts through ReyaTradingClient.

🧭 Suggested pass-through
-    async def get_spot_trade_busts(self) -> SpotTradeBustList:
+    async def get_spot_trade_busts(
+        self,
+        start_time: Optional[int] = None,
+        end_time: Optional[int] = None,
+    ) -> SpotTradeBustList:
         """
         Get spot trade busts (failed spot fills) for the owner wallet asynchronously.
 
+        Args:
+            start_time: Optional lower bound for pagination.
+            end_time: Optional upper bound for pagination.
+
         Returns:
             Spot trade busts
 
         Raises:
             ValueError: If no wallet address is available or API returns an error
@@
-        return await self.wallet.get_wallet_spot_trade_busts(address=wallet)
+        return await self.wallet.get_wallet_spot_trade_busts(
+            address=wallet,
+            start_time=start_time,
+            end_time=end_time,
+        )
🧰 Tools
🪛 Ruff (0.15.5)

[warning] 720-720: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/reya_rest_api/client.py` around lines 708 - 722, The get_spot_trade_busts
wrapper currently hardcodes the call and prevents callers from using the wallet
endpoint's pagination/time filters; update
ReyaTradingClient.get_spot_trade_busts to accept optional parameters (e.g.,
start_time, end_time, page, page_size) and forward them to
self.wallet.get_wallet_spot_trade_busts(address=wallet, start_time=start_time,
end_time=end_time, page=page, page_size=page_size), preserving existing behavior
when arguments are None and validating wallet via self.owner_wallet_address as
before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant