use pyo3::exceptions::{PyRuntimeError, PyValueError};
use pyo3::prelude::*;
use tracing_subscriber;
mod interactive;
mod session;
use session::{PyOutputStream, PySession, PySessionConfig, PySessionManager, PySessionType};
#[allow(missing_docs)]
mod exceptions {
pyo3::create_exception!(_internal, AwsSsmBridgeError, pyo3::exceptions::PyException);
pyo3::create_exception!(_internal, SsmSessionError, AwsSsmBridgeError);
pyo3::create_exception!(_internal, SsmProtocolError, AwsSsmBridgeError);
pyo3::create_exception!(_internal, SsmTransportError, AwsSsmBridgeError);
pyo3::create_exception!(_internal, SsmAwsSdkError, AwsSsmBridgeError);
pyo3::create_exception!(_internal, SsmTimeoutError, AwsSsmBridgeError);
pyo3::create_exception!(_internal, SsmCancelledError, AwsSsmBridgeError);
}
use exceptions::*;
#[pymodule]
fn _internal(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<PySessionManager>()?;
m.add_class::<PySession>()?;
m.add_class::<PySessionConfig>()?;
m.add_class::<PySessionType>()?;
m.add_class::<PyOutputStream>()?;
interactive::register(m)?;
m.add_function(wrap_pyfunction!(configure_logging, m)?)?;
m.add("AwsSsmBridgeError", m.py().get_type::<AwsSsmBridgeError>())?;
m.add("SsmSessionError", m.py().get_type::<SsmSessionError>())?;
m.add("SsmProtocolError", m.py().get_type::<SsmProtocolError>())?;
m.add("SsmTransportError", m.py().get_type::<SsmTransportError>())?;
m.add("SsmAwsSdkError", m.py().get_type::<SsmAwsSdkError>())?;
m.add("SsmTimeoutError", m.py().get_type::<SsmTimeoutError>())?;
m.add("SsmCancelledError", m.py().get_type::<SsmCancelledError>())?;
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
Ok(())
}
#[pyfunction]
#[pyo3(signature = (level="warn"))]
fn configure_logging(level: &str) -> PyResult<()> {
let directive: tracing::level_filters::LevelFilter = match level.to_lowercase().as_str() {
"error" => tracing::Level::ERROR.into(),
"warn" => tracing::Level::WARN.into(),
"info" => tracing::Level::INFO.into(),
"debug" => tracing::Level::DEBUG.into(),
"trace" => tracing::Level::TRACE.into(),
"off" => tracing::level_filters::LevelFilter::OFF,
_ => {
return Err(PyValueError::new_err(format!(
"Invalid log level '{}'. Use: off, error, warn, info, debug, trace",
level
)));
}
};
let _ = tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env().add_directive(directive.into()),
)
.try_init();
Ok(())
}
pub(crate) fn to_py_err(err: crate::Error) -> PyErr {
use crate::Error;
match err {
Error::Config(msg) => PyValueError::new_err(msg),
Error::InvalidState(msg) => PyRuntimeError::new_err(msg),
Error::Session(e) => SsmSessionError::new_err(e.to_string()),
Error::Protocol(e) => SsmProtocolError::new_err(e.to_string()),
Error::Transport(e) => SsmTransportError::new_err(e.to_string()),
Error::AwsSdk { message, .. } => SsmAwsSdkError::new_err(message),
Error::Timeout => SsmTimeoutError::new_err("Operation timed out"),
Error::Cancelled => SsmCancelledError::new_err("Operation was cancelled"),
other => AwsSsmBridgeError::new_err(other.to_string()),
}
}