Repository: rigetti/qcs-sdk-rust (language: python)

Issue:
Provide access to the configured `TranslationBackend` variant
See https://github.com/rigetti/pyquil/issues/1678


Discussion / hints:

Fix patch:
diff --git a/crates/lib/src/qpu/translation.rs b/crates/lib/src/qpu/translation.rs
index d494a55e8..c1acef30a 100644
--- a/crates/lib/src/qpu/translation.rs
+++ b/crates/lib/src/qpu/translation.rs
@@ -122,6 +122,12 @@ pub struct TranslationOptions {
 }
 
 impl TranslationOptions {
+    /// Get the backend used for translation
+    #[must_use]
+    pub fn backend(&self) -> Option<&TranslationBackend> {
+        self.inner.translation_backend.as_ref()
+    }
+
     /// Use the first-generation translation backend available on QCS since 2018.
     pub fn use_backend_v1(&mut self) {
         self.inner.translation_backend =
diff --git a/crates/python/qcs_sdk/qpu/translation.pyi b/crates/python/qcs_sdk/qpu/translation.pyi
index f3be090f7..ba2d707c9 100644
--- a/crates/python/qcs_sdk/qpu/translation.pyi
+++ b/crates/python/qcs_sdk/qpu/translation.pyi
@@ -1,4 +1,5 @@
 from typing import Dict, Optional, final
+from enum import Enum, auto
 
 from qcs_sdk.client import QCSClient
 
@@ -44,6 +45,12 @@ class TranslationResult:
         """A mapping from the program's memory references to the key used to index the results map."""
         ...
 
+
+@final
+class TranslationBackend(Enum):
+    V1 = auto()
+    V2 = auto()
+
 def get_quilt_calibrations(
     quantum_processor_id: str,
     client: Optional[QCSClient] = None,
@@ -134,6 +141,12 @@ class TranslationOptions:
     Options for translating via the QCS API.
     """
 
+    @property
+    def backend(self) -> Optional[TranslationBackend]:
+        """
+        Get the selected translation backend
+        """
+
     def use_backend_v1(self) -> None:
         """
         Use the v1 backend for translation, available on QCS since 2018.
diff --git a/crates/python/src/qpu/translation.rs b/crates/python/src/qpu/translation.rs
index 27395c9f2..9b5572851 100644
--- a/crates/python/src/qpu/translation.rs
+++ b/crates/python/src/qpu/translation.rs
@@ -6,9 +6,11 @@ use pyo3::{
 };
 use qcs::client::GrpcClientError;
 use qcs::qpu::translation::TranslationOptions;
+use qcs_api_client_grpc::services::translation::translation_options::TranslationBackend as ApiTranslationBackend;
 use qcs_api_client_openapi::models::GetQuiltCalibrationsResponse;
 use rigetti_pyo3::{
-    create_init_submodule, py_wrap_data_struct, py_wrap_error, wrap_error, ToPythonError,
+    create_init_submodule, py_wrap_data_struct, py_wrap_error, py_wrap_simple_enum, wrap_error,
+    ToPythonError,
 };
 
 use crate::py_sync::py_function_sync_async;
@@ -19,7 +21,8 @@ create_init_submodule! {
     classes: [
         PyQuiltCalibrations,
         PyTranslationOptions,
-        PyTranslationResult
+        PyTranslationResult,
+        PyTranslationBackend
     ],
     errors: [
         GetQuiltCalibrationsError,
@@ -88,6 +91,19 @@ py_wrap_error!(
     PyRuntimeError
 );
 
+#[derive(Copy, Clone)]
+pub enum TranslationBackend {
+    V1,
+    V2,
+}
+
+py_wrap_simple_enum! {
+    PyTranslationBackend(TranslationBackend) as "TranslationBackend" {
+        V1,
+        V2
+    }
+}
+
 #[derive(Clone, Default)]
 #[pyclass(name = "TranslationOptions")]
 pub struct PyTranslationOptions(TranslationOptions);
@@ -105,6 +121,14 @@ impl PyTranslationOptions {
         Ok(Self(Default::default()))
     }
 
+    #[getter]
+    fn backend(&self) -> Option<PyTranslationBackend> {
+        self.0.backend().map(|b| match b {
+            ApiTranslationBackend::V1(_) => PyTranslationBackend::V1,
+            ApiTranslationBackend::V2(_) => PyTranslationBackend::V2,
+        })
+    }
+
     fn use_backend_v1(&mut self) {
         self.0.use_backend_v1()
     }


Test patch:
diff --git a/crates/python/tests/qpu/test_translation.py b/crates/python/tests/qpu/test_translation.py
index b30719f78..1fe768f99 100644
--- a/crates/python/tests/qpu/test_translation.py
+++ b/crates/python/tests/qpu/test_translation.py
@@ -58,3 +58,13 @@ async def test_get_quilt_calibrations(
 ):
     program = await get_quilt_calibrations_async(quantum_processor_id)
     assert program
+
+
+def test_translation_backend():
+    from qcs_sdk.qpu.translation import TranslationBackend, TranslationOptions
+    opts = TranslationOptions()
+    assert opts.backend is None
+    opts.use_backend_v1()
+    assert opts.backend == TranslationBackend.V1
+    opts.use_backend_v2()
+    assert opts.backend == TranslationBackend.V2