openai-interface 0.13.0

A low-level Rust interface for the OpenAI API
Documentation
//! The Realtime API (HTTP part): create ephemeral client sessions via
//! `/realtime`.
//!
//! > ![warn] This module is untested!
//! > If you encounter any issues, please report them on the repository.
//!
//! The Realtime API's primary transport is WebSocket, which this crate
//! does not implement. The two HTTP endpoints here create the
//! short-lived session tokens a browser or mobile client uses to open
//! that WebSocket connection, so they can be issued from a backend
//! without exposing the API key. See
//! [the OpenAI Realtime guide](https://platform.openai.com/docs/guides/realtime).
//!
//! The session configuration (modalities, voice, tools, turn
//! detection, ...) is passed through as raw JSON, because it changes
//! frequently and only matters to the WebSocket client consuming it.

pub mod transcription_sessions;

use serde::{Deserialize, Serialize};
use url::Url;

use crate::{
    errors::OapiError,
    rest::post::{Post, PostNoStream},
};

/// Creates a Realtime session via `POST /realtime/sessions`.
///
/// The `session` field carries the full session configuration as raw
/// JSON (modalities, model, voice, instructions, tools,
/// turn_detection, ...), matching the official API's nested shape.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateRealtimeSessionRequest {
    /// The session configuration, as raw JSON. Use `{"model": ...}` at
    /// minimum; all other fields are optional server-side.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session: Option<serde_json::Value>,
    /// Additional JSON properties flattened into the request body, for
    /// fields not covered by the typed struct.
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_body_map: Option<serde_json::Map<String, serde_json::Value>>,
}

/// A client secret of a Realtime session.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RealtimeClientSecret {
    /// The secret token itself, e.g. `ek_...`.
    pub value: String,
    /// Unix timestamp (seconds) of when the secret expires.
    #[serde(default)]
    pub expires_at: Option<u64>,
}

/// The response of a Realtime session creation.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RealtimeSession {
    /// The object type (`realtime.session`).
    #[serde(default)]
    pub object: Option<String>,
    /// The ephemeral client secret used to open the WebSocket
    /// connection.
    pub client_secret: RealtimeClientSecret,
    /// The full effective session configuration, as raw JSON.
    #[serde(default)]
    pub session: Option<serde_json::Value>,
}

crate::impl_from_str!(RealtimeSession);

impl Post for CreateRealtimeSessionRequest {
    fn is_streaming(&self) -> bool {
        false
    }

    /// Builds the URL for the request.
    ///
    /// `base_url` should be like <https://api.openai.com/v1>
    fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
        let mut url = Url::parse(base_url.trim_end_matches('/')).map_err(OapiError::UrlError)?;
        url.path_segments_mut()
            .map_err(|_| OapiError::UrlCannotBeBase(base_url.to_string()))?
            .push("realtime")
            .push("sessions");
        Ok(url.to_string())
    }
}

impl PostNoStream for CreateRealtimeSessionRequest {
    type Response = RealtimeSession;
}