Expand description
Β§OpenFIGI Rust Client
A high-performance asynchronous Rust client library for the OpenFIGI API, providing type-safe access to financial instrument identification and mapping services.
OpenFIGI is Bloombergβs open symbology initiative that provides standardized identification for financial instruments across asset classes and markets worldwide.
Β§π Table of Contents
- Features
- Getting Started
- Configuration
- API Usage Examples
- Error Handling
- Documentation
- Contributing
- License
- Acknowledgments
- Support
Β§β¨ Features
This library is designed with a focus on ergonomics, correctness, and production readiness.
- βοΈ Ergonomic: Provide a simple, intuitive, and fluent builder API.
- π Type-safe API: Strongly-typed request and response models prevent invalid data.
- β‘ Fully Asynchronous: Built on
tokio
andreqwest
for high-concurrency applications. - π§ Extensible via Middleware: Integrates with
reqwest-middleware
for custom logic like retries, logging, and tracing. - π Ergonomic Error Handling: Provides distinct error types for network issues, API errors, and invalid requests.
- π Environment integration: Automatically detects API keys from environment variables.
- π Built-in Rate Limit Handling: The client is aware of API rate limits and provides informative errors when they are exceeded.
- π Batch operations: First-class support for bulk operations to minimize network round-trips (up to 100 with API key, 5 without).
Β§π Getting Started
First, add the crate to your projectβs dependencies:
cargo add openfigi-rs
Β§Basic Usage
use openfigi_rs::client::OpenFIGIClient;
use openfigi_rs::model::enums::IdType;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create a client. It will use the OPENFIGI_API_KEY env var if available.
let client = OpenFIGIClient::new();
// Map an ISIN to its corresponding FIGI
let mapping_results = client
.mapping(IdType::ID_ISIN, "US4592001014") // IBM
.send()
.await?;
// The result is a vector of responses. Let's inspect the first one.
let data = mapping_results.data();
println!("FIGI: {}", data[0].figi);
println!("Name: {}", data[0].display_name());
// You can also pretty-print the full debug output
// println!("{:#?}", mapping_results);
Ok(())
}
Β§π§ Configuration
Β§API Key
The client can be configured with an API key to access higher rate limits.
Β§1. Environment Variable (Recommended)
The client automatically detects the OPENFIGI_API_KEY
environment variable.
export OPENFIGI_API_KEY="your-secret-key"
Β§2. Manual Configuration
You can also provide the key explicitly using the builder pattern.
let client = OpenFIGIClient::builder()
.api_key("your-secret-key")
.build()?;
Β§Custom HTTP Client & Middleware
For production environments, youβll want to configure timeouts and retry policies. This library is built on reqwest
and reqwest-middleware
, making customization easy.
use openfigi_rs::client::OpenFIGIClient;
use reqwest_middleware::ClientBuilder;
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Create a base reqwest client with timeouts
let http_client = reqwest::Client::builder()
.timeout(Duration::from_secs(15))
.connect_timeout(Duration::from_secs(5))
.build()?;
// 2. Configure a retry policy
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
// 3. Build the middleware client
let middleware_client = ClientBuilder::new(http_client)
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
.build();
// 4. Build the OpenFIGI client with the custom middleware client
let client = OpenFIGIClient::builder()
.middleware_client(middleware_client)
.api_key("your-secret-key")
.build()?;
Ok(())
}
Β§Rate Limits
Limitation | Without API Key | With API Key |
---|---|---|
Request Rate | 25 per minute | 250 per minute (25 per 6s) |
Jobs per Request | 10 jobs | 100 jobs |
Β§π API Usage Examples
The client supports all three OpenFIGI API v3 endpoints.
Endpoint | Purpose | Batch Support |
---|---|---|
/mapping | Map third-party identifiers to FIGIs. | β |
/search | Perform a text-based search for instruments. | β |
/filter | Search for instruments using specific criteria. | β |
Β§Mapping Endpoint
Convert third-party identifiers to FIGIs:
use openfigi_rs::client::OpenFIGIClient;
use openfigi_rs::model::enums::{IdType, Currency, ExchCode};
use openfigi_rs::model::request::MappingRequest;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = OpenFIGIClient::new();
// Single mapping request with optional parameters
let single_result = client
.mapping(IdType::ID_ISIN, "US4592001014")
.currency(Currency::USD)
.exch_code(ExchCode::US)
.send()
.await?;
// Bulk mapping request for multiple identifiers using a prebuilt vector of requests
let requests = vec![
MappingRequest::new(IdType::ID_ISIN, "US4592001014"),
MappingRequest::new(IdType::TICKER, "AAPL"),
];
let bulk_results = client
.bulk_mapping()
.add_requests(requests)
.send()
.await?;
// Bulk mapping request with inline closures
let result = client
.bulk_mapping()
.add_request_with(|j| {
// Simple mapping request
j.id_type(IdType::ID_ISIN)
.id_value("US4592001014")
})?
.add_request_with(|j| {
// Complex mapping request with filters
j.id_type(IdType::TICKER)
.id_value("IBM")
.currency(Currency::USD)
.exch_code(ExchCode::US)
})?
.send()
.await?;
Ok(())
}
Β§Search Endpoint
Text-based instrument search:
use openfigi_rs::client::OpenFIGIClient;
use openfigi_rs::model::enums::Currency;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = OpenFIGIClient::new();
let results = client
.search("apple")
.currency(Currency::USD)
.send()
.await?;
Ok(())
}
Β§Filter Endpoint
Filter instruments by criteria:
use openfigi_rs::client::OpenFIGIClient;
use openfigi_rs::model::enums::SecurityType;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = OpenFIGIClient::new();
let results = client
.filter()
.query("technology")
.security_type(SecurityType::CommonStock)
.send()
.await?;
Ok(())
}
Β§π¨ Error Handling
The library provides a comprehensive OpenFIGIError
enum. A common task is handling responses in a bulk request where some jobs may succeed and others may fail.
The API returns a 200 OK
with a body containing either a data
array or an error
message for each job.
use openfigi_rs::client::OpenFIGIClient;
use openfigi_rs::error::OpenFIGIError;
use openfigi_rs::model::{enums::IdType, request::MappingRequest};
async fn handle_mapping() -> anyhow::Result<()> {
let client = OpenFIGIClient::new();
let requests = vec![
MappingRequest::new(IdType::ID_ISIN, "US4592001014"), // Valid
MappingRequest::new(IdType::ID_ISIN, "INVALID_ISIN"), // Invalid
];
match client.bulk_mapping().add_requests(requests).send().await {
Ok(mapping_results) => {
// Handle successful results
for (_index, data) in mapping_results.successes() {
println!("SUCCESS: Found {} instruments.", data.data().len());
}
// Handle failed results
for (_index, error) in mapping_results.failures() {
println!("API ERROR: {}", error);
}
}
// Handle network errors, timeouts, etc.
Err(e) => {
eprintln!("An unexpected network error occurred: {}", e);
}
}
Ok(())
}
Β§π Documentation
- API Documentation - Complete technical documentation for this crate.
- OpenFIGI API Documentation - The upstream API documentation from OpenFIGI.
Β§π€ Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines on how to submit patches, report issues, and suggest features.
Β§π License
This project is licensed under the MIT License. See the LICENSE file for details.
Β§π Acknowledgments
- OpenFIGI for providing the public API.
- Bloomberg for the OpenFIGI initiative.
- OMG for providing documentation.
- The Rust community for creating amazing libraries like
reqwest
,reqwest-middleware
,serde
, andtokio
.
Β§π Support
For help with this library, please use the following resources:
- π Documentation: Check the API reference for detailed information.
- π Issues: For bugs and feature requests, please use the GitHub Issue Tracker.
- π¬ Discussions: For questions and general discussion, please use the GitHub Discussions.
Disclaimer: This library is an independent project and is not officially affiliated with, endorsed by, or sponsored by Bloomberg L.P. or the OpenFIGI project.
ModulesΒ§
- client
- HTTP client for OpenFIGI API operations HTTP client for interacting with the OpenFIGI API.
- client_
builder - Client builder with fluent configuration API for custom HTTP settings Builder pattern for configuring OpenFIGI API clients.
- endpoint
- API endpoint implementations for mapping, search, and filter operations
- error
- Comprehensive error types with OpenFIGI-specific context and inspection methods Error handling types for OpenFIGI API operations.
- model
- Strongly typed request and response data models for all API operations Data models for OpenFIGI API requests and responses.
MacrosΒ§
- impl_
filter_ builder - Macro to implement standard filter builder methods for OpenFIGI API request builders.
ConstantsΒ§
- DEFAULT_
ENDPOINT_ FILTER - The default endpoint path for filter requests.
- DEFAULT_
ENDPOINT_ MAPPING - The default endpoint path for mapping requests.
- DEFAULT_
ENDPOINT_ SEARCH - The default endpoint path for search requests.
- VERSION
- Library version
StaticsΒ§
- DEFAULT_
BASE_ URL - The default base URL for the OpenFIGI API v3.