use std::sync::OnceLock;
use pyo3::prelude::*;
use rigetti_pyo3::{create_init_submodule, py_sync};
#[cfg(feature = "stubs")]
use pyo3_stub_gen::derive::gen_stub_pyfunction;
use crate::{
compiler, diagnostics,
python::{
executable::{ExeParameter, PyExecutable, PyJobHandle},
execution_data::{
PyRegisterMatrix, RegisterMapItemsIter, RegisterMapKeysIter, RegisterMapValuesIter,
},
},
qpu, qvm, ExecutionData, RegisterData, RegisterMap, Service,
};
pub(crate) mod client;
pub(crate) mod errors;
pub(crate) mod executable;
pub(crate) mod execution_data;
pub(crate) mod nonzero;
pub(crate) mod register_data;
pub(crate) use nonzero::NonZeroU16;
static PY_RESET_LOGGING_HANDLE: OnceLock<pyo3_log::ResetHandle> = OnceLock::new();
const PACKAGE_DOC: &str =
"An interface to Rigetti [Quantum Cloud Services](https://docs.rigetti.com/qcs/) (QCS).
These APIs allow users to compile and run Quil programs on Rigetti quantum processors.
Internally, it is powered by the [QCS Rust SDK](https://github.com/rigetti/qcs-sdk-rust).
This package is still in development and breaking changes should be expected between minor versions.
";
create_init_submodule! {
classes: [
ExeParameter,
ExecutionData,
PyExecutable,
PyJobHandle,
RegisterMap,
RegisterMapItemsIter,
RegisterMapKeysIter,
RegisterMapValuesIter,
Service
],
complex_enums: [ PyRegisterMatrix, RegisterData ],
errors: [
errors::QcsSdkError,
errors::ExecutionError,
errors::RegisterMatrixConversionError
],
funcs: [ reset_logging, gather_diagnostics ],
submodules: [
"client": client::init_submodule,
"compiler": compiler::python::init_submodule,
"qpu": qpu::python::init_submodule,
"qvm": qvm::python::init_submodule,
"diagnostics": diagnostics::python::init_submodule
],
}
#[pymodule]
#[pyo3(name = "_qcs_sdk")]
fn init_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
match pyo3_log::try_init() {
Ok(reset_handle) => {
drop(PY_RESET_LOGGING_HANDLE.set(reset_handle));
}
Err(e) => eprintln!("Failed to initialize the qcs_sdk logger: {e}"),
}
let py = m.py();
init_submodule("qcs_sdk._qcs_sdk", py, m)?;
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
m.setattr("__doc__", PACKAGE_DOC)?;
pyo3_tracing_subscriber::add_submodule("qcs_sdk", "_tracing_subscriber", py, m)?;
Ok(())
}
#[cfg(feature = "stubs")]
mod stubs {
use pyo3_stub_gen::{
define_stub_info_gatherer, export_verbatim, exclude_from_all,
derive::gen_type_alias_from_python,
generate::Module, module_doc, reexport_module_members, Result,
StubInfo,
};
use std::path::Path;
#[derive(pyo3::IntoPyObject)]
struct Final<T>(T);
impl<T> pyo3_stub_gen::PyStubType for Final<T>
where
T: pyo3_stub_gen::PyStubType,
{
fn type_output() -> pyo3_stub_gen::TypeInfo {
let mut inner = T::type_output();
inner.import.insert("typing".into());
inner.name = format!("typing.Final[{}]", inner.name);
inner
}
}
pyo3_stub_gen::module_variable!("qcs_sdk._qcs_sdk", "__version__", Final<&str>);
pyo3_stub_gen::module_variable!(
"qcs_sdk._qcs_sdk.compiler.quilc",
"DEFAULT_COMPILER_TIMEOUT",
Final<f64>
);
pyo3_stub_gen::module_doc!("qcs_sdk._qcs_sdk", "{}", super::PACKAGE_DOC);
gen_type_alias_from_python!(
"qcs_sdk._qcs_sdk.client",
r#"
AuthServer: TypeAlias = configuration.AuthServer
ClientCredentials: TypeAlias = configuration.ClientCredentials
ExternallyManaged: TypeAlias = configuration.ExternallyManaged
OAuthSession: TypeAlias = configuration.OAuthSession
RefreshToken: TypeAlias = configuration.RefreshToken
SecretRefreshToken: TypeAlias = configuration.SecretRefreshToken
"#
);
reexport_module_members!("qcs_sdk" from "qcs_sdk._qcs_sdk"; *, "__doc__", "__version__");
reexport_module_members!("qcs_sdk.client" from "qcs_sdk._qcs_sdk.client");
reexport_module_members!("qcs_sdk.compiler" from "qcs_sdk._qcs_sdk.compiler");
reexport_module_members!("qcs_sdk.compiler.quilc" from "qcs_sdk._qcs_sdk.compiler.quilc");
reexport_module_members!("qcs_sdk.diagnostics" from "qcs_sdk._qcs_sdk.diagnostics");
reexport_module_members!("qcs_sdk.qpu" from "qcs_sdk._qcs_sdk.qpu");
reexport_module_members!("qcs_sdk.qpu.api" from "qcs_sdk._qcs_sdk.qpu.api");
reexport_module_members!("qcs_sdk.qpu.experimental" from "qcs_sdk._qcs_sdk.qpu.experimental");
reexport_module_members!("qcs_sdk.qpu.experimental.random" from "qcs_sdk._qcs_sdk.qpu.experimental.random");
reexport_module_members!("qcs_sdk.qpu.isa" from "qcs_sdk._qcs_sdk.qpu.isa");
reexport_module_members!("qcs_sdk.qpu.translation" from "qcs_sdk._qcs_sdk.qpu.translation");
reexport_module_members!("qcs_sdk.qvm" from "qcs_sdk._qcs_sdk.qvm");
reexport_module_members!("qcs_sdk.qvm.api" from "qcs_sdk._qcs_sdk.qvm.api");
reexport_module_members!("qcs_sdk._qcs_sdk.client" from "qcs_api_client_common._qcs_api_client_common"; "configuration");
reexport_module_members!("qcs_sdk._qcs_sdk.compiler.quilc" from "quil._quil"; "program");
exclude_from_all!("qcs_sdk._qcs_sdk.client", "configuration");
exclude_from_all!("qcs_sdk._qcs_sdk.compiler.quilc", "program");
reexport_module_members!("qcs_sdk" from "qcs_sdk._qcs_sdk.client"; "QCSClient");
reexport_module_members!("qcs_sdk" from "qcs_sdk"; "_tracing_subscriber");
reexport_module_members!("qcs_sdk._qcs_sdk" from "qcs_sdk"; "_tracing_subscriber");
export_verbatim!("qcs_sdk._qcs_sdk", "_tracing_subscriber");
export_verbatim!("qcs_sdk._qcs_sdk", "_gather_diagnostics");
export_verbatim!("qcs_sdk._qcs_sdk", "__version__");
module_doc!("quil._quil.validation", "");
define_stub_info_gatherer!(internal_stub_info);
pub fn stub_info() -> Result<StubInfo> {
let manifest_dir: &Path = env!("CARGO_MANIFEST_DIR").as_ref();
let mut stubs = StubInfo::from_pyproject_toml(manifest_dir.join("pyproject.toml"))?;
stubs
.modules
.retain(|name, _| name == "qcs_sdk" || name.starts_with("qcs_sdk."));
Ok(stubs)
}
}
#[cfg(feature = "stubs")]
pub use stubs::stub_info;
#[cfg_attr(feature = "stubs", gen_stub_pyfunction(module = "qcs_sdk._qcs_sdk"))]
#[pyfunction]
fn reset_logging() {
if let Some(handle) = PY_RESET_LOGGING_HANDLE.get() {
handle.reset();
}
}
#[cfg_attr(feature = "stubs", gen_stub_pyfunction(module = "qcs_sdk._qcs_sdk"))]
#[pyfunction]
#[pyo3(name = "_gather_diagnostics")]
fn gather_diagnostics(py: Python<'_>) -> PyResult<String> {
py_sync!(py, async { Ok(diagnostics::get_report().await) })
}