This commit is contained in:
admin
2026-01-30 03:04:10 +00:00
parent bcc4d242c4
commit 2a3dedde11
1218 changed files with 214731 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
{
"source": "github.com/fal-ai-community/skills/tree/main/skills/claude.ai/fal-platform",
"type": "github-subdir",
"installed_at": "2026-01-30T02:27:27.47340156Z",
"repo_url": "https://github.com/fal-ai-community/skills.git",
"subdir": "skills/claude.ai/fal-platform",
"version": "69efe6e"
}

160
fal-platform/SKILL.md Normal file
View File

@@ -0,0 +1,160 @@
---
name: fal-platform
description: fal.ai Platform APIs for model management, pricing, usage tracking, and cost estimation. Use when user asks "show pricing", "check usage", "estimate cost", "setup fal", "add API key", or platform management tasks.
metadata:
author: fal-ai
version: "1.0.0"
---
# fal.ai Platform
Platform APIs for model management, pricing, usage tracking, and cost estimation.
## Scripts
| Script | Purpose |
|--------|---------|
| `setup.sh` | Setup FAL_KEY and configuration |
| `pricing.sh` | Get model pricing information |
| `usage.sh` | Check usage and billing |
| `estimate-cost.sh` | Estimate costs for operations |
| `requests.sh` | List and manage requests |
## Setup & Configuration
### Add FAL_KEY
```bash
# Interactive setup
bash /mnt/skills/user/fal-platform/scripts/setup.sh --add-fal-key
# Set key directly
bash /mnt/skills/user/fal-platform/scripts/setup.sh --add-fal-key "your_key_here"
# Show current config
bash /mnt/skills/user/fal-platform/scripts/setup.sh --show-config
```
This adds FAL_KEY to your `.env` file for persistent use.
## Model Pricing
Get pricing for any model:
```bash
# Single model pricing
bash /mnt/skills/user/fal-platform/scripts/pricing.sh --model "fal-ai/flux/dev"
# Multiple models
bash /mnt/skills/user/fal-platform/scripts/pricing.sh --model "fal-ai/flux/dev,fal-ai/kling-video/v2.1/pro"
# All pricing for a category
bash /mnt/skills/user/fal-platform/scripts/pricing.sh --category "text-to-image"
```
**Output:**
```
fal-ai/flux/dev
Price: $0.025 per image
Unit: image
fal-ai/kling-video/v2.1/pro
Price: $0.50 per second
Unit: video_second
```
## Usage Tracking
Check your usage and spending:
```bash
# Current period usage
bash /mnt/skills/user/fal-platform/scripts/usage.sh
# Filter by model
bash /mnt/skills/user/fal-platform/scripts/usage.sh --model "fal-ai/flux/dev"
# Date range
bash /mnt/skills/user/fal-platform/scripts/usage.sh --start "2024-01-01" --end "2024-01-31"
# Specific timeframe
bash /mnt/skills/user/fal-platform/scripts/usage.sh --timeframe "day"
```
**Timeframes:** `minute`, `hour`, `day`, `week`, `month`
## Estimate Cost
Estimate costs before running:
```bash
# Estimate by API calls (historical pricing)
bash /mnt/skills/user/fal-platform/scripts/estimate-cost.sh \
--model "fal-ai/flux/dev" \
--calls 100
# Estimate by units
bash /mnt/skills/user/fal-platform/scripts/estimate-cost.sh \
--model "fal-ai/kling-video/v2.1/pro" \
--units 60 \
--type "unit_price"
```
**Output:**
```
Cost Estimate for fal-ai/flux/dev
Quantity: 100 calls
Estimated Cost: $2.50
```
## Request Management
List and manage requests:
```bash
# List recent requests
bash /mnt/skills/user/fal-platform/scripts/requests.sh --model "fal-ai/flux/dev" --limit 10
# Delete request payloads (cleanup)
bash /mnt/skills/user/fal-platform/scripts/requests.sh --delete "request_id_here"
```
## API Endpoints Reference
| Operation | Endpoint | Method |
|-----------|----------|--------|
| Model Search | `GET /models` | GET |
| Pricing | `GET /models/pricing` | GET |
| Usage | `GET /models/usage` | GET |
| List Requests | `GET /models/requests/by-endpoint` | GET |
| Delete Payloads | `DELETE /models/requests/{id}/payloads` | DELETE |
**Base URL:** `https://api.fal.ai/v1`
## Common Flags (All Scripts)
All scripts support these common flags:
```bash
--add-fal-key [KEY] # Add/update FAL_KEY in .env
--help, -h # Show help
--json # Output raw JSON
--quiet, -q # Suppress status messages
```
## Troubleshooting
### API Key Required
```
Error: FAL_KEY required for this operation
Run: bash /mnt/skills/user/fal-platform/scripts/setup.sh --add-fal-key
```
### Permission Denied
```
Error: API key doesn't have permission for this operation
Some operations require admin API keys. Check your key permissions at:
https://fal.ai/dashboard/keys
```

View File

@@ -0,0 +1,161 @@
#!/bin/bash
# fal.ai Cost Estimation Script
# Usage: ./estimate-cost.sh --model MODEL --calls N | --units N
# Returns estimated costs based on pricing data
set -e
FAL_API_BASE="https://api.fal.ai/v1"
# Default values
MODEL=""
CALLS=""
UNITS=""
OUTPUT_JSON=false
# Check for --add-fal-key first
for arg in "$@"; do
if [ "$arg" = "--add-fal-key" ]; then
bash "$(dirname "$0")/setup.sh" "$@"
exit $?
fi
done
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--model|-m)
MODEL="$2"
shift 2
;;
--calls|-c)
CALLS="$2"
shift 2
;;
--units|-u)
UNITS="$2"
shift 2
;;
--json)
OUTPUT_JSON=true
shift
;;
--help|-h)
echo "fal.ai Cost Estimation Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./estimate-cost.sh --model MODEL --calls N Estimate by API calls" >&2
echo " ./estimate-cost.sh --model MODEL --units N Estimate by units" >&2
echo "" >&2
echo "Options:" >&2
echo " --model, -m Model ID (required)" >&2
echo " --calls, -c Number of API calls to estimate" >&2
echo " --units, -u Number of billing units to estimate" >&2
echo " --json Output raw JSON" >&2
echo " --add-fal-key Setup FAL_KEY" >&2
echo "" >&2
echo "Examples:" >&2
echo " ./estimate-cost.sh --model \"fal-ai/flux/dev\" --calls 100" >&2
echo " ./estimate-cost.sh --model \"fal-ai/kling-video/v2.1/pro\" --units 60" >&2
exit 0
;;
*)
shift
;;
esac
done
# Load .env if exists
if [ -f ".env" ]; then
source .env 2>/dev/null || true
fi
# Check for FAL_KEY
if [ -z "$FAL_KEY" ]; then
echo "Error: FAL_KEY required" >&2
echo "" >&2
echo "Run: ./setup.sh --add-fal-key" >&2
exit 1
fi
if [ -z "$MODEL" ]; then
echo "Error: --model is required" >&2
exit 1
fi
if [ -z "$CALLS" ] && [ -z "$UNITS" ]; then
echo "Error: --calls or --units is required" >&2
exit 1
fi
echo "Estimating cost for $MODEL..." >&2
# Get pricing info first
ENCODED_MODEL=$(echo "$MODEL" | sed 's/\//%2F/g')
PRICING_RESPONSE=$(curl -s -X GET "$FAL_API_BASE/models/pricing?endpoint_id=$ENCODED_MODEL" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json")
# Check for errors
if echo "$PRICING_RESPONSE" | grep -q '"error"'; then
ERROR_MSG=$(echo "$PRICING_RESPONSE" | grep -o '"message":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Error: $ERROR_MSG" >&2
exit 1
fi
# Calculate estimate
QUANTITY="${CALLS:-$UNITS}"
ESTIMATE_TYPE="calls"
if [ -n "$UNITS" ]; then
ESTIMATE_TYPE="units"
fi
echo "" >&2
if command -v python3 &> /dev/null; then
python3 << PYTHON_EOF - "$PRICING_RESPONSE" "$MODEL" "$QUANTITY" "$ESTIMATE_TYPE"
import json
import sys
response = json.loads(sys.argv[1])
model = sys.argv[2]
quantity = float(sys.argv[3])
estimate_type = sys.argv[4]
print(f"Cost Estimate: {model}", file=sys.stderr)
print("=" * (len(model) + 15), file=sys.stderr)
print("", file=sys.stderr)
# Extract pricing data
prices = response.get('prices', [response] if isinstance(response, dict) else response)
if isinstance(prices, list) and len(prices) > 0:
price_info = prices[0]
unit_price = float(price_info.get('unit_price', 0))
unit = price_info.get('unit', 'call')
currency = price_info.get('currency', 'USD')
# Calculate estimated cost
estimated_cost = unit_price * quantity
print(f" Unit Price: {unit_price} {currency} per {unit}", file=sys.stderr)
print(f" Quantity: {quantity:.0f} {estimate_type}", file=sys.stderr)
print(f" Estimated Cost: {estimated_cost:.4f} {currency}", file=sys.stderr)
# Output JSON
result = {
"model": model,
"unit_price": unit_price,
"unit": unit,
"quantity": quantity,
"estimated_cost": estimated_cost,
"currency": currency
}
print(json.dumps(result))
else:
print(" Unable to calculate estimate - pricing data not found", file=sys.stderr)
print(json.dumps({"error": "pricing data not found"}))
PYTHON_EOF
else
echo " Python3 required for calculation" >&2
fi

143
fal-platform/scripts/pricing.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
# fal.ai Pricing Script
# Usage: ./pricing.sh --model MODEL [--category CATEGORY]
# Returns pricing information for models
set -e
FAL_API_BASE="https://api.fal.ai/v1"
# Default values
MODELS=""
CATEGORY=""
OUTPUT_JSON=false
# Check for --add-fal-key first
for arg in "$@"; do
if [ "$arg" = "--add-fal-key" ]; then
bash "$(dirname "$0")/setup.sh" "$@"
exit $?
fi
done
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--model|-m)
MODELS="$2"
shift 2
;;
--category|-c)
CATEGORY="$2"
shift 2
;;
--json)
OUTPUT_JSON=true
shift
;;
--help|-h)
echo "fal.ai Pricing Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./pricing.sh --model MODEL Get pricing for model(s)" >&2
echo " ./pricing.sh --category CATEGORY Get pricing for category" >&2
echo "" >&2
echo "Options:" >&2
echo " --model, -m Model ID(s), comma-separated" >&2
echo " --category, -c Filter by category" >&2
echo " --json Output raw JSON" >&2
echo " --add-fal-key Setup FAL_KEY" >&2
echo "" >&2
echo "Examples:" >&2
echo " ./pricing.sh --model \"fal-ai/flux/dev\"" >&2
echo " ./pricing.sh --model \"fal-ai/flux/dev,fal-ai/kling-video/v2.1/pro\"" >&2
exit 0
;;
*)
shift
;;
esac
done
# Load .env if exists
if [ -f ".env" ]; then
source .env 2>/dev/null || true
fi
# Check for FAL_KEY
if [ -z "$FAL_KEY" ]; then
echo "Error: FAL_KEY required" >&2
echo "" >&2
echo "Run: ./setup.sh --add-fal-key" >&2
exit 1
fi
if [ -z "$MODELS" ] && [ -z "$CATEGORY" ]; then
echo "Error: --model or --category required" >&2
exit 1
fi
echo "Fetching pricing information..." >&2
# Build endpoint URL
if [ -n "$MODELS" ]; then
# URL encode the model IDs
ENCODED_MODELS=$(echo "$MODELS" | sed 's/,/%2C/g' | sed 's/\//%2F/g')
ENDPOINT="$FAL_API_BASE/models/pricing?endpoint_id=$ENCODED_MODELS"
else
ENDPOINT="$FAL_API_BASE/models?category=$CATEGORY&include_pricing=true"
fi
# Make API request
RESPONSE=$(curl -s -X GET "$ENDPOINT" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json")
# Check for errors
if echo "$RESPONSE" | grep -q '"error"'; then
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"message":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Error: $ERROR_MSG" >&2
exit 1
fi
if [ "$OUTPUT_JSON" = true ]; then
echo "$RESPONSE"
exit 0
fi
# Parse and display pricing
echo "" >&2
if command -v python3 &> /dev/null; then
python3 << 'PYTHON_EOF' - "$RESPONSE"
import json
import sys
response = json.loads(sys.argv[1])
data = response.get('data', response)
if isinstance(data, list):
for item in data:
endpoint = item.get('endpoint_id', 'Unknown')
pricing = item.get('pricing', {})
print(f"{endpoint}", file=sys.stderr)
if pricing:
price = pricing.get('price', 'N/A')
unit = pricing.get('unit', 'call')
print(f" Price: ${price} per {unit}", file=sys.stderr)
else:
print(f" Pricing: Not available", file=sys.stderr)
print("", file=sys.stderr)
elif isinstance(data, dict):
for endpoint, info in data.items():
print(f"{endpoint}", file=sys.stderr)
if isinstance(info, dict):
price = info.get('price', info.get('unit_price', 'N/A'))
unit = info.get('unit', info.get('billing_unit', 'call'))
print(f" Price: ${price} per {unit}", file=sys.stderr)
print("", file=sys.stderr)
PYTHON_EOF
fi
echo "$RESPONSE"

158
fal-platform/scripts/requests.sh Executable file
View File

@@ -0,0 +1,158 @@
#!/bin/bash
# fal.ai Requests Management Script
# Usage: ./requests.sh --model MODEL [--limit N] | --delete REQUEST_ID
# List and manage API requests
set -e
FAL_API_BASE="https://api.fal.ai/v1"
# Default values
MODEL=""
LIMIT=10
DELETE_ID=""
OUTPUT_JSON=false
# Check for --add-fal-key first
for arg in "$@"; do
if [ "$arg" = "--add-fal-key" ]; then
bash "$(dirname "$0")/setup.sh" "$@"
exit $?
fi
done
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--model|-m)
MODEL="$2"
shift 2
;;
--limit|-l)
LIMIT="$2"
shift 2
;;
--delete|-d)
DELETE_ID="$2"
shift 2
;;
--json)
OUTPUT_JSON=true
shift
;;
--help|-h)
echo "fal.ai Requests Management Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./requests.sh --model MODEL List requests for model" >&2
echo " ./requests.sh --delete REQUEST_ID Delete request payloads" >&2
echo "" >&2
echo "Options:" >&2
echo " --model, -m Model ID to filter" >&2
echo " --limit, -l Max results (default: 10)" >&2
echo " --delete, -d Request ID to delete payloads" >&2
echo " --json Output raw JSON" >&2
echo " --add-fal-key Setup FAL_KEY" >&2
echo "" >&2
echo "Examples:" >&2
echo " ./requests.sh --model \"fal-ai/flux/dev\" --limit 5" >&2
echo " ./requests.sh --delete \"req_abc123\"" >&2
exit 0
;;
*)
shift
;;
esac
done
# Load .env if exists
if [ -f ".env" ]; then
source .env 2>/dev/null || true
fi
# Check for FAL_KEY
if [ -z "$FAL_KEY" ]; then
echo "Error: FAL_KEY required" >&2
echo "" >&2
echo "Run: ./setup.sh --add-fal-key" >&2
exit 1
fi
# Delete request payloads
if [ -n "$DELETE_ID" ]; then
echo "Deleting payloads for request $DELETE_ID..." >&2
RESPONSE=$(curl -s -X DELETE "$FAL_API_BASE/models/requests/$DELETE_ID/payloads" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json")
if echo "$RESPONSE" | grep -q '"error"'; then
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"message":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Error: $ERROR_MSG" >&2
exit 1
fi
echo "Payloads deleted successfully" >&2
echo "$RESPONSE"
exit 0
fi
# List requests
if [ -z "$MODEL" ]; then
echo "Error: --model is required for listing requests" >&2
exit 1
fi
echo "Fetching requests for $MODEL..." >&2
ENCODED_MODEL=$(echo "$MODEL" | sed 's/\//%2F/g')
RESPONSE=$(curl -s -X GET "$FAL_API_BASE/models/requests/by-endpoint?endpoint_id=$ENCODED_MODEL&limit=$LIMIT" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json")
# Check for errors
if echo "$RESPONSE" | grep -q '"error"'; then
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"message":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Error: $ERROR_MSG" >&2
exit 1
fi
if [ "$OUTPUT_JSON" = true ]; then
echo "$RESPONSE"
exit 0
fi
# Parse and display requests
echo "" >&2
if command -v python3 &> /dev/null; then
python3 << 'PYTHON_EOF' - "$RESPONSE"
import json
import sys
response = json.loads(sys.argv[1])
data = response.get('data', response)
if isinstance(data, list):
print(f"Recent Requests ({len(data)} shown)", file=sys.stderr)
print("=" * 40, file=sys.stderr)
for req in data:
request_id = req.get('request_id', req.get('id', 'unknown'))
status = req.get('status', 'unknown')
created = req.get('created_at', req.get('timestamp', ''))[:19]
duration = req.get('duration', 0)
print(f"", file=sys.stderr)
print(f" ID: {request_id}", file=sys.stderr)
print(f" Status: {status}", file=sys.stderr)
print(f" Created: {created}", file=sys.stderr)
if duration:
print(f" Duration: {duration:.2f}s", file=sys.stderr)
else:
print("No requests found", file=sys.stderr)
PYTHON_EOF
fi
echo "$RESPONSE"

126
fal-platform/scripts/setup.sh Executable file
View File

@@ -0,0 +1,126 @@
#!/bin/bash
# fal.ai Setup Script
# Usage: ./setup.sh --add-fal-key [KEY] | --show-config
# Manages FAL_KEY and configuration
set -e
ENV_FILE=".env"
ACTION=""
FAL_KEY_VALUE=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--add-fal-key)
ACTION="add-key"
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
FAL_KEY_VALUE="$2"
shift
fi
shift
;;
--show-config)
ACTION="show-config"
shift
;;
--help|-h)
echo "fal.ai Setup Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./setup.sh --add-fal-key [KEY] Add or update FAL_KEY" >&2
echo " ./setup.sh --show-config Show current configuration" >&2
echo "" >&2
echo "Examples:" >&2
echo " ./setup.sh --add-fal-key # Interactive prompt" >&2
echo " ./setup.sh --add-fal-key \"your_key_here\" # Direct set" >&2
echo "" >&2
echo "Get your API key at: https://fal.ai/dashboard/keys" >&2
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Use --help for usage information" >&2
exit 1
;;
esac
done
# Show config
if [ "$ACTION" = "show-config" ]; then
echo "fal.ai Configuration" >&2
echo "===================" >&2
if [ -f "$ENV_FILE" ]; then
echo "Environment file: $ENV_FILE" >&2
if grep -q "FAL_KEY" "$ENV_FILE" 2>/dev/null; then
KEY=$(grep "FAL_KEY" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
MASKED="${KEY:0:8}...${KEY: -4}"
echo "FAL_KEY: $MASKED (set)" >&2
else
echo "FAL_KEY: not set" >&2
fi
else
echo "Environment file: not found" >&2
fi
if [ -n "$FAL_KEY" ]; then
MASKED="${FAL_KEY:0:8}...${FAL_KEY: -4}"
echo "FAL_KEY (env): $MASKED" >&2
fi
exit 0
fi
# Add FAL_KEY
if [ "$ACTION" = "add-key" ]; then
# Get key value
if [ -z "$FAL_KEY_VALUE" ]; then
echo "Enter your fal.ai API key:" >&2
echo "(Get it from https://fal.ai/dashboard/keys)" >&2
read -r FAL_KEY_VALUE
fi
if [ -z "$FAL_KEY_VALUE" ]; then
echo "Error: No API key provided" >&2
exit 1
fi
# Validate key format (basic check)
if [[ ! "$FAL_KEY_VALUE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Warning: API key contains unusual characters" >&2
fi
# Update or create .env file
if [ -f "$ENV_FILE" ]; then
# Remove existing FAL_KEY line
grep -v "^FAL_KEY=" "$ENV_FILE" > "$ENV_FILE.tmp" 2>/dev/null || true
mv "$ENV_FILE.tmp" "$ENV_FILE"
fi
# Add new FAL_KEY
echo "FAL_KEY=$FAL_KEY_VALUE" >> "$ENV_FILE"
echo "" >&2
echo "FAL_KEY saved to $ENV_FILE" >&2
echo "" >&2
echo "To use in current session, run:" >&2
echo " source $ENV_FILE" >&2
echo "" >&2
echo "Or export directly:" >&2
echo " export FAL_KEY=$FAL_KEY_VALUE" >&2
# Output JSON
echo "{\"success\": true, \"env_file\": \"$ENV_FILE\"}"
exit 0
fi
# Default: show help
echo "fal.ai Setup Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./setup.sh --add-fal-key [KEY] Add or update FAL_KEY" >&2
echo " ./setup.sh --show-config Show current configuration" >&2
echo "" >&2
echo "Get your API key at: https://fal.ai/dashboard/keys" >&2

183
fal-platform/scripts/usage.sh Executable file
View File

@@ -0,0 +1,183 @@
#!/bin/bash
# fal.ai Usage Script
# Usage: ./usage.sh [--model MODEL] [--start DATE] [--end DATE] [--timeframe TF]
# Returns usage information and billing
set -e
FAL_API_BASE="https://api.fal.ai/v1"
# Default values
MODEL=""
START_DATE=""
END_DATE=""
TIMEFRAME=""
OUTPUT_JSON=false
# Check for --add-fal-key first
for arg in "$@"; do
if [ "$arg" = "--add-fal-key" ]; then
bash "$(dirname "$0")/setup.sh" "$@"
exit $?
fi
done
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--model|-m)
MODEL="$2"
shift 2
;;
--start|-s)
START_DATE="$2"
shift 2
;;
--end|-e)
END_DATE="$2"
shift 2
;;
--timeframe|-t)
TIMEFRAME="$2"
shift 2
;;
--json)
OUTPUT_JSON=true
shift
;;
--help|-h)
echo "fal.ai Usage Script" >&2
echo "" >&2
echo "Usage:" >&2
echo " ./usage.sh Get current usage" >&2
echo " ./usage.sh --model MODEL Filter by model" >&2
echo " ./usage.sh --start DATE --end DATE Date range" >&2
echo "" >&2
echo "Options:" >&2
echo " --model, -m Model ID to filter" >&2
echo " --start, -s Start date (ISO8601 or YYYY-MM-DD)" >&2
echo " --end, -e End date" >&2
echo " --timeframe, -t Aggregation: minute, hour, day, week, month" >&2
echo " --json Output raw JSON" >&2
echo " --add-fal-key Setup FAL_KEY" >&2
echo "" >&2
echo "Examples:" >&2
echo " ./usage.sh" >&2
echo " ./usage.sh --model \"fal-ai/flux/dev\"" >&2
echo " ./usage.sh --start \"2024-01-01\" --end \"2024-01-31\"" >&2
exit 0
;;
*)
shift
;;
esac
done
# Load .env if exists
if [ -f ".env" ]; then
source .env 2>/dev/null || true
fi
# Check for FAL_KEY
if [ -z "$FAL_KEY" ]; then
echo "Error: FAL_KEY required" >&2
echo "" >&2
echo "Run: ./setup.sh --add-fal-key" >&2
exit 1
fi
echo "Fetching usage information..." >&2
# Build query parameters
PARAMS="expand=time_series,summary"
if [ -n "$MODEL" ]; then
ENCODED_MODEL=$(echo "$MODEL" | sed 's/\//%2F/g')
PARAMS="$PARAMS&endpoint_id=$ENCODED_MODEL"
fi
if [ -n "$START_DATE" ]; then
PARAMS="$PARAMS&start=$START_DATE"
fi
if [ -n "$END_DATE" ]; then
PARAMS="$PARAMS&end=$END_DATE"
fi
if [ -n "$TIMEFRAME" ]; then
PARAMS="$PARAMS&timeframe=$TIMEFRAME"
fi
# Make API request
RESPONSE=$(curl -s -X GET "$FAL_API_BASE/models/usage?$PARAMS" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json")
# Check for errors
if echo "$RESPONSE" | grep -q '"error"'; then
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"message":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "Error: $ERROR_MSG" >&2
exit 1
fi
if [ "$OUTPUT_JSON" = true ]; then
echo "$RESPONSE"
exit 0
fi
# Parse and display usage
echo "" >&2
if command -v python3 &> /dev/null; then
python3 << 'PYTHON_EOF' - "$RESPONSE"
import json
import sys
response = json.loads(sys.argv[1])
# Handle both dict and list responses
if isinstance(response, list):
data = response
else:
data = response.get('time_series', response.get('data', []))
# Summary if available
summary = response.get('summary', {})
if isinstance(summary, dict) and summary:
print("Usage Summary", file=sys.stderr)
print("=============", file=sys.stderr)
total_cost = summary.get('total_cost', summary.get('cost', 0))
total_requests = summary.get('total_requests', summary.get('request_count', 0))
print(f" Total Cost: ${total_cost:.4f}", file=sys.stderr)
print(f" Total Requests: {total_requests}", file=sys.stderr)
print("", file=sys.stderr)
# Process time_series data
if isinstance(data, list) and len(data) > 0:
by_endpoint = {}
for bucket in data:
results = bucket.get('results', [bucket]) if isinstance(bucket, dict) else [bucket]
for item in results:
if not isinstance(item, dict):
continue
endpoint = item.get('endpoint_id', '')
if not endpoint:
continue
if endpoint not in by_endpoint:
by_endpoint[endpoint] = {'cost': 0, 'quantity': 0}
by_endpoint[endpoint]['cost'] += float(item.get('cost', 0))
by_endpoint[endpoint]['quantity'] += float(item.get('quantity', item.get('request_count', 0)))
if by_endpoint:
print("Usage by Endpoint", file=sys.stderr)
print("=================", file=sys.stderr)
for endpoint, stats in by_endpoint.items():
print(f" {endpoint}", file=sys.stderr)
print(f" Cost: ${stats['cost']:.4f}", file=sys.stderr)
print(f" Quantity: {stats['quantity']:.2f}", file=sys.stderr)
else:
print("No usage data found for this period", file=sys.stderr)
PYTHON_EOF
fi
echo "$RESPONSE"