twelve-data-client 0.3.0

Rust API client for Twelve Data with automatic builder pattern generation. Provides access to comprehensive financial market data including stocks, forex, ETFs, mutual funds, commodities, and cryptocurrencies.
Documentation
# Twelve Data Rust Client

A Rust API client for [Twelve Data](https://twelvedata.com/) — comprehensive financial market data API with access to stocks, forex, ETFs, mutual funds, commodities, and cryptocurrencies across 50+ countries.

**This client features automatic builder pattern generation for all API operations**, making it ergonomic to work with endpoints that have many optional parameters.

## Features

- **Builder Pattern API**: Clean, chainable parameter builders instead of functions with 20+ parameters
-**Full API Coverage**: Complete access to all Twelve Data endpoints (time series, fundamentals, ETFs, technical indicators, etc.)
-**Type-Safe**: Strongly typed request/response models generated from OpenAPI spec
-**Async**: Built on `reqwest` with async/await support via `tokio`
-**Authentication**: API key authentication via Authorization header

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
twelve-data-client = "0.3"
tokio = { version = "1.49.0", features = ["full"] }
```

## Quick Start

```rust
use twelve_data_client::apis::{configuration, time_series_api};
use twelve_data_client::apis::time_series_api::GetTimeSeriesParams;
use twelve_data_client::models::GetTimeSeries200ResponseEnum;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure authentication
    let mut config = configuration::Configuration::new();
    config.api_key = Some(configuration::ApiKey {
        prefix: Some("apikey".to_string()),
        key: std::env::var("TWELVE_DATA_API_KEY")?,
    });

    // Build parameters using builder pattern
    let params = GetTimeSeriesParams::builder()
        .symbol("AAPL")
        .interval("1day")
        .outputsize(10)
        .build();

    // Make API call and handle response
    let response = time_series_api::get_time_series(&config, params).await?;
    
    match response {
        GetTimeSeries200ResponseEnum::GetTimeSeries200Response(data) => {
            println!("Symbol: {:?}", data.meta.as_ref().unwrap().symbol);
            println!("Data points: {}", data.values.as_ref().unwrap().len());
        }
        GetTimeSeries200ResponseEnum::ApiError(err) => {
            eprintln!("API Error: {}", err.message.unwrap_or_default());
        }
        GetTimeSeries200ResponseEnum::Text(csv) => {
            println!("CSV Response:\n{}", csv);
        }
    }
    
    Ok(())
}
```

## Authentication

Get your API key from the [Twelve Data dashboard](https://twelvedata.com/account/api-keys).

Set it as an environment variable:
```bash
export TWELVE_DATA_API_KEY="your_api_key_here"
```

Or configure it directly:
```rust
config.api_key = Some(configuration::ApiKey {
    prefix: Some("apikey".to_string()),
    key: "your_api_key_here".to_string(),
});
```

## Builder Pattern Example

Instead of this (many individual parameters):
```rust
// Old style - difficult to use
get_time_series(
    &config,
    "AAPL",
    "1day",
    None, None, None, None, None, 
    Some(10), 
    None, None, None, None, None, None, None, None, None
).await?
```

You get this (clean builder pattern):
```rust
use twelve_data_client::models::GetTimeSeries200ResponseEnum;

// New style - ergonomic and clear
let params = GetTimeSeriesParams::builder()
    .symbol("AAPL")
    .interval("1day")
    .outputsize(10)
    .build();

let response = get_time_series(&config, params).await?;

// Handle the response enum
match response {
    GetTimeSeries200ResponseEnum::GetTimeSeries200Response(data) => {
        // Process successful JSON response
        println!("Got {} data points", data.values.unwrap().len());
    }
    GetTimeSeries200ResponseEnum::ApiError(err) => {
        // Handle API errors
        eprintln!("Error: {}", err.message.unwrap_or_default());
    }
    GetTimeSeries200ResponseEnum::Text(csv) => {
        // Handle CSV format response
        println!("CSV data:\n{}", csv);
    }
}
```

### Response Types

Most endpoints return an enum type with multiple variants to handle different response scenarios:

- **Success variant**: Contains the actual data (e.g., `GetTimeSeries200Response`)
- **`ApiError` variant**: Contains error information when the API returns an error
- **`Text` variant**: Contains raw text (CSV) response when using `format` parameter

This approach provides type-safe error handling and format flexibility.

## Available APIs

This client provides access to all Twelve Data endpoints organized by module:

- **`time_series_api`** - Historical OHLCV data
- **`fundamentals_api`** - Company financials, balance sheets, income statements
- **`reference_data_api`** - Symbols, exchanges, currencies
- **`technical_indicator_api`** - Technical analysis indicators
- **`market_data_api`** - Real-time quotes and prices
- **`etfs_api`** - ETF-specific data
- **`mutual_funds_api`** - Mutual fund data
- **`analysis_api`** - Analysis endpoints
- **`regulatory_api`** - Regulatory filings
- **`advanced_api`** - Advanced data endpoints

## Code Generation

This client was automatically generated from the [Twelve Data OpenAPI specification](https://api.twelvedata.com/doc/swagger/openapi.json) using a modified version of [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).

### Generation Process

The client was generated using [openapi-generator-rust-builders](https://github.com/alex12058/openapi-generator-rust-builders), a fork of OpenAPI Generator that adds automatic builder pattern generation for all Rust API operations.

**Generator Location**: The generator is included as a git submodule at `./openapi-generator-rust-builders/`

**Build and generate:**
```bash
# Build the modified generator
cd openapi-generator-rust-builders
./mvnw clean package -DskipTests

# Generate the client
cd ..
java -jar openapi-generator-rust-builders/modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
  -i openapi.json \
  -g rust \
  -o . \
  --additional-properties=packageName=twelve_data_client,packageVersion=0.1.0,library=reqwest
```

### OpenAPI Specification Modification

The original Twelve Data OpenAPI spec required one minor modification to work with this generator:

**Issue**: The spec defined API key authentication in two places:
- As a query parameter: `?apikey=value`
- As an Authorization header: `Authorization: apikey value`

This caused the generator to add the API key twice, which the Twelve Data API rejected.

**Solution**: Removed the `queryParameters` security scheme from the OpenAPI spec, keeping only the header-based authentication:

```json
{
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "securitySchemes": {
    "ApiKeyAuth": {
      "type": "apiKey",
      "in": "header",
      "name": "Authorization"
    }
  }
}
```

The modified OpenAPI specification is saved as `openapi.json` in this repository.

### Regenerating the Client

To regenerate the client after OpenAPI spec updates:

1. Download the latest spec from Twelve Data:
   ```bash
   curl https://api.twelvedata.com/doc/swagger/openapi.json -o openapi.json
   ```

2. Apply the security modification (remove query parameter security scheme)

3. Rebuild the generator (if needed):
   ```bash
   cd openapi-generator-rust-builders
   ./mvnw clean package -DskipTests
   cd ..
   ```

4. Generate the client:
   ```bash
   java -jar openapi-generator-rust-builders/modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
     -i openapi.json \
     -g rust \
     -o . \
     --additional-properties=packageName=twelve_data_client,packageVersion=0.1.0,library=reqwest
   ```

5. Add tokio dev-dependency back to Cargo.toml (it gets overwritten):
   ```toml
   [dev-dependencies]
   tokio = { version = "1", features = ["full"] }
   ```

## Examples

See the `tests/` directory for complete working examples:

- [`time_series_builder.rs`]tests/time_series_builder.rs - Fetching historical time series data with builder pattern, including JSON, error, and CSV response handling

Run the tests:
```bash
export TWELVE_DATA_API_KEY="your_api_key"
cargo test --test time_series_builder
```

## Documentation

- [Twelve Data API Documentation]https://twelvedata.com/docs
- [API Reference]https://api.twelvedata.com/doc/swagger/
- [Get API Key]https://twelvedata.com/account/api-keys

## License

This client library is licensed under the Unlicense.

The Twelve Data API is a commercial service. See [Twelve Data pricing](https://twelvedata.com/pricing) for details.

## Links

- [Twelve Data Website]https://twelvedata.com/
- [Twelve Data GitHub]https://github.com/twelvedata
- [OpenAPI Generator Fork (with Rust Builders)]https://github.com/alex12058/openapi-generator-rust-builders
- [Base OpenAPI Generator]https://github.com/OpenAPITools/openapi-generator