A high-performance Rust SDK for building Poe bots with FastAPI-compatible interfaces. This SDK provides a complete implementation of the Poe protocol with streaming support, error handling, and comprehensive configuration options.
- Complete Poe Protocol Support: Full implementation of Poe's bot protocol including queries, settings, feedback, and error reporting
- Streaming Responses: Built-in support for real-time streaming responses
- Type Safety: Comprehensive type definitions with serde serialization/deserialization
- Error Handling: Robust error handling with detailed error types and validation
- Flexible Configuration: Support for both environment variables and TOML configuration files
- CORS Support: Built-in CORS handling for web applications
- Graceful Shutdown: Proper cleanup and shutdown handling
- Comprehensive Logging: Structured logging with configurable levels
- Rate Limiting: Built-in rate limiting and request validation
- Docker Support: Ready-to-use Docker configuration
Add this to your Cargo.toml:
[dependencies]
fastapi-poe-rust = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }use fastapi_poe_rust::*;
use async_trait::async_trait;
#[derive(Clone)]
struct EchoBot;
#[async_trait]
impl BotHandler for EchoBot {
async fn handle_query(&self, request: QueryRequest) -> Result<PoeResponse, PoeError> {
let message = request.query.last()
.map(|msg| &msg.content)
.unwrap_or("Hello!");
Ok(PoeResponse::text(format!("Echo: {}", message)))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the SDK
fastapi_poe_rust::init();
// Create bot instance
let bot = EchoBot;
// Create and start server
let server = PoeServer::new(bot)
.with_access_key("your-poe-access-key")
.with_port(8000);
server.run().await?;
Ok(())
}#[async_trait]
impl BotHandler for StreamingBot {
async fn handle_query(&self, request: QueryRequest) -> Result<PoeResponse, PoeError> {
let chunks = vec![
"Hello ".to_string(),
"from ".to_string(),
"streaming ".to_string(),
"bot!".to_string(),
];
Ok(PoeResponse::streaming(chunks))
}
}let config = BotConfig {
access_key: "your-access-key".to_string(),
bot_name: "MyBot".to_string(),
server_host: "0.0.0.0".to_string(),
server_port: 8080,
enable_cors: true,
log_level: "info".to_string(),
..Default::default()
};
let server = PoeServer::with_config(bot, config);The main trait that defines bot behavior:
#[async_trait]
pub trait BotHandler: Send + Sync + Clone {
async fn handle_query(&self, request: QueryRequest) -> Result<PoeResponse, PoeError>;
async fn handle_settings(&self, request: SettingsRequest) -> Result<SettingsResponse, PoeError> { /* default */ }
async fn handle_report_feedback(&self, request: ReportFeedbackRequest) -> Result<(), PoeError> { /* default */ }
async fn handle_report_error(&self, request: ReportErrorRequest) -> Result<(), PoeError> { /* default */ }
}pub struct QueryRequest {
pub query: Vec<ConversationMessage>,
pub user_id: String,
pub conversation_id: String,
pub message_id: String,
pub metadata: Option<serde_json::Value>,
}pub enum PoeResponse {
Text(String),
Streaming(Vec<String>),
Error { error_type: String, message: String },
// ... other variants
}// Text response
let response = poe_response!("Hello, world!");
// Streaming response
let response = poe_response!(streaming: ["chunk1", "chunk2", "chunk3"]);
// Error response
let response = poe_response!(error: "invalid_request", "Invalid input provided");bot_handler! {
MyBot {
query: |request| {
Ok(poe_response!("Hello from macro bot!"))
},
settings: |request| {
Ok(SettingsResponse::default())
}
}
}Create a .env file:
# Poe Configuration
POE_ACCESS_KEY=your-poe-access-key-here
POE_BOT_NAME=YourBotName
# Server Configuration
SERVER_HOST=0.0.0.0
SERVER_PORT=8000
SERVER_WORKERS=4
# Request Configuration
REQUEST_TIMEOUT_SECONDS=30
REQUEST_MAX_SIZE_BYTES=1048576
# CORS Configuration
ENABLE_CORS=true
CORS_ALLOW_ORIGINS=*
CORS_ALLOW_METHODS=GET,POST,PUT,DELETE,OPTIONS
CORS_ALLOW_HEADERS=*
# Logging Configuration
LOG_LEVEL=info
LOG_FORMAT=json
ENABLE_REQUEST_LOGGING=true
# Feature Flags
ENABLE_STREAMING=true
ENABLE_SETTINGS=true
ENABLE_FEEDBACK=true
ENABLE_ERROR_REPORTING=true
# Rate Limiting
RATE_LIMIT_REQUESTS_PER_MINUTE=60
RATE_LIMIT_BURST_SIZE=10
# Development
DEVELOPMENT_MODE=false
HOT_RELOAD=falseCreate a bot.toml file:
[bot]
name = "YourBotName"
access_key = "your-poe-access-key-here"
description = "A helpful assistant bot"
[server]
host = "0.0.0.0"
port = 8000
workers = 4
[cors]
enable = true
allow_origins = ["*"]
allow_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allow_headers = ["*"]
[logging]
level = "info"
format = "json"
enable_request_logging = true
[features]
enable_streaming = true
enable_settings = true
enable_feedback = true
enable_error_reporting = true
[limits]
request_timeout_seconds = 30
max_request_size_bytes = 1048576
rate_limit_requests_per_minute = 60
rate_limit_burst_size = 10
[development]
mode = false
hot_reload = falseFROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/your-bot /usr/local/bin/your-bot
EXPOSE 8000
CMD ["your-bot"]Build and run:
docker build -t my-poe-bot .
docker run -p 8000:8000 --env-file .env my-poe-bot# Build the project
cargo build --release
# Run the bot
./target/release/your-botSee the examples/ directory for more comprehensive examples:
- Echo Bot: Simple echo functionality
- Streaming Bot: Real-time streaming responses
- Smart Bot: Advanced conversation handling
- Configuration Bot: Custom configuration examples
This SDK implements the complete Poe bot protocol:
- ✅ Query handling with conversation context
- ✅ Streaming response support
- ✅ Settings management
- ✅ Feedback reporting
- ✅ Error reporting
- ✅ Metadata handling
- ✅ Authentication and authorization
- ✅ Rate limiting and validation