Skip to content

bendoyon/gliner-rs-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GLiNER RS API

A modern Rust API built with Rocket framework for PII (Personally Identifiable Information) detection using GLiNER models. Features comprehensive testing, Docker deployment, and clean architecture.

πŸš€ Features

  • PII Detection: Advanced PII detection using GLiNER models with high accuracy
  • Rocket Framework: Fast, type-safe web framework for Rust
  • Docker Ready: Multi-stage Docker build with ONNX Runtime support
  • JSON API: RESTful endpoints with structured JSON responses
  • Comprehensive Testing: Unit tests and integration tests
  • Health Monitoring: Built-in health check endpoint
  • Type Safety: Strong typing with Serde serialization
  • Production Ready: Optimized for deployment with proper security

πŸ“ Project Structure

gliner-rs-api/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ lib.rs          # Library with API logic and unit tests
β”‚   └── main.rs         # Binary entry point
β”œβ”€β”€ tests/
β”‚   └── integration_tests.rs  # Integration tests
β”œβ”€β”€ Dockerfile          # Multi-stage Docker build
β”œβ”€β”€ docker-compose.yml  # Docker Compose configuration
β”œβ”€β”€ nginx.conf          # Nginx reverse proxy config
β”œβ”€β”€ .dockerignore       # Docker ignore file
β”œβ”€β”€ docker-build.sh     # Docker build script
β”œβ”€β”€ docker-run.sh       # Docker run script
β”œβ”€β”€ Cargo.toml          # Dependencies
β”œβ”€β”€ run_tests.sh        # Test runner script
└── README.md           # This file

πŸ› οΈ Installation & Setup

Prerequisites

  • Rust 1.82+ (2021 edition)
  • Cargo package manager
  • Docker (for containerized deployment)
  • For PII detection: GLiNER model files (see PII Setup section)

Quick Start

  1. Clone and navigate to the project:

    cd gliner-rs-api
  2. Install dependencies:

    cargo build
  3. Run the API server:

    cargo run

    The server will start on http://127.0.0.1:8000

πŸ€– PII Detection Setup

The API includes PII (Personally Identifiable Information) detection using the gline-rs library with GLiNER models.

Model Setup

The API uses the gliner-multitask-large-v0.5 model in Token Mode for optimal performance.

  1. Run the setup script:

    ./setup-models.sh
  2. Model files are automatically included in the Docker image, but for local development:

    # Create model directory
    mkdir -p models/onnx-community/gliner-multitask-large-v0.5
    
    # Download tokenizer
    wget -O models/onnx-community/gliner-multitask-large-v0.5/tokenizer.json \
      'https://huggingface.co/onnx-community/gliner-multitask-large-v0.5/raw/main/tokenizer.json'
    
    # Download ONNX model
    wget -O models/onnx-community/gliner-multitask-large-v0.5/model.onnx \
      'https://huggingface.co/onnx-community/gliner-multitask-large-v0.5/resolve/main/model.onnx'
  3. The model loads automatically when the API starts - no manual loading required!

Supported PII Types

The API can detect the following types of PII with high accuracy:

  • person - Names and personal identifiers (99%+ confidence)
  • email - Email addresses (99%+ confidence)
  • phone - Phone numbers (99%+ confidence)
  • address - Physical addresses (98%+ confidence)

Note: The current model focuses on the most common PII types. Additional types can be detected by using different GLiNER models.

🌐 API Endpoints

Base URL

http://127.0.0.1:8000

Available Endpoints

Method Endpoint Description Response
GET / Welcome message {"success": true, "data": "Welcome to Gliner RS API", "message": null}
GET /health Health check {"status": "ok", "message": "API is running"}
GET /api/version API version {"success": true, "data": "0.1.0", "message": null}
POST /api/pii/detect PII detection in text {"success": true, "data": {"entities": [...], "text": "...", "total_entities": 3}}

Example Requests

# Health check
curl http://127.0.0.1:8000/health

# Welcome message
curl http://127.0.0.1:8000/

# API version
curl http://127.0.0.1:8000/api/version

# PII Detection
curl -X POST http://127.0.0.1:8000/api/pii/detect \
  -H "Content-Type: application/json" \
  -d '{"text": "My name is John Doe and my email is john@example.com. Call me at (555) 123-4567."}'

Example Responses

Health Check:

{
  "status": "ok",
  "message": "API is running"
}

API Response:

{
  "success": true,
  "data": "Welcome to Gliner RS API",
  "message": null
}

PII Detection Response:

{
  "success": true,
  "data": {
    "entities": [
      {
        "text": "John Doe",
        "label": "person",
        "probability": 0.9953098893165588,
        "sequence": 0
      },
      {
        "text": "john@example.com",
        "label": "email",
        "probability": 0.9994480013847351,
        "sequence": 0
      },
      {
        "text": "(555) 123-4567",
        "label": "phone",
        "probability": 0.9971915483474731,
        "sequence": 0
      }
    ],
    "text": "My name is John Doe and my email is john@example.com. Call me at (555) 123-4567.",
    "total_entities": 3,
    "message": "PII detection completed successfully"
  },
  "message": null
}

πŸ§ͺ Testing

The project includes comprehensive testing with both unit tests and integration tests.

Test Types

Unit Tests (in src/lib.rs)

  • Response structure validation
  • JSON serialization/deserialization
  • Individual endpoint testing
  • Error handling validation

Integration Tests (in tests/integration_tests.rs)

  • End-to-end API testing
  • Content type validation
  • Error scenario testing
  • Performance testing

Running Tests

Run All Tests

cargo test

Run Specific Test Types

# Unit tests only
cargo test --lib

# Integration tests only  
cargo test --test integration_tests

# Run with verbose output
cargo test -- --nocapture

Run Specific Tests

# Run a specific test
cargo test test_health_check_response

# Run tests matching a pattern
cargo test health

Use the Test Runner Script

./run_tests.sh

Test Coverage

Unit Tests (6 tests):

  • βœ… test_health_check_response - Health endpoint validation
  • βœ… test_index_response - Root endpoint validation
  • βœ… test_version_response - Version endpoint validation
  • βœ… test_404_for_unknown_route - Error handling
  • βœ… test_health_response_serialization - JSON serialization
  • βœ… test_api_response_serialization - Response structure validation

Integration Tests (6 tests):

  • βœ… test_api_endpoints_integration - Full endpoint testing
  • βœ… test_content_type_headers - Header validation
  • βœ… test_error_handling - Error scenario testing
  • βœ… test_json_structure_consistency - Response format validation
  • βœ… test_health_endpoint_structure - Health endpoint structure
  • βœ… test_multiple_requests - Basic performance testing

πŸ”§ Development

Adding New Endpoints

  1. Define the endpoint function in src/lib.rs:

    #[get("/api/new-endpoint")]
    pub fn new_endpoint() -> Json<ApiResponse<String>> {
        Json(ApiResponse {
            success: true,
            data: Some("New endpoint data".to_string()),
            message: None,
        })
    }
  2. Add the route to the rocket function:

    #[launch]
    pub fn rocket() -> Rocket<Build> {
        rocket::build()
            .mount("/", routes![index, health_check, version, new_endpoint])
    }
  3. Add tests for the new endpoint:

    #[test]
    fn test_new_endpoint() {
        let client = create_test_client();
        let response = client.get("/api/new-endpoint").dispatch();
        
        assert_eq!(response.status(), Status::Ok);
        let api_response: ApiResponse<String> = response.into_json().expect("valid JSON");
        assert!(api_response.success);
    }

Project Dependencies

[dependencies]
rocket = { version = "0.5", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1.0", features = ["full"] }
gline-rs = { version = "1.0.0", features = ["load-dynamic"] }
regex = "1.11.1"
orp = "0.9.2"

πŸš€ Deployment

Development

cargo run

Production Build

cargo build --release
./target/release/gliner-rs-api

🐳 Docker Deployment

The project includes comprehensive Docker support with ONNX Runtime integration for easy deployment and scaling.

Quick Start with Docker

Option 1: Manual Docker Commands (Recommended)

# Build the image
docker build -t gliner-rs-api .

# Run the container
docker run -d --name gliner-rs-api-container -p 8000:8000 gliner-rs-api

# Check logs (model loading takes ~2-3 minutes)
docker logs gliner-rs-api-container

# Test the API
curl http://localhost:8000/health

Option 2: Using Docker Scripts

# Build and run with one command
./docker-run.sh

Option 3: Docker Compose (Full Stack)

# Start with nginx reverse proxy
docker-compose up -d

# View logs
docker-compose logs -f

Docker Features

  • Multi-stage Build: Optimized production image with Rust 1.82
  • ONNX Runtime: Integrated ONNX Runtime v1.20.0 for ML model inference
  • GLiNER Model: Pre-loaded GLiNER multitask large v0.5 model in Token Mode
  • Security: Non-root user execution with proper permissions
  • Health Checks: Built-in health monitoring with curl-based checks
  • Network Binding: Configured to bind to 0.0.0.0 for external access
  • Small Image Size: Minimal runtime dependencies with Debian slim base
  • Reverse Proxy: Optional nginx configuration for production

Docker Commands Reference

# Build image
./docker-build.sh
# or
docker build -t gliner-rs-api:latest .

# Run container
./docker-run.sh
# or
docker run -d --name gliner-rs-api -p 8000:8000 gliner-rs-api:latest

# View logs
docker logs gliner-rs-api

# Stop container
docker stop gliner-rs-api

# Remove container
docker rm gliner-rs-api

# Docker Compose
docker-compose up -d          # Start services
docker-compose down           # Stop services
docker-compose logs -f        # View logs
docker-compose ps             # Check status

Docker Environment Variables

# Custom port
docker run -p 8080:8000 -e ROCKET_PORT=8000 gliner-rs-api

# Custom GLiNER model
docker run -p 8000:8000 -e GLINER_MODEL=onnx-community/gliner-multitask-large-v0.5 gliner-rs-api

# The API automatically binds to 0.0.0.0:8000 for external access

Production Docker Setup

For production deployment, use the docker-compose setup with nginx:

# docker-compose.prod.yml
version: '3.8'
services:
  gliner-api:
    build: .
    restart: always
    environment:
      - ROCKET_ADDRESS=0.0.0.0
      - ROCKET_PORT=8000
    networks:
      - api-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - gliner-api
    restart: always
    networks:
      - api-network

πŸ“Š API Response Structure

Standard API Response

{
  "success": boolean,
  "data": any | null,
  "message": string | null
}

Health Response

{
  "status": string,
  "message": string
}

πŸ›‘οΈ Security Features

  • Shield Protection: Built-in security headers
  • Content Type Validation: Proper JSON content types
  • Input Validation: Type-safe request/response handling

πŸ“ Logging

The API includes comprehensive logging:

  • Request/response logging
  • Error tracking
  • Performance monitoring

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License.

πŸ†˜ Troubleshooting

Common Issues

Port already in use:

# Kill existing processes
pkill -f gliner-rs-api
# Or use a different port
ROCKET_PORT=8001 cargo run

Model loading takes time:

# The GLiNER model takes 2-3 minutes to load on first startup
# Check logs to monitor progress
docker logs gliner-rs-api-container
# Look for "Model loaded successfully!" and "Rocket has launched"

Docker build issues:

# Clean Docker cache and rebuild
docker system prune -a
docker build --no-cache -t gliner-rs-api .

Tests failing:

# Clean and rebuild
cargo clean
cargo test

Dependencies issues:

# Update dependencies
cargo update
cargo build

PII detection not working:

# Ensure the model is loaded (check logs)
docker logs gliner-rs-api-container

# Test with a simple example
curl -X POST http://localhost:8000/api/pii/detect \
  -H "Content-Type: application/json" \
  -d '{"text": "My name is John Doe"}'

βœ… Verified Working Features

This API has been successfully tested and verified to work with the following:

  • βœ… Docker Build: Multi-stage build with Rust 1.82 and ONNX Runtime v1.20.0
  • βœ… Model Loading: GLiNER multitask large v0.5 model loads successfully in Token Mode
  • βœ… PII Detection: High-accuracy detection of person names, emails, phones, and addresses
  • βœ… API Endpoints: All endpoints respond correctly with proper JSON formatting
  • βœ… Health Checks: Built-in health monitoring works as expected
  • βœ… Network Access: Properly configured to accept external connections
  • βœ… Error Handling: Graceful error handling for model loading and inference failures

Test Results

PII Detection Accuracy:

  • Person names: 99.5%+ confidence
  • Email addresses: 99.9%+ confidence
  • Phone numbers: 99.7%+ confidence
  • Physical addresses: 98.6%+ confidence

Performance:

  • Model loading: ~2-3 minutes on first startup
  • API response time: <1 second for PII detection
  • Memory usage: Optimized with multi-stage Docker build

Happy coding! πŸ¦€

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors