Skip to main content

tpluspy: Client utilities for interacting with tplus

Project description

TPlus Python Client Utilities

Python clients for interacting with tplus.

Install

To install, use either pip or uv pip:

uv pip install -e .

Usage Example

REST and WebSocket Client (tplus.client)

The tpluspy library also provides an asynchronous client (OrderBookClient) for interacting with the tplus-core REST API and WebSocket streams.

Initialization

To use the client, first initialize it with a User object (for signing requests) and the base URL of your tplus-core instance:

import asyncio
from tplus.client import OrderBookClient
from tplus.utils.user import User

API_BASE_URL = "http://127.0.0.1:8000"  # Replace with your API URL
user = User()

async def run_client():
    # Use async context manager for automatic cleanup
    async with OrderBookClient(user=user, base_url=API_BASE_URL) as client:
        print("Client initialized.")
        # ... use client methods ...

asyncio.run(run_client())

REST API Usage

The client offers async methods for common REST endpoints:

Fetching Data:

# Get Order Book Snapshot for asset index 200
from tplus.model.asset_identifier import AssetIdentifier

example_asset = AssetIdentifier(Index=200)
orderbook = await client.get_orderbook_snapshot(example_asset)
print(f"Snapshot Sequence: {orderbook.sequence_number}")

# Get Klines for an asset
klines = await client.get_klines(example_asset)
print(f"Klines: {klines}")

# Get Market Details for an asset
market_details = await client.get_market(example_asset)
print(f"Market Details: Price Decimals={market_details.book_price_decimals}, Quantity Decimals={market_details.book_quantity_decimals}")

# Get orders for the user
user_orders, _ = await client.get_user_orders()
print(f"User Orders: {user_orders}")

# Get trades for the user and asset
user_asset_trades = await client.get_user_trades_for_asset(example_asset)
print(f"User Asset Trades: {user_asset_trades}")

# Get user inventory
inventory = await client.get_user_inventory()
print(f"Inventory: {inventory}")

Creating Orders:

# Ensure example_asset is defined (e.g., from "Fetching Data" section)
from tplus.model.asset_identifier import AssetIdentifier
example_asset = AssetIdentifier(200)

# Create a Market for an asset (idempotent)
market_creation_response = await client.create_market(asset_id=example_asset)
print(f"Market Creation Response: {market_creation_response}")

# Create a Market Order for a specific asset
market_response = await client.create_market_order(
    asset_id=example_asset,
    quantity=10,  # integer quantity
    side="Buy",
    fill_or_kill=False,
)
print(f"Market Order Response: {market_response}")

# Create a Limit Order for a specific asset
# Good-Till-Cancelled limit order
from tplus.model.limit_order import GTC
limit_response = await client.create_limit_order(
    asset_id=example_asset,
    quantity=5,
    price=1_000,
    side="Sell",
    time_in_force=GTC(),
)
print(f"Limit Order Response: {limit_response}")

# Cancel an Order
# Order ID should be obtained from an order creation response.
order_id_to_cancel = "actual-order-id-from-api"  # Replace with a real order ID
cancel_response = await client.cancel_order(
    order_id=order_id_to_cancel,
    asset_id=example_asset
)
print(f"Cancel Order Response: {cancel_response}")

# Replace an Order
# Original Order ID should be from an existing, open order.
original_order_id_to_replace = "actual-original-order-id"  # Replace with a real order ID
replace_response = await client.replace_order(
    original_order_id=original_order_id_to_replace,
    asset_id=example_asset,
    new_quantity=6, # Optional: New integer quantity
    new_price=1050   # Optional: New integer price
)
print(f"Replace Order Response: {replace_response}")

See examples/rest_usage.py for a runnable demonstration.

WebSocket Streaming

The client provides async iterators to stream real-time data:

from tplus.model.asset_identifier import AssetIdentifier
from tplus.model.orderbook import OrderBookDiff
from tplus.model.trades import Trade

example_asset = AssetIdentifier(200)

# Stream Order Book Diffs
async for diff_update in client.stream_depth(example_asset):
    if isinstance(diff_update, OrderBookDiff):
        print(f"[Depth] Seq={diff_update.sequence_number}, Asks={len(diff_update.asks)}, Bids={len(diff_update.bids)}")
    # Add logic to handle the update, e.g., update a local order book

# Stream Finalized Trades
async for trade in client.stream_finalized_trades():
     if isinstance(trade, Trade):
        print(f"[Trade] ID: {trade.trade_id}, Price: {trade.price}, Qty: {trade.quantity}")
    # Add logic to handle the trade

# Other available streams:
# client.stream_orders() -> OrderEvent
# client.stream_all_trades() -> TradeEvent
# client.stream_klines(asset_id) -> KlineUpdate

See examples/websocket_usage.py for a runnable demonstration using asyncio.gather to run multiple streams concurrently.

Contracts

To interact with the contracts or sign T+ specific EIP-712 messages, ensure you have installed the evm extra:

pip install tpluspy[evm]

Use the tplusp.contracts module to read data from t+ contracts. For example, launch a Sepolia-connected Ape console:

ape console --network ethereum:sepolia:alchemy

Note: You can use any provider you want or a RPC directly, it doesn't have to be Alchemy.

Then, once in the console, you will already have access to contracts that you can call methods on:

In [1]: registry.getAssets()
Out[1]: [getAssets_return(assetAddress=HexBytes('0x000000000000000000000000f08a50178dfcde18524640ea6618a1f965821715'), chainId=11155111, maxDeposits=100)]
In [2]: registry.admin()
Out[2]: '0x467a95fC5359edE5d5dDc4f10A1F4B680694858E'

EIP-712

Sign EIP-712 messages, such as settlements, using the eip712 library.

from ape import accounts, convert, chain
from tplus.evm.eip712 import Order
from tplus.evm.contracts import vault
from tplus.utils.user import UserManager

# Load your Ethereum account for t+.
tplus_user = accounts.load("tplus-account")

# Load your t+ user (public key).
user_id = UserManager.load("my_user").public_key

# Get the nonce from t+ or the contracts directly.
nonce = vault.getDepositNonce(tplus_user)

order = Order(
    tokenOut="0x62622E77D1349Face943C6e7D5c01C61465FE1dc",
    amountOut=convert("1 ether", int),
    tokenIn="0x58372ab62269A52fA636aD7F200d93999595DCAF",
    amountIn=convert("1 ether", int),
    userId=user_id,
    nonce=nonce,
    validUntil=chain.pending_timestamp,
)

# Use this signature for the settlement.
signature = tplus_user.sign_message(order).encode_rsv()
print(signature)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tpluspy-0.1.0a0.tar.gz (51.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tpluspy-0.1.0a0-py3-none-any.whl (51.4 kB view details)

Uploaded Python 3

File details

Details for the file tpluspy-0.1.0a0.tar.gz.

File metadata

  • Download URL: tpluspy-0.1.0a0.tar.gz
  • Upload date:
  • Size: 51.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for tpluspy-0.1.0a0.tar.gz
Algorithm Hash digest
SHA256 c1b5a4f3c43b04113bb25d5cbaa1fd3bcb63ba111b237d7ae0485fd7cd783847
MD5 0704dcf29c18c4243fc8c71be5fa54a2
BLAKE2b-256 7b66c71f23c9f25a8a20098a4edc2c55366167bcbaa9e22f39c4056c28b4d9a7

See more details on using hashes here.

File details

Details for the file tpluspy-0.1.0a0-py3-none-any.whl.

File metadata

  • Download URL: tpluspy-0.1.0a0-py3-none-any.whl
  • Upload date:
  • Size: 51.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for tpluspy-0.1.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 376a3de9c87422d423654e427ac37774fead7aab685eeebf256fa4ff17bbdf97
MD5 2df0b1d247d8fd0ede87bdc32166e661
BLAKE2b-256 31176b6ddba98c9c5c739ed8fa49c218000e0cae24198c09a95a24fc59ebc194

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page