Skip to content

Commit d82607d

Browse files
authored
Extend BaseClient to accept extra middleware (#8807)
This PR is a revival of #3502, albeit in a much simpler form. This would allow for different middlewares like authentication and such, useful for if you want to deviate from the keychain authentication methods when using uv as a library. @zanieb I hope I made the changes as you noted you wanted to see them :) Happy to add/change anything you need.
1 parent ef8724c commit d82607d

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

crates/uv-client/src/base_client.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use itertools::Itertools;
22
use reqwest::{Client, ClientBuilder, Response};
3-
use reqwest_middleware::ClientWithMiddleware;
3+
use reqwest_middleware::{ClientWithMiddleware, Middleware};
44
use reqwest_retry::policies::ExponentialBackoff;
55
use reqwest_retry::{
66
DefaultRetryableStrategy, RetryTransientMiddleware, Retryable, RetryableStrategy,
77
};
88
use std::error::Error;
99
use std::fmt::Debug;
1010
use std::path::Path;
11+
use std::sync::Arc;
1112
use std::time::Duration;
1213
use std::{env, iter};
1314
use tracing::debug;
@@ -54,6 +55,19 @@ pub struct BaseClientBuilder<'a> {
5455
platform: Option<&'a Platform>,
5556
auth_integration: AuthIntegration,
5657
default_timeout: Duration,
58+
extra_middleware: Option<ExtraMiddleware>,
59+
}
60+
61+
/// A list of user-defined middlewares to be applied to the client.
62+
#[derive(Clone)]
63+
pub struct ExtraMiddleware(pub Vec<Arc<dyn Middleware>>);
64+
65+
impl Debug for ExtraMiddleware {
66+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67+
f.debug_struct("ExtraMiddleware")
68+
.field("0", &format!("{} middlewares", self.0.len()))
69+
.finish()
70+
}
5771
}
5872

5973
impl Default for BaseClientBuilder<'_> {
@@ -75,6 +89,7 @@ impl BaseClientBuilder<'_> {
7589
platform: None,
7690
auth_integration: AuthIntegration::default(),
7791
default_timeout: Duration::from_secs(30),
92+
extra_middleware: None,
7893
}
7994
}
8095
}
@@ -140,6 +155,12 @@ impl<'a> BaseClientBuilder<'a> {
140155
self
141156
}
142157

158+
#[must_use]
159+
pub fn extra_middleware(mut self, middleware: ExtraMiddleware) -> Self {
160+
self.extra_middleware = Some(middleware);
161+
self
162+
}
163+
143164
pub fn is_offline(&self) -> bool {
144165
matches!(self.connectivity, Connectivity::Offline)
145166
}
@@ -313,6 +334,13 @@ impl<'a> BaseClientBuilder<'a> {
313334
}
314335
}
315336

337+
// When supplied add the extra middleware
338+
if let Some(extra_middleware) = &self.extra_middleware {
339+
for middleware in &extra_middleware.0 {
340+
client = client.with_arc(middleware.clone());
341+
}
342+
}
343+
316344
client.build()
317345
}
318346
Connectivity::Offline => reqwest_middleware::ClientBuilder::new(client)

crates/uv-client/src/registry_client.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use uv_pep508::MarkerEnvironment;
2626
use uv_platform_tags::Platform;
2727
use uv_pypi_types::{ResolutionMetadata, SimpleJson};
2828

29-
use crate::base_client::BaseClientBuilder;
29+
use crate::base_client::{BaseClientBuilder, ExtraMiddleware};
3030
use crate::cached_client::CacheControl;
3131
use crate::html::SimpleHtml;
3232
use crate::remote_metadata::wheel_metadata_from_remote_zip;
@@ -110,6 +110,12 @@ impl<'a> RegistryClientBuilder<'a> {
110110
self
111111
}
112112

113+
#[must_use]
114+
pub fn extra_middleware(mut self, middleware: ExtraMiddleware) -> Self {
115+
self.base_client_builder = self.base_client_builder.extra_middleware(middleware);
116+
self
117+
}
118+
113119
#[must_use]
114120
pub fn markers(mut self, markers: &'a MarkerEnvironment) -> Self {
115121
self.base_client_builder = self.base_client_builder.markers(markers);

0 commit comments

Comments
 (0)