Lesson 1 — Crypto: Environment & testnet setup
Prepare your Python environment, create exchange testnet API keys, and run quick REST and WebSocket smoke tests. This lesson gets you ready for the Crypto track.
Prerequisites
- Python 3.10+ installed
- Basic command-line familiarity
- An editor (VS Code / PyCharm) and optional git
- Exchange testnet accounts (e.g., Binance testnet, Deribit testnet, or exchange sandbox)
Download software & tools (links)
Official downloads and helpful tools for crypto development:
1) Create project & virtual environment
Run these commands to create a project and venv. Activate the venv before installing dependencies.
# create project dir and virtualenv
mkdir crypto-lesson1 && cd crypto-lesson1
python -m venv .venv
# activate:
# macOS / Linux
source .venv/bin/activate
# Windows (PowerShell)
# .\.venv\Scripts\Activate.ps1
# install essentials
pip install requests websockets python-dotenv ccxt
Tip: CCXT is optional but handy for interacting with many exchange REST APIs uniformly. For websockets prefer native exchange docs for order book payloads.
2) Recommended .env values
Save these locally in .env (never commit). The download button provides a template.
# .env example - DO NOT COMMIT
EXCHANGE_API_URL=https://testnet-api.example.com
EXCHANGE_API_KEY=your_testnet_api_key
EXCHANGE_API_SECRET=your_testnet_api_secret
EXCHANGE_WS_URL=wss://testnet-ws.example.com
3) Create testnet API keys
Most exchanges provide a separate testnet or sandbox. Quick links:
Note: Testnet keys are separate from live keys and usually have no monetary risk. Use them to validate auth, order flows and websockets before requesting production keys.
4) Minimal HMAC auth helper (auth.py)
Many exchanges require HMAC signing for REST. This example demonstrates building a signed header for a REST GET on an exchange testnet. Adapt to your exchange’s spec (e.g., Binance, Kraken, Deribit).
import os
import time
import hmac
import hashlib
import requests
from dotenv import load_dotenv
load_dotenv()
API_URL = os.getenv('EXCHANGE_API_URL')
API_KEY = os.getenv('EXCHANGE_API_KEY')
API_SECRET = os.getenv('EXCHANGE_API_SECRET')
def sign_message(payload: str) -> str:
return hmac.new(API_SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()
def public_get(path, params=None):
url = API_URL.rstrip('/') + '/' + path.lstrip('/')
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()
return r.json()
def private_get(path, params=None):
url = API_URL.rstrip('/') + '/' + path.lstrip('/')
ts = str(int(time.time() * 1000))
pre = ts + 'GET' + path + ( '?' + '&'.join([f"{k}={v}" for k,v in (params or {}).items() ]) if params else '')
signature = sign_message(pre)
headers = {
'X-API-KEY': API_KEY,
'X-SIGNATURE': signature,
'X-TIMESTAMP': ts,
'Content-Type': 'application/json'
}
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
return r.json()
if __name__ == '__main__':
print('Public markets example:', public_get('/markets'))
Warning: Exchange signing formats vary—read the exchange’s docs. Never expose secrets in client JS or public repos.
5) Quick WebSocket market data smoke test
Example using the websockets library to subscribe to a ticker channel. Replace the URL and subscribe message with the exchange-specific payload.
import asyncio
import os
import json
import websockets
from dotenv import load_dotenv
load_dotenv()
WS_URL = os.getenv('EXCHANGE_WS_URL', 'wss://testnet-ws.example.com')
async def ws_test():
async with websockets.connect(WS_URL) as ws:
# Example subscribe message; adapt to exchange
await ws.send(json.dumps({"op":"subscribe","channel":"ticker","symbol":"BTC/USDT"}))
for i in range(5):
msg = await ws.recv()
print('msg:', msg)
if __name__ == '__main__':
asyncio.run(ws_test())
If your exchange requires signed WS auth, sign per their docs (some use a pre-auth token or signed CONNECT frame).
6) Optional: CCXT for unified REST calls
CCXT simplifies talking to many exchanges. Example to connect to Binance testnet via CCXT (install with pip install ccxt):
import os
import ccxt
from dotenv import load_dotenv
load_dotenv()
exchange = ccxt.binance({
'apiKey': os.getenv('EXCHANGE_API_KEY'),
'secret': os.getenv('EXCHANGE_API_SECRET'),
'enableRateLimit': True,
'options': {'defaultType': 'future'},
})
exchange.set_sandbox_mode(True) # use testnet on supported exchanges
markets = exchange.load_markets()
print('Loaded markets:', len(markets))
Note: CCXT’s sandbox support varies by exchange—check the exchange’s CCXT docs.
7) Safety & next steps
- Keep testnet and live keys separate and never mix them in code.
- Use small stakes on live and validate logic thoroughly in testnet first.
- Store secrets in .env during development and migrate to a secrets manager for production.
Security: Do not accept API key input client-side; verify WS signatures and always use HTTPS/WSS.
What you’ll build next
Lesson 2 will implement HMAC authentication in full, show signed REST examples, and add a resilient request helper with retries. Then we’ll move on to market data (REST & WS) and order placement in later lessons.
