Skip to content

Commit b7ed702

Browse files
chore: prepare new release(s)
1 parent 764191b commit b7ed702

31 files changed

+2937
-473
lines changed

.github/action-common-python-release/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ runs:
2424
steps:
2525
- uses: actions/setup-python@v4
2626
with:
27-
python-version: "3.13"
27+
python-version: "3.12"
2828
architecture: ${{ inputs.python-architecture }}
2929
- name: Install Rust toolchain
3030
uses: actions-rs/toolchain@v1
@@ -47,7 +47,7 @@ runs:
4747
manylinux: '2_28'
4848
command: ${{ inputs.maturin-command }}
4949
target: ${{ inputs.maturin-target }}
50-
args: -i 3.8 3.9 3.10 3.11 3.12 3.13 --release --manifest-path qcs-api-client-common/Cargo.toml --out dist
50+
args: -i 3.8 3.9 3.10 3.11 3.12 --release --manifest-path qcs-api-client-common/Cargo.toml --out dist
5151
docker-options: -e CI
5252
- if: inputs.maturin-command == 'sdist'
5353
name: Maturin - Source Distribution

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

qcs-api-client-common/CHANGELOG-py.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.11.8 (2025-01-27)
2+
3+
### Fixes
4+
5+
#### allow oauth_session to be constructed without refresh tokens, allow JWTBearerOptional operations to skip bearer tokens
6+
7+
#### temporarily revert python 3.13 support introduced in common/v0.11.7
8+
19
## 0.11.7 (2025-01-27)
210

311
### Features

qcs-api-client-common/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.11.8 (2025-01-27)
2+
3+
### Fixes
4+
5+
#### allow oauth_session to be constructed without refresh tokens, allow JWTBearerOptional operations to skip bearer tokens
6+
7+
#### temporarily revert python 3.13 support introduced in common/v0.11.7
8+
19
## 0.11.7 (2025-01-27)
210

311
### Features

qcs-api-client-common/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "qcs-api-client-common"
3-
version = "0.11.7"
3+
version = "0.11.8"
44
edition = "2021"
55
license = "Apache-2.0"
66
readme = "README.md"

qcs-api-client-common/pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "qcs-api-client-common"
3-
version = "0.11.7"
3+
version = "0.11.8"
44
description = "Contains core QCS client functionality and middleware implementations."
55
readme = "README-py.md"
66
license = { text = "Apache-2.0" }
@@ -14,7 +14,6 @@ classifiers = [
1414
"Programming Language :: Python :: 3.10",
1515
"Programming Language :: Python :: 3.11",
1616
"Programming Language :: Python :: 3.12",
17-
"Programming Language :: Python :: 3.13",
1817
"Operating System :: OS Independent",
1918
]
2019
dependencies = [

qcs-api-client-common/src/configuration/mod.rs

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use std::{env, path::PathBuf};
3535
use pyo3::prelude::*;
3636

3737
use self::{
38-
secrets::{Credential, Secrets},
38+
secrets::{Credential, Secrets, TokenPayload},
3939
settings::Settings,
4040
};
4141

@@ -183,26 +183,38 @@ impl ClientConfiguration {
183183

184184
let secrets_path = secrets.file_path;
185185
let credential = secrets.credentials.remove(&profile.credentials_name);
186-
let (access_token, refresh_token) = match credential {
186+
let oauth_session = match credential {
187187
Some(Credential {
188-
token_payload: Some(token_payload),
189-
}) => (token_payload.access_token, token_payload.refresh_token),
190-
_ => (None, None),
188+
token_payload:
189+
Some(TokenPayload {
190+
access_token,
191+
refresh_token,
192+
..
193+
}),
194+
}) => {
195+
Some(OAuthSession::new(
196+
OAuthGrant::RefreshToken(RefreshToken::new(
197+
// Some configurations do not populate or may use an
198+
// empty string for the `refresh_token`, but are still
199+
// valid sessions with a valid `access_token`.
200+
//
201+
// Because we found a `token_payload`, we must assume
202+
// the user wants to construct an `OAuthSession`.
203+
// Note that this is no guarantee of session validity.
204+
refresh_token.unwrap_or_default(),
205+
)),
206+
auth_server,
207+
access_token,
208+
))
209+
}
210+
_ => None,
191211
};
192212

193213
let api_url = env::var(API_URL_VAR).unwrap_or(profile.api_url);
194214
let quilc_url = env::var(QUILC_URL_VAR).unwrap_or(profile.applications.pyquil.quilc_url);
195215
let qvm_url = env::var(QVM_URL_VAR).unwrap_or(profile.applications.pyquil.qvm_url);
196216
let grpc_api_url = env::var(GRPC_API_URL_VAR).unwrap_or(profile.grpc_api_url);
197217

198-
let oauth_session = refresh_token.map(|refresh_token| {
199-
OAuthSession::new(
200-
OAuthGrant::RefreshToken(RefreshToken::new(refresh_token)),
201-
auth_server.clone(),
202-
access_token,
203-
)
204-
});
205-
206218
#[cfg(feature = "tracing-config")]
207219
let tracing_configuration =
208220
TracingConfiguration::from_env().map_err(LoadError::TracingFilterParseError)?;
@@ -756,4 +768,72 @@ token_type = "Bearer"
756768
);
757769
assert!(tokens.validate().is_err());
758770
}
771+
772+
#[tokio::test]
773+
async fn test_session_is_present_with_empty_refresh_token_and_valid_access_token() {
774+
let access_token = Claims::new_valid().to_encoded();
775+
let mut config = ClientConfiguration::builder().build().unwrap();
776+
figment::Jail::expect_with(|jail| {
777+
let directory = jail.directory();
778+
let settings_file_name = "settings.toml";
779+
let settings_file_path = directory.join(settings_file_name);
780+
let secrets_file_name = "secrets.toml";
781+
let secrets_file_path = directory.join(secrets_file_name);
782+
783+
let settings_file_contents = r#"
784+
default_profile_name = "default"
785+
786+
[profiles]
787+
[profiles.default]
788+
api_url = ""
789+
auth_server_name = "default"
790+
credentials_name = "default"
791+
792+
[auth_servers]
793+
[auth_servers.default]
794+
client_id = ""
795+
issuer = ""
796+
"#;
797+
798+
// note this has no `refresh_token` property
799+
let secrets_file_contents = format!(
800+
r#"
801+
[credentials]
802+
[credentials.default]
803+
[credentials.default.token_payload]
804+
access_token = "{access_token}"
805+
expires_in = 3600
806+
id_token = "id_token"
807+
scope = "offline_access openid profile email"
808+
token_type = "Bearer"
809+
"#
810+
);
811+
812+
jail.create_file(settings_file_name, settings_file_contents)
813+
.expect("should create test settings.toml");
814+
jail.create_file(secrets_file_name, &secrets_file_contents)
815+
.expect("should create test secrets.toml");
816+
817+
jail.set_env(
818+
"QCS_SETTINGS_FILE_PATH",
819+
settings_file_path
820+
.to_str()
821+
.expect("settings file path should be a string"),
822+
);
823+
jail.set_env(
824+
"QCS_SECRETS_FILE_PATH",
825+
secrets_file_path
826+
.to_str()
827+
.expect("secrets file path should be a string"),
828+
);
829+
830+
config = ClientConfiguration::load_default().unwrap();
831+
Ok(())
832+
});
833+
834+
assert_eq!(
835+
config.get_bearer_access_token().await.unwrap(),
836+
access_token.to_string()
837+
);
838+
}
759839
}

qcs-api-client-common/src/configuration/tokens.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ impl RefreshToken {
4040
&mut self,
4141
auth_server: &AuthServer,
4242
) -> Result<String, TokenError> {
43+
if self.refresh_token.is_empty() {
44+
return Err(TokenError::NoRefreshToken);
45+
}
4346
let token_url = format!("{}/v1/token", auth_server.issuer());
4447
let data = TokenRefreshRequest::new(auth_server.client_id(), &self.refresh_token);
4548
let resp = reqwest::Client::builder()

qcs-api-client-grpc/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.11.8 (2025-01-27)
2+
3+
### Fixes
4+
5+
#### allow oauth_session to be constructed without refresh tokens, allow JWTBearerOptional operations to skip bearer tokens
6+
7+
#### temporarily revert python 3.13 support introduced in common/v0.11.7
8+
19
## 0.11.7 (2025-01-27)
210

311
### Features

qcs-api-client-grpc/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "qcs-api-client-grpc"
3-
version = "0.11.7"
3+
version = "0.11.8"
44
edition = "2021"
55
license = "Apache-2.0"
66
readme = "README.md"
@@ -27,7 +27,7 @@ opentelemetry_sdk = { workspace = true }
2727
pbjson = { workspace = true }
2828
pbjson-types = { workspace = true }
2929
prost = { workspace = true }
30-
qcs-api-client-common = { path = "../qcs-api-client-common", version = "0.11.7" }
30+
qcs-api-client-common = { path = "../qcs-api-client-common", version = "0.11.8" }
3131
serde = { workspace = true }
3232
thiserror = { workspace = true }
3333
tokio = { workspace = true, features = ["time"] }

0 commit comments

Comments
 (0)