ci: standardize pytest invocation and add security scanning
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 8s
CLI Tests / test-cli (push) Successful in 10s
Contract Performance Benchmarks / benchmark-gas-usage (push) Successful in 1m22s
Contract Performance Benchmarks / benchmark-execution-time (push) Successful in 1m11s
Contract Performance Benchmarks / benchmark-throughput (push) Successful in 1m13s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Failing after 5s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 5s
Cross-Chain Functionality Tests / test-cross-chain-bridge (push) Has been skipped
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Failing after 3s
Cross-Chain Functionality Tests / aggregate-results (push) Has been skipped
Cross-Node Transaction Testing / transaction-test (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Successful in 1m14s
Contract Performance Benchmarks / compare-benchmarks (push) Has been cancelled
Documentation Validation / validate-docs (push) Failing after 10s
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Has been cancelled
Smart Contract Tests / test-foundry (push) Has been cancelled
Smart Contract Tests / lint-solidity (push) Has been cancelled
Smart Contract Tests / deploy-contracts (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Failing after 45s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Failing after 2s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 5s
P2P Network Verification / p2p-verification (push) Successful in 3s
Production Tests / Production Integration Tests (push) Failing after 7s
Python Tests / test-python (push) Failing after 46s
Staking Tests / test-staking-service (push) Failing after 2s
Staking Tests / test-staking-integration (push) Has been skipped
Staking Tests / test-staking-contract (push) Has been skipped
Staking Tests / run-staking-test-runner (push) Has been skipped
Systemd Sync / sync-systemd (push) Successful in 21s
API Endpoint Tests / test-api-endpoints (push) Failing after 12m19s
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 8s
CLI Tests / test-cli (push) Successful in 10s
Contract Performance Benchmarks / benchmark-gas-usage (push) Successful in 1m22s
Contract Performance Benchmarks / benchmark-execution-time (push) Successful in 1m11s
Contract Performance Benchmarks / benchmark-throughput (push) Successful in 1m13s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Failing after 5s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 5s
Cross-Chain Functionality Tests / test-cross-chain-bridge (push) Has been skipped
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Failing after 3s
Cross-Chain Functionality Tests / aggregate-results (push) Has been skipped
Cross-Node Transaction Testing / transaction-test (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Successful in 1m14s
Contract Performance Benchmarks / compare-benchmarks (push) Has been cancelled
Documentation Validation / validate-docs (push) Failing after 10s
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Has been cancelled
Smart Contract Tests / test-foundry (push) Has been cancelled
Smart Contract Tests / lint-solidity (push) Has been cancelled
Smart Contract Tests / deploy-contracts (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Failing after 45s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Failing after 2s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 5s
P2P Network Verification / p2p-verification (push) Successful in 3s
Production Tests / Production Integration Tests (push) Failing after 7s
Python Tests / test-python (push) Failing after 46s
Staking Tests / test-staking-service (push) Failing after 2s
Staking Tests / test-staking-integration (push) Has been skipped
Staking Tests / test-staking-contract (push) Has been skipped
Staking Tests / run-staking-test-runner (push) Has been skipped
Systemd Sync / sync-systemd (push) Successful in 21s
API Endpoint Tests / test-api-endpoints (push) Failing after 12m19s
- Changed pytest calls to use `venv/bin/python -m pytest` with explicit config - Added `--rootdir "$PWD"` and `--import-mode=importlib` for consistent imports - Fixed PYTHONPATH to use absolute paths with $PWD prefix - Added smart contract security scanning for Solidity files - Added Circom circuit security checks for ZK proof circuits - Added ZK proof implementation security validation - Added contracts/** to security scanning workflow
This commit is contained in:
438
docs/api/examples/curl-examples.md
Normal file
438
docs/api/examples/curl-examples.md
Normal file
@@ -0,0 +1,438 @@
|
||||
# cURL Examples
|
||||
|
||||
This document provides comprehensive cURL examples for interacting with the AITBC APIs.
|
||||
|
||||
## Common Headers
|
||||
|
||||
```bash
|
||||
# Set API key header
|
||||
export API_KEY="your-api-key"
|
||||
export BASE_URL="http://localhost:8011"
|
||||
|
||||
# Common curl command pattern
|
||||
curl -H "X-Api-Key: $API_KEY" $BASE_URL/v1/endpoint
|
||||
```
|
||||
|
||||
## Coordinator API Examples
|
||||
|
||||
### Job Submission
|
||||
|
||||
#### Simple Job Submission
|
||||
|
||||
```bash
|
||||
curl -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-d '{
|
||||
"payload": {
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
"ttl_seconds": 900
|
||||
}'
|
||||
```
|
||||
|
||||
#### Job with Constraints
|
||||
|
||||
```bash
|
||||
curl -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-d '{
|
||||
"payload": {
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
"constraints": {
|
||||
"min_gpu_memory": 8,
|
||||
"gpu_type": "nvidia-rtx-3090"
|
||||
},
|
||||
"ttl_seconds": 900
|
||||
}'
|
||||
```
|
||||
|
||||
#### Job with Payment
|
||||
|
||||
```bash
|
||||
curl -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-d '{
|
||||
"payload": {
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
"payment_amount": 100.0,
|
||||
"payment_currency": "AITBC",
|
||||
"ttl_seconds": 900
|
||||
}'
|
||||
```
|
||||
|
||||
### Job Status
|
||||
|
||||
#### Get Job Status
|
||||
|
||||
```bash
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}
|
||||
```
|
||||
|
||||
#### Poll for Completion
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
JOB_ID="your-job-id"
|
||||
|
||||
while true; do
|
||||
STATUS=$(curl -s -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/$JOB_ID | jq -r '.state')
|
||||
|
||||
echo "State: $STATUS"
|
||||
|
||||
if [[ "$STATUS" =~ ^(COMPLETED|FAILED|CANCELLED|EXPIRED)$ ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
done
|
||||
```
|
||||
|
||||
### Job Results
|
||||
|
||||
#### Get Job Result
|
||||
|
||||
```bash
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/result
|
||||
```
|
||||
|
||||
#### Get Receipts
|
||||
|
||||
```bash
|
||||
# Get latest receipt
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/receipt
|
||||
|
||||
# Get all receipts
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/receipts
|
||||
```
|
||||
|
||||
### Job Cancellation
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/cancel
|
||||
```
|
||||
|
||||
### Payment Operations
|
||||
|
||||
#### Get Payment Status
|
||||
|
||||
```bash
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/payment
|
||||
```
|
||||
|
||||
## Blockchain API Examples
|
||||
|
||||
### Block Operations
|
||||
|
||||
#### Get Head Block
|
||||
|
||||
```bash
|
||||
export BLOCKCHAIN_URL="http://localhost:8080"
|
||||
|
||||
curl $BLOCKCHAIN_URL/v1/blocks/head
|
||||
```
|
||||
|
||||
#### Get Block by Height
|
||||
|
||||
```bash
|
||||
curl $BLOCKCHAIN_URL/v1/blocks/12345
|
||||
```
|
||||
|
||||
#### Get Block Range
|
||||
|
||||
```bash
|
||||
curl "$BLOCKCHAIN_URL/v1/blocks?from=12340&to=12350"
|
||||
```
|
||||
|
||||
### Transaction Operations
|
||||
|
||||
#### Get Transaction
|
||||
|
||||
```bash
|
||||
curl $BLOCKCHAIN_URL/v1/transactions/{tx_hash}
|
||||
```
|
||||
|
||||
#### Submit Transaction
|
||||
|
||||
```bash
|
||||
curl -X POST $BLOCKCHAIN_URL/v1/transactions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"from": "0x...",
|
||||
"to": "0x...",
|
||||
"value": 1000,
|
||||
"gas": 21000,
|
||||
"data": "0x...",
|
||||
"signature": "0x..."
|
||||
}'
|
||||
```
|
||||
|
||||
### Network Status
|
||||
|
||||
#### Get Network Info
|
||||
|
||||
```bash
|
||||
curl $BLOCKCHAIN_URL/v1/network
|
||||
```
|
||||
|
||||
#### Get Peers
|
||||
|
||||
```bash
|
||||
curl $BLOCKCHAIN_URL/v1/network/peers
|
||||
```
|
||||
|
||||
### Smart Contract Operations
|
||||
|
||||
#### Call Contract (Read-only)
|
||||
|
||||
```bash
|
||||
curl -X POST $BLOCKCHAIN_URL/v1/contracts/{address}/call \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"method": "balanceOf",
|
||||
"args": ["0x..."]
|
||||
}'
|
||||
```
|
||||
|
||||
#### Send Transaction to Contract (State-changing)
|
||||
|
||||
```bash
|
||||
curl -X POST $BLOCKCHAIN_URL/v1/contracts/{address}/transact \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"method": "transfer",
|
||||
"args": ["0x...", 1000],
|
||||
"gas": 100000,
|
||||
"value": 0
|
||||
}'
|
||||
```
|
||||
|
||||
## Advanced cURL Examples
|
||||
|
||||
### Using jq for JSON Processing
|
||||
|
||||
```bash
|
||||
# Extract job ID from response
|
||||
JOB_ID=$(curl -s -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-d '{"payload": {"model": "llama2", "prompt": "Hello"}, "ttl_seconds": 900}' \
|
||||
| jq -r '.job_id')
|
||||
|
||||
echo "Job ID: $JOB_ID"
|
||||
```
|
||||
|
||||
### Pretty Print JSON Output
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id} | jq '.'
|
||||
```
|
||||
|
||||
### Extract Specific Fields
|
||||
|
||||
```bash
|
||||
# Get job state only
|
||||
curl -s -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id} | jq -r '.state'
|
||||
|
||||
# Get multiple fields
|
||||
curl -s -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id} | jq '{state: .state, assigned_miner_id: .assigned_miner_id}'
|
||||
```
|
||||
|
||||
### Batch Operations
|
||||
|
||||
```bash
|
||||
# Submit multiple jobs
|
||||
for prompt in "Hello" "World" "Test"; do
|
||||
curl -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-d "{\"payload\": {\"model\": \"llama2\", \"prompt\": \"$prompt\"}, \"ttl_seconds\": 900}" &
|
||||
done
|
||||
|
||||
wait
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```bash
|
||||
# Check HTTP status code
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id})
|
||||
|
||||
if [ $HTTP_CODE -eq 200 ]; then
|
||||
echo "Success"
|
||||
else
|
||||
echo "Failed with status code: $HTTP_CODE"
|
||||
fi
|
||||
```
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
```bash
|
||||
# Add delay between requests to respect rate limits
|
||||
for i in {1..10}; do
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}
|
||||
sleep 1 # 1 second delay
|
||||
done
|
||||
```
|
||||
|
||||
### Retry Logic
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
MAX_RETRIES=3
|
||||
RETRY_DELAY=5
|
||||
|
||||
for i in $(seq 1 $MAX_RETRIES); do
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id})
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
BODY=$(echo "$RESPONSE" | head -n-1)
|
||||
|
||||
if [ $HTTP_CODE -eq 200 ]; then
|
||||
echo "$BODY"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Attempt $i failed with status $HTTP_CODE"
|
||||
sleep $RETRY_DELAY
|
||||
done
|
||||
|
||||
echo "Max retries exceeded"
|
||||
exit 1
|
||||
```
|
||||
|
||||
### File Upload
|
||||
|
||||
```bash
|
||||
# Upload file as job payload
|
||||
curl -X POST $BASE_URL/v1/jobs \
|
||||
-H "Content-Type: multipart/form-data" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
-F "payload=@input.json" \
|
||||
-F "ttl_seconds=900"
|
||||
```
|
||||
|
||||
### Download Results
|
||||
|
||||
```bash
|
||||
# Download job result to file
|
||||
curl -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}/result \
|
||||
-o result.json
|
||||
```
|
||||
|
||||
### WebSocket Testing
|
||||
|
||||
```bash
|
||||
# Test WebSocket connection (requires websocat)
|
||||
websocat ws://localhost:8011/v1/jobs/{job_id}/ws
|
||||
```
|
||||
|
||||
## Configuration Files
|
||||
|
||||
### .curlrc Configuration
|
||||
|
||||
```bash
|
||||
# ~/.curlrc
|
||||
header = "X-Api-Key: your-api-key"
|
||||
header = "Content-Type: application/json"
|
||||
silent = false
|
||||
show-error = true
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# ~/.bashrc or ~/.zshrc
|
||||
export AITBC_API_KEY="your-api-key"
|
||||
export AITBC_BASE_URL="http://localhost:8011"
|
||||
export AITBC_BLOCKCHAIN_URL="http://localhost:8080"
|
||||
```
|
||||
|
||||
### Shell Functions
|
||||
|
||||
```bash
|
||||
# Add to ~/.bashrc or ~/.zshrc
|
||||
|
||||
# Submit job function
|
||||
aitbc-submit() {
|
||||
curl -X POST $AITBC_BASE_URL/v1/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $AITBC_API_KEY" \
|
||||
-d "$1"
|
||||
}
|
||||
|
||||
# Get job function
|
||||
aitbc-job() {
|
||||
curl -H "X-Api-Key: $AITBC_API_KEY" \
|
||||
$AITBC_BASE_URL/v1/jobs/$1
|
||||
}
|
||||
|
||||
# Get result function
|
||||
aitbc-result() {
|
||||
curl -H "X-Api-Key: $AITBC_API_KEY" \
|
||||
$AITBC_BASE_URL/v1/jobs/$1/result
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Verbose Output
|
||||
|
||||
```bash
|
||||
curl -v -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}
|
||||
```
|
||||
|
||||
### Include Headers in Response
|
||||
|
||||
```bash
|
||||
curl -i -H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}
|
||||
```
|
||||
|
||||
### Timing Information
|
||||
|
||||
```bash
|
||||
curl -w "@curl-format.txt" \
|
||||
-H "X-Api-Key: $API_KEY" \
|
||||
$BASE_URL/v1/jobs/{job_id}
|
||||
```
|
||||
|
||||
### curl-format.txt
|
||||
|
||||
```
|
||||
time_namelookup: %{time_namelookup}s\n
|
||||
time_connect: %{time_connect}s\n
|
||||
time_appconnect: %{time_appconnect}s\n
|
||||
time_pretransfer: %{time_pretransfer}s\n
|
||||
time_redirect: %{time_redirect}s\n
|
||||
time_starttransfer: %{time_starttransfer}s\n
|
||||
----------\n
|
||||
time_total: %{time_total}s\n
|
||||
```
|
||||
417
docs/api/examples/js-sdk-examples.md
Normal file
417
docs/api/examples/js-sdk-examples.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# JavaScript/TypeScript SDK Examples
|
||||
|
||||
This document provides comprehensive examples for using the AITBC JavaScript/TypeScript SDK.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @aitbc/aitbc-sdk
|
||||
```
|
||||
|
||||
## Basic Setup
|
||||
|
||||
```typescript
|
||||
import { AITBCClient } from '@aitbc/aitbc-sdk';
|
||||
|
||||
// Initialize client
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'your-api-key',
|
||||
baseUrl: 'http://localhost:8011'
|
||||
});
|
||||
```
|
||||
|
||||
## Job Submission
|
||||
|
||||
### Simple Job Submission
|
||||
|
||||
```typescript
|
||||
// Submit a simple job
|
||||
const job = await client.submitJob({
|
||||
payload: {
|
||||
model: 'llama2',
|
||||
prompt: 'Hello, world!'
|
||||
},
|
||||
ttlSeconds: 900
|
||||
});
|
||||
|
||||
console.log(`Job ID: ${job.jobId}`);
|
||||
console.log(`State: ${job.state}`);
|
||||
```
|
||||
|
||||
### Job with Constraints
|
||||
|
||||
```typescript
|
||||
// Submit job with GPU constraints
|
||||
const job = await client.submitJob({
|
||||
payload: {
|
||||
model: 'llama2',
|
||||
prompt: 'Hello, world!'
|
||||
},
|
||||
constraints: {
|
||||
minGpuMemory: 8,
|
||||
gpuType: 'nvidia-rtx-3090'
|
||||
},
|
||||
ttlSeconds: 900
|
||||
});
|
||||
```
|
||||
|
||||
### Job with Payment
|
||||
|
||||
```typescript
|
||||
// Submit job with payment
|
||||
const job = await client.submitJob({
|
||||
payload: {
|
||||
model: 'llama2',
|
||||
prompt: 'Hello, world!'
|
||||
},
|
||||
paymentAmount: 100.0,
|
||||
paymentCurrency: 'AITBC',
|
||||
ttlSeconds: 900
|
||||
});
|
||||
|
||||
console.log(`Payment ID: ${job.paymentId}`);
|
||||
```
|
||||
|
||||
## Job Status Monitoring
|
||||
|
||||
### Get Job Status
|
||||
|
||||
```typescript
|
||||
// Get current job status
|
||||
const status = await client.getJob('your-job-id');
|
||||
console.log(`State: ${status.state}`);
|
||||
console.log(`Assigned Miner: ${status.assignedMinerId}`);
|
||||
console.log(`Error: ${status.error}`);
|
||||
```
|
||||
|
||||
### Poll for Completion
|
||||
|
||||
```typescript
|
||||
async function waitForCompletion(jobId: string): Promise<void> {
|
||||
while (true) {
|
||||
const status = await client.getJob(jobId);
|
||||
console.log(`State: ${status.state}`);
|
||||
|
||||
if (['COMPLETED', 'FAILED', 'CANCELLED', 'EXPIRED'].includes(status.state)) {
|
||||
break;
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
}
|
||||
}
|
||||
|
||||
waitForCompletion('your-job-id');
|
||||
```
|
||||
|
||||
### WebSocket for Real-time Updates
|
||||
|
||||
```typescript
|
||||
// Monitor job status via WebSocket
|
||||
const ws = client.watchJob('your-job-id', (update) => {
|
||||
console.log(`Status update: ${JSON.stringify(update)}`);
|
||||
});
|
||||
|
||||
// Close connection when done
|
||||
ws.close();
|
||||
```
|
||||
|
||||
## Job Results
|
||||
|
||||
### Get Job Result
|
||||
|
||||
```typescript
|
||||
// Get job result
|
||||
const result = await client.getJobResult('your-job-id');
|
||||
console.log(`Output: ${JSON.stringify(result.result)}`);
|
||||
console.log(`Receipt: ${JSON.stringify(result.receipt)}`);
|
||||
```
|
||||
|
||||
### Get Receipts
|
||||
|
||||
```typescript
|
||||
// Get latest receipt
|
||||
const receipt = await client.getReceipt('your-job-id');
|
||||
console.log(`Signature: ${receipt.signature}`);
|
||||
|
||||
// Get all receipts
|
||||
const receipts = await client.listReceipts('your-job-id');
|
||||
for (const receipt of receipts) {
|
||||
console.log(`Receipt: ${receipt.signature}`);
|
||||
}
|
||||
```
|
||||
|
||||
## Job Cancellation
|
||||
|
||||
```typescript
|
||||
// Cancel a job
|
||||
const cancelledJob = await client.cancelJob('your-job-id');
|
||||
console.log(`State: ${cancelledJob.state}`);
|
||||
```
|
||||
|
||||
## Payment Operations
|
||||
|
||||
### Get Payment Status
|
||||
|
||||
```typescript
|
||||
// Get payment information
|
||||
const payment = await client.getPayment('your-job-id');
|
||||
console.log(`Status: ${payment.status}`);
|
||||
console.log(`Amount: ${payment.amount}`);
|
||||
```
|
||||
|
||||
## Blockchain Operations
|
||||
|
||||
### Initialize Blockchain Client
|
||||
|
||||
```typescript
|
||||
import { BlockchainClient } from '@aitbc/aitbc-sdk';
|
||||
|
||||
const blockchain = new BlockchainClient({
|
||||
baseUrl: 'http://localhost:8080'
|
||||
});
|
||||
```
|
||||
|
||||
### Get Block Information
|
||||
|
||||
```typescript
|
||||
// Get head block
|
||||
const headBlock = await blockchain.getHeadBlock();
|
||||
console.log(`Current height: ${headBlock.height}`);
|
||||
|
||||
// Get block by height
|
||||
const block = await blockchain.getBlock(12345);
|
||||
console.log(`Block hash: ${block.hash}`);
|
||||
```
|
||||
|
||||
### Network Status
|
||||
|
||||
```typescript
|
||||
// Get network information
|
||||
const network = await blockchain.getNetworkInfo();
|
||||
console.log(`Peer count: ${network.peerCount}`);
|
||||
console.log(`Chain ID: ${network.chainId}`);
|
||||
|
||||
// Get peers
|
||||
const peers = await blockchain.getPeers();
|
||||
for (const peer of peers) {
|
||||
console.log(`Peer: ${peer.address}`);
|
||||
}
|
||||
```
|
||||
|
||||
### Transaction Operations
|
||||
|
||||
```typescript
|
||||
// Get transaction
|
||||
const tx = await blockchain.getTransaction('0x...');
|
||||
console.log(`From: ${tx.from}`);
|
||||
console.log(`To: ${tx.to}`);
|
||||
console.log(`Value: ${tx.value}`);
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import { APIError, AuthenticationError } from '@aitbc/aitbc-sdk';
|
||||
|
||||
try {
|
||||
const job = await client.submitJob({
|
||||
payload: { model: 'llama2', prompt: 'Hello' }
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof AuthenticationError) {
|
||||
console.error('Invalid API key');
|
||||
} else if (error instanceof APIError) {
|
||||
console.error(`API error: ${error.message}`);
|
||||
} else {
|
||||
console.error(`Unexpected error: ${error}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Examples
|
||||
|
||||
### Batch Job Submission
|
||||
|
||||
```typescript
|
||||
// Submit multiple jobs
|
||||
const prompts = ['Hello', 'World', 'Test'];
|
||||
const jobs = await Promise.all(
|
||||
prompts.map(prompt =>
|
||||
client.submitJob({
|
||||
payload: { model: 'llama2', prompt },
|
||||
ttlSeconds: 900
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
console.log(`Submitted ${jobs.length} jobs`);
|
||||
```
|
||||
|
||||
### Job History
|
||||
|
||||
```typescript
|
||||
// Get job history
|
||||
const history = await client.getJobHistory({ limit: 10 });
|
||||
for (const job of history) {
|
||||
console.log(`Job ${job.jobId}: ${job.state}`);
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Headers
|
||||
|
||||
```typescript
|
||||
// Use custom headers
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'your-api-key',
|
||||
baseUrl: 'http://localhost:8011',
|
||||
headers: {
|
||||
'X-Custom-Header': 'value'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## TypeScript Configuration
|
||||
|
||||
```typescript
|
||||
// Enable strict type checking
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```typescript
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
const client = new AITBCClient({
|
||||
apiKey: process.env.AITBC_API_KEY || '',
|
||||
baseUrl: process.env.AITBC_BASE_URL || 'http://localhost:8011'
|
||||
});
|
||||
```
|
||||
|
||||
### Timeout Configuration
|
||||
|
||||
```typescript
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'your-api-key',
|
||||
baseUrl: 'http://localhost:8011',
|
||||
timeout: 30000 // 30 second timeout
|
||||
});
|
||||
```
|
||||
|
||||
## React Integration
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect } from 'react';
|
||||
import { AITBCClient } from '@aitbc/aitbc-sdk';
|
||||
|
||||
function JobComponent({ jobId }: { jobId: string }) {
|
||||
const [status, setStatus] = useState<string | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'your-api-key',
|
||||
baseUrl: 'http://localhost:8011'
|
||||
});
|
||||
|
||||
const fetchStatus = async () => {
|
||||
try {
|
||||
const job = await client.getJob(jobId);
|
||||
setStatus(job.state);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Unknown error');
|
||||
}
|
||||
};
|
||||
|
||||
fetchStatus();
|
||||
}, [jobId]);
|
||||
|
||||
if (error) return <div>Error: {error}</div>;
|
||||
return <div>Job Status: {status}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
## Node.js Integration
|
||||
|
||||
```typescript
|
||||
import express from 'express';
|
||||
import { AITBCClient } from '@aitbc/aitbc-sdk';
|
||||
|
||||
const app = express();
|
||||
const client = new AITBCClient({
|
||||
apiKey: process.env.AITBC_API_KEY!,
|
||||
baseUrl: process.env.AITBC_BASE_URL!
|
||||
});
|
||||
|
||||
app.post('/api/jobs', async (req, res) => {
|
||||
try {
|
||||
const job = await client.submitJob(req.body);
|
||||
res.json(job);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```typescript
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { AITBCClient } from '@aitbc/aitbc-sdk';
|
||||
|
||||
describe('AITBCClient', () => {
|
||||
it('should submit job successfully', async () => {
|
||||
const mockFetch = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
job_id: 'test-id',
|
||||
state: 'QUEUED'
|
||||
})
|
||||
});
|
||||
|
||||
global.fetch = mockFetch;
|
||||
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'test-key',
|
||||
baseUrl: 'http://localhost:8011'
|
||||
});
|
||||
|
||||
const job = await client.submitJob({
|
||||
payload: { model: 'test', prompt: 'Hello' }
|
||||
});
|
||||
|
||||
expect(job.jobId).toBe('test-id');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Receipt Verification
|
||||
|
||||
```typescript
|
||||
import { verifyReceipt } from '@aitbc/aitbc-sdk';
|
||||
|
||||
// Verify receipt signature
|
||||
const receipt = await client.getReceipt('your-job-id');
|
||||
const isValid = verifyReceipt(
|
||||
receipt.signature,
|
||||
receipt.data,
|
||||
'miner-public-key'
|
||||
);
|
||||
|
||||
if (isValid) {
|
||||
console.log('Receipt is valid');
|
||||
} else {
|
||||
console.log('Receipt is invalid');
|
||||
}
|
||||
```
|
||||
315
docs/api/examples/python-sdk-examples.md
Normal file
315
docs/api/examples/python-sdk-examples.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# Python SDK Examples
|
||||
|
||||
This document provides comprehensive examples for using the AITBC Python SDK.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install aitbc-sdk
|
||||
```
|
||||
|
||||
## Basic Setup
|
||||
|
||||
```python
|
||||
import aitbc_sdk
|
||||
|
||||
# Initialize client
|
||||
client = aitbc_sdk.Client(
|
||||
api_key="your-api-key",
|
||||
base_url="http://localhost:8011"
|
||||
)
|
||||
```
|
||||
|
||||
## Job Submission
|
||||
|
||||
### Simple Job Submission
|
||||
|
||||
```python
|
||||
# Submit a simple job
|
||||
job = client.submit_job(
|
||||
payload={
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
ttl_seconds=900
|
||||
)
|
||||
|
||||
print(f"Job ID: {job.job_id}")
|
||||
print(f"State: {job.state}")
|
||||
```
|
||||
|
||||
### Job with Constraints
|
||||
|
||||
```python
|
||||
# Submit job with GPU constraints
|
||||
from aitbc_sdk import Constraints
|
||||
|
||||
job = client.submit_job(
|
||||
payload={
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
constraints=Constraints(
|
||||
min_gpu_memory=8,
|
||||
gpu_type="nvidia-rtx-3090"
|
||||
),
|
||||
ttl_seconds=900
|
||||
)
|
||||
```
|
||||
|
||||
### Job with Payment
|
||||
|
||||
```python
|
||||
# Submit job with payment
|
||||
job = client.submit_job(
|
||||
payload={
|
||||
"model": "llama2",
|
||||
"prompt": "Hello, world!"
|
||||
},
|
||||
payment_amount=100.0,
|
||||
payment_currency="AITBC",
|
||||
ttl_seconds=900
|
||||
)
|
||||
|
||||
print(f"Payment ID: {job.payment_id}")
|
||||
```
|
||||
|
||||
## Job Status Monitoring
|
||||
|
||||
### Get Job Status
|
||||
|
||||
```python
|
||||
# Get current job status
|
||||
status = client.get_job(job_id="your-job-id")
|
||||
print(f"State: {status.state}")
|
||||
print(f"Assigned Miner: {status.assigned_miner_id}")
|
||||
print(f"Error: {status.error}")
|
||||
```
|
||||
|
||||
### Poll for Completion
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
job_id = "your-job-id"
|
||||
|
||||
while True:
|
||||
status = client.get_job(job_id)
|
||||
print(f"State: {status.state}")
|
||||
|
||||
if status.state in ["COMPLETED", "FAILED", "CANCELLED", "EXPIRED"]:
|
||||
break
|
||||
|
||||
time.sleep(5)
|
||||
```
|
||||
|
||||
### WebSocket for Real-time Updates
|
||||
|
||||
```python
|
||||
# Monitor job status via WebSocket
|
||||
def on_status_update(update):
|
||||
print(f"Status update: {update}")
|
||||
|
||||
client.watch_job(job_id="your-job-id", callback=on_status_update)
|
||||
```
|
||||
|
||||
## Job Results
|
||||
|
||||
### Get Job Result
|
||||
|
||||
```python
|
||||
# Get job result
|
||||
result = client.get_job_result(job_id="your-job-id")
|
||||
print(f"Output: {result.result}")
|
||||
print(f"Receipt: {result.receipt}")
|
||||
```
|
||||
|
||||
### Get Receipts
|
||||
|
||||
```python
|
||||
# Get latest receipt
|
||||
receipt = client.get_receipt(job_id="your-job-id")
|
||||
print(f"Signature: {receipt.signature}")
|
||||
|
||||
# Get all receipts
|
||||
receipts = client.list_receipts(job_id="your-job-id")
|
||||
for receipt in receipts:
|
||||
print(f"Receipt: {receipt.signature}")
|
||||
```
|
||||
|
||||
## Job Cancellation
|
||||
|
||||
```python
|
||||
# Cancel a job
|
||||
cancelled_job = client.cancel_job(job_id="your-job-id")
|
||||
print(f"State: {cancelled_job.state}")
|
||||
```
|
||||
|
||||
## Payment Operations
|
||||
|
||||
### Get Payment Status
|
||||
|
||||
```python
|
||||
# Get payment information
|
||||
payment = client.get_payment(job_id="your-job-id")
|
||||
print(f"Status: {payment.status}")
|
||||
print(f"Amount: {payment.amount}")
|
||||
```
|
||||
|
||||
## Blockchain Operations
|
||||
|
||||
### Initialize Blockchain Client
|
||||
|
||||
```python
|
||||
blockchain = aitbc_sdk.BlockchainClient(
|
||||
base_url="http://localhost:8080"
|
||||
)
|
||||
```
|
||||
|
||||
### Get Block Information
|
||||
|
||||
```python
|
||||
# Get head block
|
||||
head_block = blockchain.get_head_block()
|
||||
print(f"Current height: {head_block.height}")
|
||||
|
||||
# Get block by height
|
||||
block = blockchain.get_block(height=12345)
|
||||
print(f"Block hash: {block.hash}")
|
||||
```
|
||||
|
||||
### Network Status
|
||||
|
||||
```python
|
||||
# Get network information
|
||||
network = blockchain.get_network_info()
|
||||
print(f"Peer count: {network.peer_count}")
|
||||
print(f"Chain ID: {network.chain_id}")
|
||||
|
||||
# Get peers
|
||||
peers = blockchain.get_peers()
|
||||
for peer in peers:
|
||||
print(f"Peer: {peer.address}")
|
||||
```
|
||||
|
||||
### Transaction Operations
|
||||
|
||||
```python
|
||||
# Get transaction
|
||||
tx = blockchain.get_transaction(tx_hash="0x...")
|
||||
print(f"From: {tx.from}")
|
||||
print(f"To: {tx.to}")
|
||||
print(f"Value: {tx.value}")
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from aitbc_sdk.exceptions import APIError, AuthenticationError
|
||||
|
||||
try:
|
||||
job = client.submit_job(
|
||||
payload={"model": "llama2", "prompt": "Hello"}
|
||||
)
|
||||
except AuthenticationError:
|
||||
print("Invalid API key")
|
||||
except APIError as e:
|
||||
print(f"API error: {e}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}")
|
||||
```
|
||||
|
||||
## Advanced Examples
|
||||
|
||||
### Batch Job Submission
|
||||
|
||||
```python
|
||||
# Submit multiple jobs
|
||||
jobs = []
|
||||
for prompt in ["Hello", "World", "Test"]:
|
||||
job = client.submit_job(
|
||||
payload={"model": "llama2", "prompt": prompt},
|
||||
ttl_seconds=900
|
||||
)
|
||||
jobs.append(job)
|
||||
|
||||
print(f"Submitted {len(jobs)} jobs")
|
||||
```
|
||||
|
||||
### Job History
|
||||
|
||||
```python
|
||||
# Get job history
|
||||
history = client.get_job_history(limit=10)
|
||||
for job in history:
|
||||
print(f"Job {job.job_id}: {job.state}")
|
||||
```
|
||||
|
||||
### Custom Headers
|
||||
|
||||
```python
|
||||
# Use custom headers
|
||||
client = aitbc_sdk.Client(
|
||||
api_key="your-api-key",
|
||||
base_url="http://localhost:8011",
|
||||
headers={"X-Custom-Header": "value"}
|
||||
)
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```python
|
||||
# Mock client for testing
|
||||
from unittest.mock import Mock
|
||||
|
||||
mock_client = Mock()
|
||||
mock_client.submit_job.return_value = Mock(job_id="test-id", state="QUEUED")
|
||||
|
||||
job = mock_client.submit_job(payload={"model": "test"})
|
||||
assert job.job_id == "test-id"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```python
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
client = aitbc_sdk.Client(
|
||||
api_key=os.getenv("AITBC_API_KEY"),
|
||||
base_url=os.getenv("AITBC_BASE_URL", "http://localhost:8011")
|
||||
)
|
||||
```
|
||||
|
||||
### Timeout Configuration
|
||||
|
||||
```python
|
||||
client = aitbc_sdk.Client(
|
||||
api_key="your-api-key",
|
||||
base_url="http://localhost:8011",
|
||||
timeout=30 # 30 second timeout
|
||||
)
|
||||
```
|
||||
|
||||
## Receipt Verification
|
||||
|
||||
```python
|
||||
import aitbc_crypto
|
||||
|
||||
# Verify receipt signature
|
||||
receipt = client.get_receipt(job_id="your-job-id")
|
||||
is_valid = aitbc_crypto.verify_receipt(
|
||||
receipt.signature,
|
||||
receipt.data,
|
||||
public_key="miner-public-key"
|
||||
)
|
||||
|
||||
if is_valid:
|
||||
print("Receipt is valid")
|
||||
else:
|
||||
print("Receipt is invalid")
|
||||
```
|
||||
Reference in New Issue
Block a user