Code Examples
Rust Examples
Production-ready Rust examples for building with BrainUs API
Complete Rust examples for integrating BrainUs API with popular frameworks.
The Rust SDK is coming soon! For now, use reqwest to call our REST API.
Basic Client with reqwest
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
use serde::{Deserialize, Serialize};
use std::env;
#[derive(Debug, Serialize)]
struct QueryRequest {
query: String,
store_id: String,
}
#[derive(Debug, Deserialize)]
struct QueryResponse {
answer: String,
citations: Vec<Citation>,
metadata: Metadata,
}
#[derive(Debug, Deserialize)]
struct Citation {
document: String,
page: i32,
excerpt: String,
relevance: f64,
}
#[derive(Debug, Deserialize)]
struct Metadata {
query_id: String,
tokens_used: i32,
response_time_ms: i32,
}
async fn query(question: &str, store_id: &str) -> Result<QueryResponse, Box<dyn std::error::Error>> {
let api_key = env::var("BRAINUS_API_KEY")?;
let client = reqwest::Client::new();
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
headers.insert("X-API-Key", HeaderValue::from_str(&api_key)?);
let request_body = QueryRequest {
query: question.to_string(),
store_id: store_id.to_string(),
};
let response = client
.post("https://api.brainus.lk/api/v1/query")
.headers(headers)
.json(&request_body)
.send()
.await?;
if !response.status().is_success() {
let error_text = response.text().await?;
return Err(format!("API error: {}", error_text).into());
}
let result: QueryResponse = response.json().await?;
Ok(result)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let result = query("What is photosynthesis?", "default").await?;
println!("Answer: {}", result.answer);
println!("Citations: {}", result.citations.len());
Ok(())
}Client with Error Handling
use thiserror::Error;
#[derive(Error, Debug)]
pub enum BrainUsError {
#[error("Authentication failed: {0}")]
AuthError(String),
#[error("Rate limit exceeded, retry after {retry_after}s")]
RateLimitError { retry_after: u64 },
#[error("Validation error: {0}")]
ValidationError(String),
#[error("Server error: {0}")]
ServerError(String),
#[error("Network error: {0}")]
NetworkError(#[from] reqwest::Error),
}
pub struct BrainUsClient {
api_key: String,
base_url: String,
client: reqwest::Client,
}
impl BrainUsClient {
pub fn new(api_key: String) -> Self {
Self {
api_key,
base_url: "https://api.brainus.lk".to_string(),
client: reqwest::Client::new(),
}
}
pub async fn query(&self, question: &str, store_id: &str) -> Result<QueryResponse, BrainUsError> {
let url = format!("{}/api/v1/query", self.base_url);
let request_body = QueryRequest {
query: question.to_string(),
store_id: store_id.to_string(),
};
let response = self.client
.post(&url)
.header("Content-Type", "application/json")
.header("X-API-Key", &self.api_key)
.json(&request_body)
.send()
.await?;
match response.status().as_u16() {
200 => Ok(response.json().await?),
401 => Err(BrainUsError::AuthError("Invalid API key".to_string())),
429 => {
let retry_after = response
.headers()
.get("Retry-After")
.and_then(|h| h.to_str().ok())
.and_then(|s| s.parse().ok())
.unwrap_or(60);
Err(BrainUsError::RateLimitError { retry_after })
}
400 => {
let error_text = response.text().await?;
Err(BrainUsError::ValidationError(error_text))
}
500..=599 => {
let error_text = response.text().await?;
Err(BrainUsError::ServerError(error_text))
}
_ => {
let error_text = response.text().await?;
Err(BrainUsError::ServerError(format!("Unexpected error: {}", error_text)))
}
}
}
}Axum Web Framework
use axum::{
extract::Json,
http::StatusCode,
response::IntoResponse,
routing::post,
Router,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
use std::collections::HashMap;
#[derive(Clone)]
struct AppState {
client: Arc<BrainUsClient>,
cache: Arc<RwLock<HashMap<String, CachedResponse>>>,
}
#[derive(Clone)]
struct CachedResponse {
data: QueryResponse,
timestamp: std::time::Instant,
}
#[derive(Deserialize)]
struct QueryPayload {
query: String,
store_id: Option<String>,
}
#[derive(Serialize)]
struct ApiResponse {
data: QueryResponse,
cached: bool,
}
async fn query_handler(
Json(payload): Json<QueryPayload>,
state: axum::extract::State<AppState>,
) -> Result<Json<ApiResponse>, (StatusCode, String)> {
let store_id = payload.store_id.unwrap_or_else(|| "default".to_string());
let cache_key = format!("{}-{}", payload.query, store_id);
// Check cache
{
let cache = state.cache.read().await;
if let Some(cached) = cache.get(&cache_key) {
if cached.timestamp.elapsed().as_secs() < 3600 {
return Ok(Json(ApiResponse {
data: cached.data.clone(),
cached: true,
}));
}
}
}
// Query API
let result = state
.client
.query(&payload.query, &store_id)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
// Update cache
{
let mut cache = state.cache.write().await;
cache.insert(
cache_key,
CachedResponse {
data: result.clone(),
timestamp: std::time::Instant::now(),
},
);
}
Ok(Json(ApiResponse {
data: result,
cached: false,
}))
}
#[tokio::main]
async fn main() {
let api_key = std::env::var("BRAINUS_API_KEY").expect("BRAINUS_API_KEY must be set");
let state = AppState {
client: Arc::new(BrainUsClient::new(api_key)),
cache: Arc::new(RwLock::new(HashMap::new())),
};
let app = Router::new()
.route("/api/query", post(query_handler))
.with_state(state);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
println!("Server running on http://127.0.0.1:3000");
axum::serve(listener, app).await.unwrap();
}Concurrent Queries with Tokio
use tokio::task::JoinSet;
async fn query_multiple(
client: &BrainUsClient,
queries: Vec<&str>,
store_id: &str,
) -> Vec<Result<QueryResponse, BrainUsError>> {
let mut set = JoinSet::new();
for query in queries {
let client = client.clone();
let query = query.to_string();
let store_id = store_id.to_string();
set.spawn(async move {
client.query(&query, &store_id).await
});
}
let mut results = Vec::new();
while let Some(result) = set.join_next().await {
results.push(result.unwrap());
}
results
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("BRAINUS_API_KEY")?;
let client = BrainUsClient::new(api_key);
let queries = vec![
"What is photosynthesis?",
"Explain the water cycle",
"What causes earthquakes?",
];
let results = query_multiple(&client, queries, "default").await;
for (i, result) in results.iter().enumerate() {
match result {
Ok(response) => println!("Query {}: {}", i + 1, &response.answer[..100]),
Err(e) => println!("Query {}: Error - {}", i + 1, e),
}
}
Ok(())
}All examples are available in our GitHub repository.
Next Steps
- Python Examples - Django, Flask, FastAPI
- JavaScript Examples - Node.js, React, Next.js
- Go Examples - Standard library and frameworks