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

Issue:
QCSClient initialization errors
I've hit some errors when trying to initialize a QVM using `get_qc` in an environment where there are no QCS credential files. My understanding is pyQuil v3 would not throw an error if credential files were missing whereas `qcs_sdk.QCSClient.load()` will.

As a workaround, I tried to manually initialize `QCSClient`, but it seems initialization with keywords is not working as expected (see script below).

In addition fixing the attribute naming issue, there should probably be a test for initializing a QVM without any QCS credentials.

### Reproducing script

```python
from qcs_sdk import QCSClient

def main():
    client = QCSClient(
        qvm_url="QCS_SETTINGS_APPLICATIONS_QVM_URL",
        quilc_url="QCS_SETTINGS_APPLICATIONS_QUILC_URL",
        grpc_api_url="https://legacy.grpc.qcs.rigetti.com",
        api_url="https://api.qcs.rigetti.com",
    )
    assert client.qvm_url == "QCS_SETTINGS_APPLICATIONS_QVM_URL"
    assert client.quilc_url == "QCS_SETTINGS_APPLICATIONS_QUILC_URL"
    assert client.grpc_api_url == "https://legacy.grpc.qcs.rigetti.com"
    assert client.api_url == "https://api.qcs.rigetti.com"

if __name__ == "__main__":
    main()
```


Discussion / hints:

Fix patch:
diff --git a/crates/python/src/qpu/client.rs b/crates/python/src/qpu/client.rs
index 776989d96..17edfaba7 100644
--- a/crates/python/src/qpu/client.rs
+++ b/crates/python/src/qpu/client.rs
@@ -169,7 +169,7 @@ impl PyQcsClient {
             builder = builder.set_quilc_url(quilc_url);
         }
         if let Some(qvm_url) = qvm_url {
-            builder = builder.set_grpc_api_url(qvm_url);
+            builder = builder.set_qvm_url(qvm_url);
         }
         let client = builder
             .build()


Test patch:
diff --git a/crates/python/tests/qpu/test_client.py b/crates/python/tests/qpu/test_client.py
index 7e68cb06b..95a0b1f82 100644
--- a/crates/python/tests/qpu/test_client.py
+++ b/crates/python/tests/qpu/test_client.py
@@ -4,10 +4,12 @@
 from qcs_sdk import QCSClient
 from qcs_sdk.qpu.client import LoadClientError, QCSClientAuthServer, QCSClientTokens
 
+
 @pytest.fixture
 def default_client():
     return QCSClient()
 
+
 def test_client_has_url_from_env(default_client: QCSClient):
     """The default client is configured with valid urls."""
     assert urlparse(default_client.api_url).geturl() != ""
@@ -38,7 +40,9 @@ def test_client_default_profile_is_not_empty(default_client: QCSClient):
 @pytest.mark.not_qcs_session
 def test_client_broken_raises():
     """Using a profile with broken configuration should surface the underlying error."""
-    with pytest.raises(LoadClientError, match=r"Expected auth server .* but it didn't exist"):
+    with pytest.raises(
+        LoadClientError, match=r"Expected auth server .* but it didn't exist"
+    ):
         QCSClient.load(profile_name="broken")
 
 
@@ -54,3 +58,16 @@ def test_client_tokens_can_be_manually_defined():
     auth_server = QCSClientTokens(bearer_access_token="foo", refresh_token="bar")
     assert auth_server.bearer_access_token == "foo"
     assert auth_server.refresh_token == "bar"
+
+
+def test_client_constructor():
+    client = QCSClient(
+        qvm_url="qvm_url",
+        quilc_url="quilc_url",
+        grpc_api_url="grpc_api_url",
+        api_url="api_url",
+    )
+    assert client.qvm_url == "qvm_url"
+    assert client.quilc_url == "quilc_url"
+    assert client.grpc_api_url == "grpc_api_url"
+    assert client.api_url == "api_url"