mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 20:28:23 +00:00
edits
This commit is contained in:
+4
-4
@@ -23,8 +23,6 @@ docs/
|
||||
│ ├── architecture.md # System architecture
|
||||
│ ├── code-structure.md # Codebase organization
|
||||
│ ├── testing.md # Testing guide
|
||||
│ ├── database.md # Database design
|
||||
│ └── guidelines.md # Contribution guidelines
|
||||
├── api/ # API reference
|
||||
│ ├── overview.md # API overview
|
||||
│ ├── authentication.md # Auth details
|
||||
@@ -63,7 +61,7 @@ mkdocs serve
|
||||
make docs-serve
|
||||
```
|
||||
|
||||
Visit http://localhost:8001 to view the documentation.
|
||||
Visit <http://localhost:8000> to view the documentation.
|
||||
|
||||
### Building Static Site
|
||||
|
||||
@@ -130,6 +128,7 @@ graph LR
|
||||
A[Client] --> B[Routstr]
|
||||
B --> C[Provider]
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
#### Code Blocks
|
||||
@@ -139,6 +138,7 @@ graph LR
|
||||
def example():
|
||||
return "Hello, Routstr!"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
## Contributing to Docs
|
||||
@@ -152,4 +152,4 @@ def example():
|
||||
|
||||
- [MkDocs Documentation](https://www.mkdocs.org/)
|
||||
- [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)
|
||||
- [Mermaid Diagrams](https://mermaid-js.github.io/mermaid/)
|
||||
- [Mermaid Diagrams](https://mermaid-js.github.io/mermaid/)
|
||||
|
||||
@@ -5,6 +5,7 @@ This guide covers database schema management using Alembic migrations in Routstr
|
||||
## Overview
|
||||
|
||||
Routstr uses Alembic for database migrations with these features:
|
||||
|
||||
- **Automatic migrations** on startup
|
||||
- **Version control** for schema changes
|
||||
- **Rollback capability** for safety
|
||||
@@ -27,6 +28,7 @@ async def lifespan(_: FastAPI) -> AsyncGenerator[None, None]:
|
||||
```
|
||||
|
||||
This ensures:
|
||||
|
||||
- ✅ Database is always up-to-date
|
||||
- ✅ No manual migration steps in production
|
||||
- ✅ Zero-downtime deployments
|
||||
@@ -35,6 +37,7 @@ This ensures:
|
||||
### Migration Safety
|
||||
|
||||
Migrations are designed to be safe:
|
||||
|
||||
- Idempotent (can run multiple times)
|
||||
- Non-destructive by default
|
||||
- Tested before release
|
||||
@@ -404,6 +407,7 @@ async def test_migration_with_data():
|
||||
Strategy for seamless updates:
|
||||
|
||||
1. **Make migrations backwards compatible**
|
||||
|
||||
```python
|
||||
# Good: Add nullable column
|
||||
op.add_column('apikey', sa.Column('new_field', sa.String(), nullable=True))
|
||||
@@ -413,6 +417,7 @@ Strategy for seamless updates:
|
||||
```
|
||||
|
||||
2. **Deploy in phases**
|
||||
|
||||
```bash
|
||||
# Phase 1: Deploy code that works with both schemas
|
||||
# Phase 2: Run migration
|
||||
@@ -421,6 +426,7 @@ Strategy for seamless updates:
|
||||
```
|
||||
|
||||
3. **Use feature flags**
|
||||
|
||||
```python
|
||||
if feature_enabled('use_new_schema'):
|
||||
# Use new column
|
||||
@@ -478,6 +484,7 @@ alembic current
|
||||
### Common Issues
|
||||
|
||||
**Migration Conflicts**
|
||||
|
||||
```bash
|
||||
# Multiple heads detected
|
||||
alembic heads
|
||||
@@ -489,6 +496,7 @@ alembic merge -m "Merge migrations" a1b2c3 b2c3d4
|
||||
```
|
||||
|
||||
**Failed Migration**
|
||||
|
||||
```python
|
||||
# Add rollback logic
|
||||
def upgrade():
|
||||
@@ -505,6 +513,7 @@ def downgrade():
|
||||
```
|
||||
|
||||
**Lock Timeout**
|
||||
|
||||
```python
|
||||
# Add timeout handling
|
||||
def upgrade():
|
||||
@@ -526,12 +535,14 @@ def upgrade():
|
||||
If migration fails in production:
|
||||
|
||||
1. **Check current state**
|
||||
|
||||
```bash
|
||||
alembic current
|
||||
alembic history
|
||||
```
|
||||
|
||||
2. **Manual rollback if needed**
|
||||
|
||||
```sql
|
||||
-- Check migration table
|
||||
SELECT * FROM alembic_version;
|
||||
@@ -541,6 +552,7 @@ If migration fails in production:
|
||||
```
|
||||
|
||||
3. **Fix and retry**
|
||||
|
||||
```bash
|
||||
# Fix migration file
|
||||
vim migrations/versions/problematic_migration.py
|
||||
@@ -563,6 +575,7 @@ If migration fails in production:
|
||||
- Test database-specific features
|
||||
|
||||
3. **Document breaking changes**
|
||||
|
||||
```python
|
||||
"""BREAKING: Change balance column type
|
||||
|
||||
@@ -575,6 +588,7 @@ If migration fails in production:
|
||||
```
|
||||
|
||||
4. **Make migrations idempotent**
|
||||
|
||||
```python
|
||||
def upgrade():
|
||||
# Check if column exists
|
||||
@@ -591,6 +605,7 @@ If migration fails in production:
|
||||
### Performance Considerations
|
||||
|
||||
1. **Add indexes concurrently (PostgreSQL)**
|
||||
|
||||
```python
|
||||
def upgrade():
|
||||
# Create index without locking table
|
||||
@@ -603,6 +618,7 @@ If migration fails in production:
|
||||
```
|
||||
|
||||
2. **Batch large updates**
|
||||
|
||||
```python
|
||||
def upgrade():
|
||||
connection = op.get_bind()
|
||||
@@ -626,6 +642,5 @@ If migration fails in production:
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Database Guide](../contributing/database.md) - Database design details
|
||||
- [Testing Guide](../contributing/testing.md) - Testing migrations
|
||||
- [Deployment](../getting-started/docker.md) - Production deployment
|
||||
- [Deployment](../getting-started/docker.md) - Production deployment
|
||||
|
||||
@@ -123,7 +123,7 @@ proxies = {
|
||||
http_client = httpx.Client(proxies=proxies)
|
||||
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="http://roustrjfsdgfiueghsklchg.onion/v1",
|
||||
http_client=http_client
|
||||
)
|
||||
@@ -159,7 +159,7 @@ const agent = new SocksProxyAgent('socks5://127.0.0.1:9050');
|
||||
|
||||
// Configure OpenAI client
|
||||
const openai = new OpenAI({
|
||||
apiKey: 'rstr_your_key',
|
||||
apiKey: 'sk-...',
|
||||
baseURL: 'http://roustrjfsdgfiueghsklchg.onion/v1',
|
||||
httpAgent: agent
|
||||
});
|
||||
@@ -527,5 +527,4 @@ server {
|
||||
## Next Steps
|
||||
|
||||
- [Nostr Discovery](nostr.md) - Announce your onion service
|
||||
- [Security Guide](../contributing/guidelines.md#security) - Security best practices
|
||||
- [Docker Setup](../getting-started/docker.md) - Container configuration
|
||||
|
||||
+11
-11
@@ -8,7 +8,7 @@ Routstr uses API key authentication for all protected endpoints. This guide cove
|
||||
|
||||
Create an API key by depositing an eCash token:
|
||||
|
||||
**Note: The POST /v1/wallet/create endpoint is coming soon. Currently, you can use Cashu tokens directly as API keys in the Authorization header.**
|
||||
**Note: The POST /v1/wallet/create endpoint is coming soon. Currently, you can use Cashu tokens directly as API credentials in the Authorization header. The token is hashed on the server, and the hash acts as an API key with the token's balance.**
|
||||
|
||||
```bash
|
||||
POST /v1/wallet/create
|
||||
@@ -29,7 +29,7 @@ Content-Type: application/json
|
||||
|
||||
```json
|
||||
{
|
||||
"api_key": "rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p",
|
||||
"api_key": "sk-1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p",
|
||||
"balance": 10000,
|
||||
"created_at": "2024-01-01T00:00:00Z",
|
||||
"key_id": "key_123456"
|
||||
@@ -58,7 +58,7 @@ Include the API key in the Authorization header:
|
||||
|
||||
```bash
|
||||
curl https://your-node.com/v1/chat/completions \
|
||||
-H "Authorization: Bearer rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p" \
|
||||
-H "Authorization: Bearer sk-1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hello"}]}'
|
||||
```
|
||||
@@ -68,7 +68,7 @@ curl https://your-node.com/v1/chat/completions \
|
||||
For tools that don't support headers:
|
||||
|
||||
```bash
|
||||
GET /v1/models?api_key=rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
|
||||
GET /v1/models?api_key=sk-1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
|
||||
```
|
||||
|
||||
⚠️ **Warning**: Query parameters may be logged. Use headers when possible.
|
||||
@@ -81,7 +81,7 @@ Get current balance and usage statistics:
|
||||
|
||||
```bash
|
||||
GET /v1/wallet/balance
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
|
||||
Response:
|
||||
{
|
||||
@@ -104,7 +104,7 @@ Add funds to existing key:
|
||||
|
||||
```bash
|
||||
POST /v1/wallet/topup
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -126,7 +126,7 @@ View transaction history:
|
||||
|
||||
```bash
|
||||
GET /v1/wallet/transactions?limit=10
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
|
||||
Response:
|
||||
{
|
||||
@@ -175,7 +175,7 @@ Response:
|
||||
|
||||
```bash
|
||||
# .env file
|
||||
ROUTSTR_API_KEY=rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
|
||||
ROUTSTR_API_KEY=sk-1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p
|
||||
ROUTSTR_BASE_URL=https://your-node.com/v1
|
||||
|
||||
# Usage in code
|
||||
@@ -313,7 +313,7 @@ Create sub-keys with limited permissions:
|
||||
|
||||
```bash
|
||||
POST /v1/wallet/create/subkey
|
||||
Authorization: Bearer rstr_parent_key
|
||||
Authorization: Bearer sk-parent-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -375,7 +375,7 @@ Restrict API key usage by IP:
|
||||
|
||||
```bash
|
||||
POST /v1/wallet/update
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -394,7 +394,7 @@ Set up usage notifications:
|
||||
|
||||
```bash
|
||||
POST /v1/wallet/alerts
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ https://api.routstr.com/v1
|
||||
|
||||
All endpoints require authentication via:
|
||||
|
||||
- **Bearer Token**: `Authorization: Bearer rstr_your_api_key`
|
||||
- **Bearer Token**: `Authorization: Bearer sk-...` or `Authorization: Bearer cashuAeyJ0...`
|
||||
- **X-Cashu Header**: `X-Cashu: cashuAeyJ0...` (for direct eCash payments)
|
||||
|
||||
See [Authentication](authentication.md) for details.
|
||||
@@ -352,7 +352,7 @@ POST /v1/wallet/create
|
||||
|
||||
```json
|
||||
{
|
||||
"api_key": "rstr_1234567890abcdef",
|
||||
"api_key": "sk-1234567890abcdef",
|
||||
"admin_key": "radmin_fedcba0987654321",
|
||||
"balance": 10000,
|
||||
"mint": "https://mint.example.com",
|
||||
@@ -366,7 +366,7 @@ Get current wallet balance.
|
||||
|
||||
```http
|
||||
GET /v1/wallet/balance
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
```
|
||||
|
||||
**Response:**
|
||||
@@ -385,7 +385,7 @@ Add funds to existing wallet.
|
||||
|
||||
```http
|
||||
POST /v1/wallet/topup
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
@@ -412,7 +412,7 @@ Withdraw balance as eCash.
|
||||
|
||||
```http
|
||||
POST /v1/wallet/withdraw
|
||||
Authorization: Bearer rstr_your_api_key
|
||||
Authorization: Bearer sk-...
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
|
||||
+3
-2
@@ -220,6 +220,7 @@ All errors follow a consistent JSON structure:
|
||||
|
||||
**Status:** 429
|
||||
**Headers:**
|
||||
|
||||
```
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 0
|
||||
@@ -547,7 +548,7 @@ async def test_insufficient_balance_handling():
|
||||
async def test_real_error_scenarios():
|
||||
# Test with invalid API key
|
||||
invalid_client = OpenAI(
|
||||
api_key="rstr_invalid",
|
||||
api_key="sk-invalid",
|
||||
base_url=test_url
|
||||
)
|
||||
|
||||
@@ -588,4 +589,4 @@ class ErrorMetrics:
|
||||
|
||||
- [Authentication](authentication.md) - Auth error details
|
||||
- [Endpoints](endpoints.md) - Endpoint-specific errors
|
||||
- [Examples](../user-guide/using-api.md) - Error handling examples
|
||||
- [Examples](../user-guide/using-api.md) - Error handling examples
|
||||
|
||||
+23
-7
@@ -15,14 +15,22 @@ All API endpoints are prefixed with `/v1` for versioning.
|
||||
Routstr uses API keys for authentication. Include your key in the Authorization header:
|
||||
|
||||
```bash
|
||||
Authorization: Bearer rstr_your_api_key_here
|
||||
Authorization: Bearer sk-...
|
||||
```
|
||||
|
||||
### API Key Format
|
||||
|
||||
- Prefix: `rstr_`
|
||||
- Prefix: `sk-`
|
||||
- Length: 32 characters
|
||||
- Example: `rstr_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p`
|
||||
- Example: `sk-1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p`
|
||||
|
||||
### Cashu Tokens as Authentication
|
||||
|
||||
You can also use a Cashu eCash token directly in the `Authorization` header. The server hashes the token internally; this hash represents your API key identity and carries the token's balance.
|
||||
|
||||
```bash
|
||||
Authorization: Bearer cashuAeyJ0b2tlbiI6W3...
|
||||
```
|
||||
|
||||
## Content Types
|
||||
|
||||
@@ -47,6 +55,7 @@ Rate limits are applied per API key:
|
||||
- **Concurrent**: 10 simultaneous requests
|
||||
|
||||
Rate limit headers:
|
||||
|
||||
```
|
||||
X-RateLimit-Limit: 1000
|
||||
X-RateLimit-Remaining: 999
|
||||
@@ -172,6 +181,7 @@ GET /openapi.json
|
||||
```
|
||||
|
||||
Interactive documentation:
|
||||
|
||||
```
|
||||
GET /docs # Swagger UI
|
||||
GET /redoc # ReDoc
|
||||
@@ -182,29 +192,32 @@ GET /redoc # ReDoc
|
||||
Routstr is compatible with official OpenAI SDKs:
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://your-node.com/v1"
|
||||
)
|
||||
```
|
||||
|
||||
### JavaScript/TypeScript
|
||||
|
||||
```javascript
|
||||
import OpenAI from 'openai';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: 'rstr_your_key',
|
||||
apiKey: 'sk-...',
|
||||
baseURL: 'https://your-node.com/v1'
|
||||
});
|
||||
```
|
||||
|
||||
### cURL
|
||||
|
||||
```bash
|
||||
curl https://your-node.com/v1/chat/completions \
|
||||
-H "Authorization: Bearer rstr_your_key" \
|
||||
-H "Authorization: Bearer sk-..." \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hello"}]}'
|
||||
```
|
||||
@@ -223,6 +236,7 @@ POST /v1/webhooks
|
||||
```
|
||||
|
||||
Events are sent with signature verification:
|
||||
|
||||
```
|
||||
X-Webhook-Signature: sha256=...
|
||||
```
|
||||
@@ -265,6 +279,7 @@ Access-Control-Max-Age: 86400
|
||||
## Compression
|
||||
|
||||
Responses are compressed with gzip when:
|
||||
|
||||
- Client sends `Accept-Encoding: gzip`
|
||||
- Response is larger than 1KB
|
||||
- Content type is compressible
|
||||
@@ -278,6 +293,7 @@ GET /v1/transactions?limit=50&offset=100
|
||||
```
|
||||
|
||||
Response includes pagination metadata:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [...],
|
||||
@@ -346,4 +362,4 @@ Response:
|
||||
- [Authentication](authentication.md) - Detailed auth guide
|
||||
- [Endpoints](endpoints.md) - Complete endpoint reference
|
||||
- [Errors](errors.md) - Error handling guide
|
||||
- [Examples](../user-guide/using-api.md) - Code examples
|
||||
- [Examples](../user-guide/using-api.md) - Code examples
|
||||
|
||||
@@ -309,6 +309,7 @@ logger.info("api_request", extra={
|
||||
### Metrics Collection
|
||||
|
||||
Key metrics tracked:
|
||||
|
||||
- Request rate by endpoint
|
||||
- Token usage by model
|
||||
- Balance changes
|
||||
@@ -368,6 +369,7 @@ FROM python:3.11-slim
|
||||
### Technical Debt
|
||||
|
||||
Areas for improvement:
|
||||
|
||||
- Database query optimization
|
||||
- Response caching layer
|
||||
- Metric aggregation
|
||||
@@ -377,5 +379,3 @@ Areas for improvement:
|
||||
|
||||
- Review [Code Structure](code-structure.md) for detailed organization
|
||||
- See [Testing Guide](testing.md) for test architecture
|
||||
- Check [Database Guide](database.md) for schema details
|
||||
- Read [Guidelines](guidelines.md) for coding standards
|
||||
@@ -69,6 +69,7 @@ routstr-core/
|
||||
### Application Entry Point
|
||||
|
||||
#### `routstr/__init__.py`
|
||||
|
||||
```python
|
||||
# Loads environment variables
|
||||
import dotenv
|
||||
@@ -79,6 +80,7 @@ from .core.main import app as fastapi_app
|
||||
```
|
||||
|
||||
#### `routstr/core/main.py`
|
||||
|
||||
```python
|
||||
# FastAPI application setup
|
||||
app = FastAPI(
|
||||
@@ -118,6 +120,7 @@ async def protected_route(api_key: APIKey = Depends(APIKeyAuth())):
|
||||
```
|
||||
|
||||
Key functions:
|
||||
|
||||
- `create_api_key()` - Generate new API keys
|
||||
- `validate_api_key()` - Verify and retrieve key
|
||||
- `check_balance()` - Ensure sufficient funds
|
||||
@@ -202,6 +205,7 @@ async def proxy_request(
|
||||
```
|
||||
|
||||
Key features:
|
||||
|
||||
- Streaming support
|
||||
- Header preservation
|
||||
- Error handling
|
||||
@@ -257,6 +261,7 @@ async def withdraw_balance(
|
||||
```
|
||||
|
||||
Features:
|
||||
|
||||
- HTML dashboard
|
||||
- API key management
|
||||
- Balance withdrawals
|
||||
@@ -485,6 +490,4 @@ except SpecificError as e:
|
||||
## Next Steps
|
||||
|
||||
- Review [Testing Guide](testing.md) for test structure
|
||||
- See [Database Guide](database.md) for schema details
|
||||
- Check [Guidelines](guidelines.md) for coding standards
|
||||
- Read [Architecture](architecture.md) for system design
|
||||
- Read [Architecture](architecture.md) for system design
|
||||
|
||||
@@ -46,6 +46,7 @@ make setup
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- ✅ Install uv if not present
|
||||
- ✅ Create a virtual environment
|
||||
- ✅ Install all dependencies
|
||||
@@ -61,6 +62,7 @@ cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` with your configuration:
|
||||
|
||||
```bash
|
||||
# Minimum required for development
|
||||
UPSTREAM_BASE_URL=https://api.openai.com/v1
|
||||
@@ -213,6 +215,7 @@ routstr-core/
|
||||
5. Add integration tests
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
# In routstr/core/main.py or appropriate router
|
||||
@app.get("/v1/stats")
|
||||
@@ -232,6 +235,7 @@ async def get_stats(
|
||||
4. Apply: `make db-upgrade`
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
class Transaction(SQLModel, table=True):
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
@@ -282,12 +286,14 @@ make docker-build # Build Docker image
|
||||
#### VS Code
|
||||
|
||||
Recommended extensions:
|
||||
|
||||
- Python
|
||||
- Pylance
|
||||
- Ruff
|
||||
- GitLens
|
||||
|
||||
Settings (`.vscode/settings.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"python.linting.enabled": true,
|
||||
@@ -333,6 +339,7 @@ uv run pytest tests/unit/test_auth.py --pdb
|
||||
### Common Issues
|
||||
|
||||
**Import Errors**
|
||||
|
||||
```bash
|
||||
# Ensure project is installed in editable mode
|
||||
uv sync
|
||||
@@ -340,6 +347,7 @@ uv pip install -e .
|
||||
```
|
||||
|
||||
**Database Errors**
|
||||
|
||||
```bash
|
||||
# Reset database
|
||||
rm dev.db
|
||||
@@ -347,6 +355,7 @@ make db-upgrade
|
||||
```
|
||||
|
||||
**Type Checking Fails**
|
||||
|
||||
```bash
|
||||
# Clear mypy cache
|
||||
make clean
|
||||
@@ -354,6 +363,7 @@ make type-check
|
||||
```
|
||||
|
||||
**Tests Fail Locally**
|
||||
|
||||
```bash
|
||||
# Ensure test dependencies are installed
|
||||
uv sync --dev
|
||||
@@ -365,7 +375,6 @@ rm -rf test_*.db
|
||||
### Getting Help
|
||||
|
||||
- Check existing [GitHub Issues](https://github.com/routstr/routstr-core/issues)
|
||||
- Review [Contributing Guidelines](guidelines.md)
|
||||
- Ask in [GitHub Discussions](https://github.com/routstr/routstr-core/discussions)
|
||||
- Read the [Architecture Guide](architecture.md)
|
||||
|
||||
@@ -374,8 +383,7 @@ rm -rf test_*.db
|
||||
Now that you're set up:
|
||||
|
||||
1. Read the [Architecture Overview](architecture.md)
|
||||
2. Review [Code Standards](guidelines.md)
|
||||
3. Check [open issues](https://github.com/routstr/routstr-core/issues)
|
||||
4. Start with a small contribution
|
||||
|
||||
Happy coding! 🚀
|
||||
Happy coding! 🚀
|
||||
|
||||
@@ -5,6 +5,7 @@ This guide covers testing practices, patterns, and tools used in Routstr Core de
|
||||
## Testing Philosophy
|
||||
|
||||
We follow these principles:
|
||||
|
||||
- **Test Behavior, Not Implementation** - Tests should survive refactoring
|
||||
- **Fast Feedback** - Unit tests run in milliseconds
|
||||
- **Reliable Tests** - No flaky tests allowed
|
||||
@@ -100,7 +101,7 @@ class TestAPIKeyAuth:
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert api_key.key.startswith("rstr_")
|
||||
assert api_key.key.startswith("sk-")
|
||||
assert len(api_key.key) == 32
|
||||
assert api_key.balance == initial_balance
|
||||
|
||||
@@ -385,7 +386,7 @@ from datetime import datetime, timedelta
|
||||
def create_test_api_key(**kwargs):
|
||||
"""Factory for test API keys"""
|
||||
defaults = {
|
||||
"key": f"rstr_test_{uuid4().hex[:8]}",
|
||||
"key": f"sk-test-{uuid4().hex[:8]}",
|
||||
"balance": 10000,
|
||||
"created_at": datetime.utcnow(),
|
||||
"expires_at": datetime.utcnow() + timedelta(days=30)
|
||||
@@ -414,7 +415,7 @@ TEST_MODELS = {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_KEY = "rstr_test_1234567890"
|
||||
TEST_API_KEY = "sk-test-1234567890"
|
||||
TEST_MINT_URL = "https://testmint.example.com"
|
||||
```
|
||||
|
||||
@@ -498,6 +499,7 @@ async def test_logging(caplog):
|
||||
### GitHub Actions
|
||||
|
||||
Tests run automatically on:
|
||||
|
||||
- Pull requests
|
||||
- Pushes to main
|
||||
- Nightly schedules
|
||||
@@ -542,6 +544,7 @@ pre-commit run --all-files
|
||||
### Common Issues
|
||||
|
||||
**Async Test Errors**
|
||||
|
||||
```python
|
||||
# Wrong
|
||||
def test_async(): # Missing async
|
||||
@@ -553,6 +556,7 @@ async def test_async():
|
||||
```
|
||||
|
||||
**Database State**
|
||||
|
||||
```python
|
||||
# Ensure clean state
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -564,6 +568,7 @@ async def cleanup(test_db):
|
||||
```
|
||||
|
||||
**Mock Not Working**
|
||||
|
||||
```python
|
||||
# Check import path
|
||||
mocker.patch("routstr.wallet.Wallet") # Full path
|
||||
@@ -572,7 +577,5 @@ mocker.patch("routstr.wallet.Wallet") # Full path
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Review [Database Guide](database.md) for schema testing
|
||||
- Check [Guidelines](guidelines.md) for code standards
|
||||
- See [Architecture](architecture.md) for system design
|
||||
- Read [Setup Guide](setup.md) for environment setup
|
||||
- Read [Setup Guide](setup.md) for environment setup
|
||||
|
||||
@@ -126,6 +126,7 @@ UPSTREAM_PROVIDER_FEE=1.05
|
||||
### Dockerfile Overview
|
||||
|
||||
The provided Dockerfile:
|
||||
|
||||
- Uses Alpine Linux for small size
|
||||
- Installs required dependencies for secp256k1
|
||||
- Runs as non-root user
|
||||
@@ -218,6 +219,7 @@ api.yournode.com {
|
||||
### Log Management
|
||||
|
||||
View logs:
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker logs -f routstr
|
||||
@@ -232,6 +234,7 @@ tail -f ./logs/routstr.log
|
||||
### Metrics
|
||||
|
||||
Monitor key metrics:
|
||||
|
||||
- Request count and latency
|
||||
- Token validation success rate
|
||||
- Upstream API errors
|
||||
@@ -332,4 +335,3 @@ docker exec routstr nslookup api.openai.com
|
||||
|
||||
- [Configuration Guide](configuration.md) - All environment variables
|
||||
- [Admin Dashboard](../user-guide/admin-dashboard.md) - Manage your node
|
||||
- [Monitoring](../advanced/monitoring.md) - Set up observability
|
||||
@@ -206,7 +206,7 @@ View security events:
|
||||
|
||||
```
|
||||
2024-01-15 12:34:56 | Login Success | IP: 192.168.1.1
|
||||
2024-01-15 12:35:12 | Withdrawal | Key: rstr_abcd | Amount: 5000
|
||||
2024-01-15 12:35:12 | Withdrawal | Key: sk-****abcd | Amount: 5000
|
||||
2024-01-15 12:40:00 | Session Timeout | IP: 192.168.1.1
|
||||
```
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ POST /v1/wallet/create
|
||||
}
|
||||
```
|
||||
|
||||
This returns an API key (`rstr_...`) and your balance. The wallet persists between requests.
|
||||
This returns an API key (`sk-...`) and your balance. The wallet persists between requests.
|
||||
|
||||
#### Option B: Direct Token Usage
|
||||
|
||||
@@ -129,7 +129,7 @@ With either method:
|
||||
```python
|
||||
# Using persistent wallet API key
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_api_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://api.routstr.com/v1"
|
||||
)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ curl -X POST https://api.routstr.com/v1/wallet/create \
|
||||
|
||||
```json
|
||||
{
|
||||
"api_key": "rstr_1234567890abcdef",
|
||||
"api_key": "sk-1234567890abcdef",
|
||||
"balance": 10000000,
|
||||
"created_at": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
@@ -72,7 +72,7 @@ Check your key's balance:
|
||||
|
||||
```bash
|
||||
curl -X GET https://api.routstr.com/v1/wallet/balance \
|
||||
-H "Authorization: Bearer rstr_1234567890abcdef"
|
||||
-H "Authorization: Bearer sk-1234567890abcdef"
|
||||
```
|
||||
|
||||
Response:
|
||||
@@ -114,7 +114,7 @@ Costs are calculated based on:
|
||||
import openai
|
||||
|
||||
client = openai.OpenAI(
|
||||
api_key="rstr_1234567890abcdef",
|
||||
api_key="sk-1234567890abcdef",
|
||||
base_url="https://api.routstr.com/v1"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ This guide shows how to integrate Routstr with your applications using various p
|
||||
## API Compatibility
|
||||
|
||||
Routstr maintains full compatibility with the OpenAI API, meaning:
|
||||
|
||||
- Existing OpenAI client libraries work without modification
|
||||
- Only the base URL and API key need to change
|
||||
- All parameters and responses match OpenAI's format
|
||||
@@ -20,7 +21,7 @@ from openai import OpenAI
|
||||
|
||||
# Initialize client with Routstr endpoint
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_api_key_here",
|
||||
api_key="sk-...",
|
||||
base_url="https://api.routstr.com/v1"
|
||||
)
|
||||
|
||||
@@ -45,7 +46,7 @@ import OpenAI from 'openai';
|
||||
|
||||
// Initialize client
|
||||
const openai = new OpenAI({
|
||||
apiKey: 'rstr_your_api_key_here',
|
||||
apiKey: 'sk-...',
|
||||
baseURL: 'https://api.routstr.com/v1'
|
||||
});
|
||||
|
||||
@@ -72,7 +73,7 @@ Direct HTTP requests:
|
||||
```bash
|
||||
curl https://api.routstr.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer rstr_your_api_key_here" \
|
||||
-H "Authorization: Bearer sk-..." \
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [
|
||||
@@ -265,7 +266,7 @@ import httpx
|
||||
|
||||
# Configure timeout and retries
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://your-node.com/v1",
|
||||
timeout=httpx.Timeout(60.0, connect=5.0),
|
||||
max_retries=2
|
||||
@@ -290,7 +291,7 @@ proxies = {
|
||||
http_client = httpx.Client(proxies=proxies)
|
||||
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="http://your-onion-address.onion/v1",
|
||||
http_client=http_client
|
||||
)
|
||||
@@ -309,7 +310,7 @@ class CustomClient(httpx.Client):
|
||||
self.headers["X-Custom-Header"] = "value"
|
||||
|
||||
client = OpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://your-node.com/v1",
|
||||
http_client=CustomClient()
|
||||
)
|
||||
@@ -324,7 +325,7 @@ import asyncio
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
async_client = AsyncOpenAI(
|
||||
api_key="rstr_your_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://your-node.com/v1"
|
||||
)
|
||||
|
||||
@@ -492,29 +493,32 @@ def test_routstr_connection():
|
||||
### Common Issues
|
||||
|
||||
**SSL Certificate Errors**
|
||||
|
||||
```python
|
||||
# For development only - not for production!
|
||||
import ssl
|
||||
import httpx
|
||||
|
||||
client = OpenAI(
|
||||
api_key="rstr_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://localhost:8000/v1",
|
||||
http_client=httpx.Client(verify=False)
|
||||
)
|
||||
```
|
||||
|
||||
**Timeout Issues**
|
||||
|
||||
```python
|
||||
# Increase timeout for slow connections
|
||||
client = OpenAI(
|
||||
api_key="rstr_key",
|
||||
api_key="sk-...",
|
||||
base_url="https://your-node.com/v1",
|
||||
timeout=httpx.Timeout(120.0) # 2 minutes
|
||||
)
|
||||
```
|
||||
|
||||
**Debugging Requests**
|
||||
|
||||
```python
|
||||
import logging
|
||||
import httpx
|
||||
@@ -529,4 +533,4 @@ httpx_logger.setLevel(logging.DEBUG)
|
||||
|
||||
- [Admin Dashboard](admin-dashboard.md) - Manage your account
|
||||
- [Models & Pricing](models-pricing.md) - Understanding costs
|
||||
- [API Reference](../api/overview.md) - Technical details
|
||||
- [API Reference](../api/overview.md) - Technical details
|
||||
|
||||
@@ -93,8 +93,6 @@ nav:
|
||||
- Architecture: contributing/architecture.md
|
||||
- Code Structure: contributing/code-structure.md
|
||||
- Testing: contributing/testing.md
|
||||
- Database: contributing/database.md
|
||||
- Guidelines: contributing/guidelines.md
|
||||
- API Reference:
|
||||
- Overview: api/overview.md
|
||||
- Authentication: api/authentication.md
|
||||
|
||||
Reference in New Issue
Block a user