Thanks to visit codestin.com
Credit goes to lib.rs

1 unstable release

new 0.1.0 Jan 16, 2026

#5 in #species

MIT/Apache

1MB
23K SLoC

sevensense-api

Crate Docs License

HTTP API layer for the 7sense bioacoustic intelligence platform.

sevensense-api provides a comprehensive HTTP interface to all 7sense functionality. It offers GraphQL for flexible queries, REST endpoints with OpenAPI documentation, WebSocket streaming for real-time analysis, and Server-Sent Events for monitoring. Built on Axum for high performance and reliability.

Features

  • GraphQL API: Flexible queries with async-graphql
  • REST Endpoints: OpenAPI/Swagger documented
  • WebSocket Streaming: Real-time audio analysis
  • Authentication: JWT-based auth with refresh tokens
  • Rate Limiting: Configurable request throttling
  • Health Checks: Kubernetes-ready probes

Use Cases

Use Case Description Endpoint
Species Identification Identify birds from audio POST /api/identify
Similarity Search Find similar recordings POST /api/search
Batch Processing Process multiple files POST /api/batch
Real-time Analysis Stream audio for analysis WS /ws/stream
Health Monitoring Check system status GET /health

Installation

Add to your Cargo.toml:

[dependencies]
sevensense-api = "0.1"

Quick Start

Starting the Server

# Start with default configuration
cargo run -p sevensense-api --release

# With custom port
SEVENSENSE_PORT=8080 cargo run -p sevensense-api --release

# With configuration file
cargo run -p sevensense-api --release -- --config config.toml

API Endpoints

Once running, access:

  • GraphQL Playground: http://localhost:3000/graphql
  • Swagger UI: http://localhost:3000/docs/swagger-ui
  • Health Check: http://localhost:3000/health

Tutorial: GraphQL Queries

Basic Species Query

query {
  identifySpecies(audioUrl: "https://example.com/bird.wav") {
    predictions {
      speciesId
      commonName
      scientificName
      confidence
    }
    processingTime
  }
}
query SearchSimilar($embedding: [Float!]!, $k: Int!) {
  searchSimilar(embedding: $embedding, k: $k, minSimilarity: 0.8) {
    id
    species {
      scientificName
      commonName
    }
    similarity
    recordingUrl
    timestamp
  }
}

With Filters

query FilteredSearch {
  searchSimilar(
    embedding: [0.1, 0.2, ...]
    k: 20
    filter: {
      species: ["Turdus merula", "Turdus philomelos"]
      location: { lat: 51.5, lon: -0.1, radiusKm: 50 }
      timeRange: { start: "2024-01-01", end: "2024-06-30" }
    }
  ) {
    id
    species { commonName }
    similarity
    location { lat, lon, siteName }
  }
}

Mutations

mutation AddRecording($input: RecordingInput!) {
  addRecording(input: $input) {
    id
    status
    embedding
  }
}

mutation DeleteRecording($id: ID!) {
  deleteRecording(id: $id) {
    success
    message
  }
}

Subscriptions

subscription OnNewDetection {
  newDetection(location: { lat: 51.5, lon: -0.1, radiusKm: 10 }) {
    id
    species { commonName }
    confidence
    timestamp
    audioUrl
  }
}
Tutorial: REST API

Species Identification

# From file upload
curl -X POST http://localhost:3000/api/identify \
  -F "audio=@bird_call.wav"

# From URL
curl -X POST http://localhost:3000/api/identify \
  -H "Content-Type: application/json" \
  -d '{"audioUrl": "https://example.com/bird.wav"}'

Response:

{
  "predictions": [
    {
      "speciesId": "turdus-merula",
      "scientificName": "Turdus merula",
      "commonName": "Eurasian Blackbird",
      "confidence": 0.94
    }
  ],
  "processingTimeMs": 127,
  "embedding": [0.123, -0.456, ...]
}

Similarity Search

curl -X POST http://localhost:3000/api/search \
  -H "Content-Type: application/json" \
  -d '{
    "embedding": [0.123, -0.456, ...],
    "k": 10,
    "minSimilarity": 0.8
  }'

Batch Processing

curl -X POST http://localhost:3000/api/batch \
  -H "Content-Type: application/json" \
  -d '{
    "audioUrls": [
      "https://example.com/bird1.wav",
      "https://example.com/bird2.wav",
      "https://example.com/bird3.wav"
    ],
    "options": {
      "includeEmbeddings": true,
      "topK": 3
    }
  }'

Health Checks

# Liveness probe
curl http://localhost:3000/health/live

# Readiness probe
curl http://localhost:3000/health/ready

# Detailed status
curl http://localhost:3000/health/status
Tutorial: WebSocket Streaming

Connecting to Stream

const ws = new WebSocket('ws://localhost:3000/ws/stream');

ws.onopen = () => {
  console.log('Connected to stream');

  // Start streaming audio
  ws.send(JSON.stringify({
    type: 'start',
    config: {
      sampleRate: 32000,
      channels: 1,
      format: 'float32'
    }
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  if (message.type === 'detection') {
    console.log('Detection:', message.data);
  }
};

// Stream audio chunks
function sendAudioChunk(audioData) {
  ws.send(audioData);  // ArrayBuffer
}

Rust Client

use sevensense_api::client::{StreamClient, StreamConfig};
use tokio_tungstenite::connect_async;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = StreamConfig {
        sample_rate: 32000,
        channels: 1,
        chunk_duration_ms: 500,
    };

    let client = StreamClient::connect("ws://localhost:3000/ws/stream", config).await?;

    // Send audio chunks
    for chunk in audio_chunks {
        client.send_audio(&chunk).await?;
    }

    // Receive detections
    while let Some(detection) = client.receive().await? {
        println!("Detected: {} ({:.1}%)",
            detection.species, detection.confidence * 100.0);
    }

    Ok(())
}

Stream Protocol

Message Type Direction Description
start Client→Server Start streaming with config
audio Client→Server Audio chunk (binary)
stop Client→Server Stop streaming
detection Server→Client Species detection event
error Server→Client Error message
status Server→Client Processing status
Tutorial: Authentication

JWT Authentication

# Login to get tokens
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "user", "password": "pass"}'

# Response
{
  "accessToken": "eyJ...",
  "refreshToken": "eyJ...",
  "expiresIn": 3600
}

# Use access token
curl http://localhost:3000/api/search \
  -H "Authorization: Bearer eyJ..."

# Refresh token
curl -X POST http://localhost:3000/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refreshToken": "eyJ..."}'

API Keys

# Create API key
curl -X POST http://localhost:3000/auth/api-keys \
  -H "Authorization: Bearer eyJ..." \
  -d '{"name": "My App", "scopes": ["read", "write"]}'

# Use API key
curl http://localhost:3000/api/search \
  -H "X-API-Key: sk_live_..."

Scopes

Scope Description
read Read-only access to search and identify
write Add/modify recordings
admin Administrative operations
stream Real-time streaming access
Tutorial: Server Configuration

Configuration File

# config.toml
[server]
host = "0.0.0.0"
port = 3000
workers = 4

[auth]
jwt_secret = "your-secret-key"
token_expiry_hours = 24
refresh_expiry_days = 30

[rate_limiting]
enabled = true
requests_per_minute = 100
burst_size = 20

[database]
url = "postgres://user:pass@localhost/sevensense"
max_connections = 20

[index]
path = "./data/hnsw.index"
preload = true

[logging]
level = "info"
format = "json"

Environment Variables

# Server
export SEVENSENSE_HOST=0.0.0.0
export SEVENSENSE_PORT=3000

# Authentication
export SEVENSENSE_JWT_SECRET=your-secret
export SEVENSENSE_JWT_EXPIRY=3600

# Database
export DATABASE_URL=postgres://...

# Logging
export RUST_LOG=sevensense_api=info

Programmatic Configuration

use sevensense_api::{Server, ServerConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::builder()
        .host("0.0.0.0")
        .port(3000)
        .workers(4)
        .enable_graphql(true)
        .enable_swagger(true)
        .rate_limit(100, 20)
        .build()?;

    Server::new(config)
        .with_index(&index)
        .with_embedding_pipeline(&pipeline)
        .run()
        .await?;

    Ok(())
}

API Reference

GraphQL Schema

Type Description
Query.identifySpecies Identify species from audio
Query.searchSimilar Find similar recordings
Query.getRecording Get recording by ID
Mutation.addRecording Add new recording
Subscription.newDetection Real-time detection events

REST Endpoints

Method Path Description
POST /api/identify Identify species
POST /api/search Similarity search
POST /api/batch Batch processing
GET /api/recordings/:id Get recording
WS /ws/stream Real-time streaming

Health Endpoints

Path Description
/health/live Liveness probe
/health/ready Readiness probe
/health/status Detailed status

Performance

Metric Target Actual
Identify Latency <200ms ~150ms
Search Latency <50ms ~35ms
Concurrent Connections 1000
Requests/Second 500 ~600

License

MIT License - see LICENSE for details.


Part of the 7sense Bioacoustic Intelligence Platform by rUv

Dependencies

~58MB
~1M SLoC