### Install Pyth Client Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Use pip to install the library. ```bash pip install pythclient ``` -------------------------------- ### Setup Virtual Environment Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Commands to create and activate a virtual environment for development. ```bash python3 -m venv ve . ve/bin/activate ``` -------------------------------- ### Install Editable Dependencies Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Install the library in editable mode with testing dependencies. ```bash pip install -e '.[testing]' ``` -------------------------------- ### Get Network Keys Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Retrieves program and mapping keys for different Pythnet networks (mainnet, devnet, pythnet). ```python networks = ["mainnet", "devnet", "pythnet"] for network in networks: program_key = get_key(network, "program") mapping_key = get_key(network, "mapping") print(f" {network.upper()}:") print(f" Program: {program_key}") print(f" Mapping: {mapping_key}") ``` -------------------------------- ### Get Pyth Network Keys Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Utility function to retrieve program and mapping account keys for various Pyth networks. Supports mainnet, devnet, testnet, pythnet, and specific test networks. ```python from pythclient.utils import get_key # Available networks: "mainnet", "devnet", "testnet", "pythnet", # "pythtest-conformance", "pythtest-crosschain" ``` -------------------------------- ### Solana Client Operations Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Interact directly with the Solana blockchain using SolanaClient. This client supports various RPC methods like checking node health, getting slot information, and querying account details. It can connect to different Solana endpoints. ```python import asyncio from pythclient.solana import ( SolanaClient, SolanaPublicKey, SolanaCommitment, PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT, SOLANA_MAINNET_HTTP_ENDPOINT ) async def solana_operations(): # Create client for pythnet client = SolanaClient( endpoint=PYTHNET_HTTP_ENDPOINT, ws_endpoint=PYTHNET_WS_ENDPOINT ) # Check node health health = await client.get_health() print(f"Node health: {health}") # Get current slot slot = await client.get_slot(commitment=SolanaCommitment.CONFIRMED) print(f"Current slot: {slot}") # Get account info account_key = SolanaPublicKey("FsSM3s38PX9K7Dn6eGzuE29S2Dsk1Sss1baytTQdCaQj") account_info = await client.get_account_info( account_key, commitment=SolanaCommitment.CONFIRMED, encoding="base64" ) print(f"Account lamports: {account_info['value']['lamports']}") print(f"Data length: {len(account_info['value']['data'][0])} chars (base64)") # Get multiple accounts in one call (max 100) keys = [account_key] # Add more keys as needed multi_info = await client.get_account_info(keys) print(f"Fetched {len(multi_info['value'])} accounts") # Get block time for a slot block_time = await client.get_block_time(slot) print(f"Block time: {block_time}") await client.close() asyncio.run(solana_operations()) ``` -------------------------------- ### Build and Distribute Package Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Commands to build the package and upload it to PyPI. ```bash python3 -m pip install --upgrade twine build ``` ```bash python3 -m build ``` ```bash python3 -m twine upload --repository pypi dist/* ``` -------------------------------- ### Initialize and Connect PythClient to Pyth Network Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Initialize the PythClient to retrieve price data directly from the Solana blockchain. Use a context manager for automatic resource cleanup. Ensure network keys are fetched for the target network. ```python import asyncio from pythclient.pythclient import PythClient from pythclient.utils import get_key from pythclient.solana import PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT async def main(): # Get network keys for pythnet mapping_key = get_key("pythnet", "mapping") program_key = get_key("pythnet", "program") # Initialize client with context manager for automatic cleanup async with PythClient( first_mapping_account_key=mapping_key, program_key=program_key, # Optional: enables getProgramAccounts optimization solana_endpoint=PYTHNET_HTTP_ENDPOINT, solana_ws_endpoint=PYTHNET_WS_ENDPOINT ) as client: # Refresh all prices from the blockchain await client.refresh_all_prices() # Get all available products products = await client.get_products() for product in products: print(f"Product: {product.symbol}") print(f" Attributes: {product.attrs}") # Get prices for each product prices = await product.get_prices() for price_type, price_account in prices.items(): print(f" Price Type: {price_type}") print(f" Status: {price_account.aggregate_price_status}") print(f" Price: {price_account.aggregate_price}") print(f" Confidence: {price_account.aggregate_price_confidence_interval}") asyncio.run(main()) ``` -------------------------------- ### Run Unit Tests Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Execute unit tests or generate HTML coverage reports. ```bash pytest ``` ```bash pytest --cov-report=html ``` -------------------------------- ### Stream Real-time Prices with WatchSession Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Establishes a WebSocket connection to monitor price updates for specific accounts. Requires an active PythClient session and cleanup of subscriptions upon completion. ```python import asyncio import signal from pythclient.pythclient import PythClient from pythclient.pythaccounts import PythPriceAccount from pythclient.utils import get_key from pythclient.solana import PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT async def stream_prices(): mapping_key = get_key("pythnet", "mapping") program_key = get_key("pythnet", "program") async with PythClient( first_mapping_account_key=mapping_key, program_key=program_key, solana_endpoint=PYTHNET_HTTP_ENDPOINT, solana_ws_endpoint=PYTHNET_WS_ENDPOINT ) as client: # Load initial prices await client.refresh_all_prices() products = await client.get_products() # Collect price accounts to subscribe price_accounts = [] for product in products[:5]: # Subscribe to first 5 products prices = await product.get_prices() price_accounts.extend(prices.values()) # Create WebSocket watch session watch_session = client.create_watch_session() await watch_session.connect() # Subscribe to individual accounts for account in price_accounts: await watch_session.subscribe(account) print("Subscribed! Waiting for price updates...") # Process updates for 30 seconds try: for _ in range(10): # Wait for next update with timeout update_task = asyncio.create_task(watch_session.next_update()) done, _ = await asyncio.wait({update_task}, timeout=5.0) if update_task in done: updated_account = update_task.result() if isinstance(updated_account, PythPriceAccount) and updated_account.product: print(f"{updated_account.product.symbol}: " f"${updated_account.aggregate_price} " f"± {updated_account.aggregate_price_confidence_interval}") finally: # Clean up subscriptions for account in price_accounts: await watch_session.unsubscribe(account) await watch_session.disconnect() asyncio.run(stream_prices()) ``` -------------------------------- ### Read Pyth Prices Source: https://github.com/pyth-network/pyth-client-py/blob/main/README.md Retrieve and print current price data for products using the PythClient. ```python from pythclient.pythclient import PythClient from pythclient.pythaccounts import PythPriceAccount from pythclient.utils import get_key solana_network="devnet" async with PythClient( first_mapping_account_key=get_key(solana_network, "mapping"), program_key=get_key(solana_network, "program") if use_program else None, ) as c: await c.refresh_all_prices() products = await c.get_products() for p in products: print(p.attrs) prices = await p.get_prices() for _, pr in prices.items(): print( pr.price_type, pr.aggregate_price_status, pr.aggregate_price, "p/m", pr.aggregate_price_confidence_interval, ) ``` -------------------------------- ### Access Product Metadata and Price Feeds Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Retrieves product metadata, market schedules, and detailed price account information including publisher components from the Pyth network. ```python import asyncio from pythclient.pythclient import PythClient from pythclient.pythaccounts import PythPriceStatus from pythclient.utils import get_key from pythclient.solana import PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT async def explore_products(): mapping_key = get_key("pythnet", "mapping") async with PythClient( first_mapping_account_key=mapping_key, solana_endpoint=PYTHNET_HTTP_ENDPOINT, solana_ws_endpoint=PYTHNET_WS_ENDPOINT ) as client: await client.refresh_all_prices() products = await client.get_products() # Filter for specific asset types crypto_products = [p for p in products if p.attrs.get('asset_type') == 'Crypto'] equity_products = [p for p in products if p.attrs.get('asset_type') == 'Equity'] fx_products = [p for p in products if p.attrs.get('asset_type') == 'FX'] print(f"Total products: {len(products)}") print(f"Crypto: {len(crypto_products)}, Equity: {len(equity_products)}, FX: {len(fx_products)}") # Examine a specific product for product in products: if product.symbol == "Crypto.BTC/USD": print(f"\nProduct: {product.symbol}") print(f"Account key: {product.key}") print(f"All attributes: {product.attrs}") # Get market schedule schedule = product.schedule print(f"Timezone: {schedule.timezone}") # Get all price types for this product prices = await product.get_prices() for price_type, price_account in prices.items(): print(f"\nPrice type: {price_type}") print(f" Account key: {price_account.key}") print(f" Exponent: {price_account.exponent}") print(f" Min publishers: {price_account.min_publishers}") print(f" Max latency: {price_account.max_latency} slots") if price_account.aggregate_price_status == PythPriceStatus.TRADING: print(f" Current price: ${price_account.aggregate_price:,.2f}") print(f" Confidence: ±${price_account.aggregate_price_confidence_interval:,.2f}") # Access individual publisher components print(f" Number of publishers: {len(price_account.price_components)}") for component in price_account.price_components[:3]: # First 3 print(f" Publisher: {component.publisher_key}") print(f" Latest price: {component.latest_price_info.price}") break asyncio.run(explore_products()) ``` -------------------------------- ### Read Single Price Feed using PythPriceAccount Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Fetch data for a specific Pyth price feed using its Solana account key. This is efficient when only one price feed is needed. Always check the price status before using the price data. ```python import asyncio from pythclient.pythaccounts import PythPriceAccount, PythPriceStatus from pythclient.solana import SolanaClient, SolanaPublicKey, PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT async def get_single_price(): # DOGE/USD price account key from pythnet (find keys at pyth.network) account_key = SolanaPublicKey("FsSM3s38PX9K7Dn6eGzuE29S2Dsk1Sss1baytTQdCaQj") # Create Solana client solana_client = SolanaClient( endpoint=PYTHNET_HTTP_ENDPOINT, ws_endpoint=PYTHNET_WS_ENDPOINT ) # Create price account and fetch data price_account = PythPriceAccount(account_key, solana_client) await price_account.update() # Check price status before using if price_account.aggregate_price_status == PythPriceStatus.TRADING: print(f"DOGE/USD: ${price_account.aggregate_price:.6f}") print(f"Confidence: ±${price_account.aggregate_price_confidence_interval:.6f}") print(f"Last updated slot: {price_account.slot}") else: print(f"Price unavailable. Status: {price_account.aggregate_price_status}") await solana_client.close() asyncio.run(get_single_price()) ``` -------------------------------- ### Extract Price Information from VAA Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Demonstrates how to parse price information from a VAA hex string and retrieve specific price data by feed ID. ```python # Extract all price infos from VAA price_infos = vaa_to_price_infos(vaa_hex, encoding="hex") if price_infos: for info in price_infos: print(f"\nFeed ID: {info.price_feed.id}") print(f"Price: {info.price_feed.price.price}") print(f"Confidence: {info.price_feed.price.conf}") print(f"Exponent: {info.price_feed.price.expo}") print(f"Publish time: {info.publish_time}") print(f"Sequence: {info.seq_num}") # Get specific price by feed ID btc_feed_id = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" btc_info = vaa_to_price_info(btc_feed_id, vaa_hex, encoding="hex") if btc_info: # Convert to dictionary for JSON serialization price_dict = btc_info.to_dict(verbose=True, vaa_format="base64") print(f"\nBTC/USD price data: {price_dict}") ``` -------------------------------- ### Configure API Rate Limiting Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Configures global rate limits for Solana RPC calls using RateLimit.configure_default_ratelimit before creating PythClient instances. Ensures API calls do not exceed specified calls per second (CPS) for overall, method, and connection limits. ```python import asyncio from pythclient.ratelimit import RateLimit from pythclient.pythclient import PythClient from pythclient.utils import get_key from pythclient.solana import PYTHNET_HTTP_ENDPOINT, PYTHNET_WS_ENDPOINT # Configure global rate limits before creating clients RateLimit.configure_default_ratelimit( overall_cps=9, # Overall calls per second method_cps=3, # Calls per second per method connection_cps=3 # Calls per second per connection ) async def rate_limited_example(): mapping_key = get_key("pythnet", "mapping") async with PythClient( first_mapping_account_key=mapping_key, solana_endpoint=PYTHNET_HTTP_ENDPOINT, solana_ws_endpoint=PYTHNET_WS_ENDPOINT ) as client: # Rate limiting is automatically applied await client.refresh_all_prices() products = await client.get_products() print(f"Loaded {len(products)} products with rate limiting") # Check current rate limit status if client.solana_ratelimit: print("Rate limiting is enabled") asyncio.run(rate_limited_example()) ``` -------------------------------- ### Retrieve Historical Price with HermesClient Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Fetch historical Pyth prices at a specific Unix timestamp using HermesClient. This is useful for backtesting and historical analysis. Requires a feed ID and a Unix timestamp. ```python import asyncio import time from pythclient.hermes import HermesClient async def get_historical_price(): hermes_client = HermesClient([]) # BTC/USD feed ID btc_feed_id = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" # Get price from 1 hour ago one_hour_ago = int(time.time()) - 3600 # Fetch historical price (v2 API) price_feed = await hermes_client.get_pyth_price_at_time( feed_id=btc_feed_id, timestamp=one_hour_ago, version=2 ) price = price_feed['price'] actual_price = int(price.price) * (10 ** price.expo) print(f"BTC/USD 1 hour ago:") print(f" Price: ${actual_price:,.2f}") print(f" Timestamp: {price.publish_time}") print(f" Update data available for on-chain use: {len(price_feed['update_data'])} bytes") asyncio.run(get_historical_price()) ``` -------------------------------- ### Parse Market Schedules Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Parses and validates market schedules for traditional assets using MarketSchedule. Allows defining trading hours for different markets and checking if they are currently open. Requires specifying timezone, weekly schedule, and optional holidays. ```python from datetime import datetime, timezone from pythclient.market_schedule import MarketSchedule # Schedule format: "Timezone;WeeklySchedule;Holidays" # Weekly schedule: 7 comma-separated day schedules (Mon-Sun) # Day formats: O=Open 24h, C=Closed, HHMM-HHMM=Time range # US Stock market schedule (Mon-Fri 9:30-16:00 ET) us_stocks = MarketSchedule("America/New_York;0930-1600,0930-1600,0930-1600,0930-1600,0930-1600,C,C;") # Crypto market (always open) crypto = MarketSchedule("UTC;O,O,O,O,O,O,O;") # Forex market with multiple sessions forex = MarketSchedule("America/New_York;1700-1700,1700-1700,1700-1700,1700-1700,1700-1700,C,1700-2400;") # Check if market is currently open now = datetime.now(timezone.utc) print(f"Current time (UTC): {now.strftime('%Y-%m-%d %H:%M')}") print(f"US Stocks open: {us_stocks.is_market_open(now)}") print(f"Crypto open: {crypto.is_market_open(now)}") print(f"Forex open: {forex.is_market_open(now)}") # Get next market open/close times next_open = us_stocks.get_next_market_open(now) next_close = us_stocks.get_next_market_close(now) if next_open: print(f"US Stocks next open: {next_open.strftime('%Y-%m-%d %H:%M %Z')}") if next_close: print(f"US Stocks next close: {next_close.strftime('%Y-%m-%d %H:%M %Z')}") # Schedule with holiday override (closed on July 4th) with_holiday = MarketSchedule("America/New_York;0930-1600,0930-1600,0930-1600,0930-1600,0930-1600,C,C;0704/C") ``` -------------------------------- ### Parse VAA Price Data Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Parses Verifiable Action Approvals (VAAs) to extract price information, specifically handling the accumulator update format. Use `is_accumulator_update` to check format and `parse_accumulator_update` to extract data like the number of price updates and VAA length. ```python from pythclient.price_feeds import ( vaa_to_price_infos, vaa_to_price_info, is_accumulator_update, parse_accumulator_update ) # Example VAA hex string (truncated for brevity) # In production, get this from Hermes API update_data field vaa_hex = "504e415501000000..." # Accumulator update format # Check if it's an accumulator update (new format) if is_accumulator_update(vaa_hex, encoding="hex"): print("VAA is accumulator format") # Parse accumulator update accumulator = parse_accumulator_update(vaa_hex, "hex") if accumulator: print(f"Number of price updates: {accumulator.num_updates}") print(f"VAA length: {accumulator.vaa_length}") ``` -------------------------------- ### Stream Hermes Prices via WebSocket Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Use HermesClient to stream real-time price updates over WebSocket. Initialize with feed IDs and handle price updates. Ensure to cancel the WebSocket task when done. ```python import asyncio from pythclient.hermes import HermesClient async def stream_hermes_prices(): # Initialize with feed IDs feed_ids = [ "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", # BTC/USD "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", # ETH/USD ] hermes_client = HermesClient(feed_ids) # Get initial prices via HTTP initial_prices = await hermes_client.get_all_prices(version=2) print("Initial prices loaded") # Start WebSocket stream in background ws_task = asyncio.create_task(hermes_client.ws_pyth_prices(version=1)) # Monitor prices for 30 seconds for i in range(6): await asyncio.sleep(5) print(f"\n--- Update {i+1} ---") for feed_id, price_feed in hermes_client.prices_dict.items(): price = price_feed['price'] actual_price = int(price.price) * (10 ** price.expo) print(f"{feed_id[:8]}...: ${actual_price:,.2f} (conf: {price.conf})") # Cancel WebSocket task ws_task.cancel() try: await ws_task except asyncio.CancelledError: pass asyncio.run(stream_hermes_prices()) ``` -------------------------------- ### Access Off-chain Prices with HermesClient Source: https://context7.com/pyth-network/pyth-client-py/llms.txt Retrieves price data via the Hermes HTTP service using specific feed IDs. Useful for cross-chain applications that do not require direct blockchain interaction. ```python import asyncio from pythclient.hermes import HermesClient async def get_hermes_prices(): # Initialize client (empty list, will add feed IDs later) hermes_client = HermesClient([]) # Get all available price feed IDs all_feed_ids = await hermes_client.get_price_feed_ids() print(f"Available feeds: {len(all_feed_ids)}") # Add specific feed IDs to track (e.g., BTC/USD, ETH/USD) # Feed IDs are hex strings - find them at pyth.network btc_usd = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" eth_usd = "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace" hermes_client.add_feed_ids([btc_usd, eth_usd]) # Get latest prices via HTTP (v2 API) prices = await hermes_client.get_all_prices(version=2) for feed_id, price_feed in prices.items(): price = price_feed['price'] ema_price = price_feed['ema_price'] # Calculate actual price from raw value and exponent actual_price = int(price.price) * (10 ** price.expo) print(f"Feed: {feed_id[:16]}...") print(f" Price: ${actual_price:,.2f}") print(f" Confidence: {price.conf}") print(f" EMA Price: {ema_price.price}") print(f" Publish Time: {price.publish_time}") asyncio.run(get_hermes_prices()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.