Skip to content

Commit ee42dbd

Browse files
committed
Relax platform requirements to support macOS 13
1 parent e9e663c commit ee42dbd

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

Package.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import PackageDescription
66
let package = Package(
77
name: "swift-huggingface",
88
platforms: [
9-
.macOS(.v14),
10-
.macCatalyst(.v14),
9+
.macOS(.v13),
10+
.macCatalyst(.v16),
1111
.iOS(.v16),
12-
.watchOS(.v10),
13-
.tvOS(.v17),
12+
.watchOS(.v9),
13+
.tvOS(.v16),
1414
.visionOS(.v1),
1515
],
1616
products: [

Sources/HuggingFace/OAuth/HuggingFaceAuthenticationManager.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/// A manager for handling Hugging Face OAuth authentication.
66
///
77
/// - SeeAlso: [Hugging Face OAuth Documentation](https://huggingface.co/docs/api-inference/authentication)
8+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
89
@Observable
910
@MainActor
1011
public final class HuggingFaceAuthenticationManager: Sendable {
@@ -184,6 +185,7 @@
184185

185186
// MARK: -
186187

188+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
187189
extension HuggingFaceAuthenticationManager {
188190
/// OAuth scopes supported by HuggingFace
189191
public enum Scope: Hashable, Sendable {
@@ -247,6 +249,7 @@
247249
}
248250
}
249251

252+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
250253
extension HuggingFaceAuthenticationManager.Scope: RawRepresentable {
251254
public init(rawValue: String) {
252255
switch rawValue {
@@ -299,6 +302,7 @@
299302
}
300303
}
301304

305+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
302306
extension HuggingFaceAuthenticationManager.Scope: Codable {
303307
public init(from decoder: Decoder) throws {
304308
let container = try decoder.singleValueContainer()
@@ -312,12 +316,14 @@
312316
}
313317
}
314318

319+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
315320
extension HuggingFaceAuthenticationManager.Scope: ExpressibleByStringLiteral {
316321
public init(stringLiteral value: String) {
317322
self = Self(rawValue: value)
318323
}
319324
}
320325

326+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
321327
extension Set<HuggingFaceAuthenticationManager.Scope> {
322328
public static var basic: Self { [.openid, .profile, .email] }
323329
public static var readAccess: Self { [.openid, .profile, .email, .readRepos] }
@@ -329,6 +335,7 @@
329335

330336
// MARK: -
331337

338+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
332339
extension HuggingFaceAuthenticationManager {
333340
/// A mechanism for storing and retrieving OAuth tokens.
334341
public struct TokenStorage: Sendable {

Sources/HuggingFace/Shared/TokenProvider.swift

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@ import Foundation
3434
///
3535
/// ## OAuth Authentication
3636
///
37-
/// For OAuth-based authentication, use the `.oauth` case with an authentication manager:
37+
/// For OAuth-based authentication (requires macOS 14+, iOS 17+), use the `.oauth(manager:)` factory method:
3838
///
3939
/// ```swift
40-
/// let authManager = HuggingFaceAuthenticationManager(
40+
/// let authManager = try HuggingFaceAuthenticationManager(
4141
/// clientID: "your-client-id",
42-
/// redirectURL: URL(string: "myapp://oauth")!
42+
/// redirectURL: URL(string: "myapp://oauth")!,
43+
/// scope: .basic,
44+
/// keychainService: "com.example.app",
45+
/// keychainAccount: "huggingface"
4346
/// )
4447
/// let client = HubClient(tokenProvider: .oauth(manager: authManager))
4548
/// ```
@@ -117,13 +120,13 @@ public indirect enum TokenProvider: Sendable {
117120
/// the same token detection logic as the Hugging Face CLI.
118121
case environment
119122

120-
/// An OAuth token provider that uses HuggingFaceAuthenticationManager.
123+
/// An OAuth token provider that retrieves tokens asynchronously.
121124
///
122-
/// Use this case for OAuth-based authentication flows. The authentication
123-
/// manager handles the complete OAuth flow including token refresh.
125+
/// Use this case for OAuth-based authentication flows. Create instances using
126+
/// the `TokenProvider.oauth(manager:)` factory method when using `HuggingFaceAuthenticationManager`.
124127
///
125-
/// - Parameter manager: The OAuth authentication manager that handles token retrieval and refresh.
126-
case oauth(manager: HuggingFaceAuthenticationManager)
128+
/// - Parameter getToken: A closure that retrieves a valid OAuth token.
129+
case oauth(getToken: @Sendable () async throws -> String)
127130

128131
/// A composite token provider that tries multiple providers in order.
129132
///
@@ -185,7 +188,7 @@ public indirect enum TokenProvider: Sendable {
185188
case .environment:
186189
return try getTokenFromEnvironment()
187190

188-
case .oauth(let manager):
191+
case .oauth:
189192
fatalError(
190193
"OAuth token provider requires async context. Use getToken() in an async context or switch to a synchronous provider."
191194
)
@@ -209,6 +212,39 @@ public indirect enum TokenProvider: Sendable {
209212
}
210213
}
211214

215+
// MARK: - OAuth Factory
216+
217+
#if canImport(AuthenticationServices)
218+
import Observation
219+
220+
extension TokenProvider {
221+
/// Creates an OAuth token provider using HuggingFaceAuthenticationManager.
222+
///
223+
/// Use this factory method for OAuth-based authentication flows. The authentication
224+
/// manager handles the complete OAuth flow including token refresh.
225+
///
226+
/// ```swift
227+
/// let authManager = try HuggingFaceAuthenticationManager(
228+
/// clientID: "your-client-id",
229+
/// redirectURL: URL(string: "myapp://oauth")!,
230+
/// scope: .basic,
231+
/// keychainService: "com.example.app",
232+
/// keychainAccount: "huggingface"
233+
/// )
234+
/// let client = HubClient(tokenProvider: .oauth(manager: authManager))
235+
/// ```
236+
///
237+
/// - Parameter manager: The OAuth authentication manager that handles token retrieval and refresh.
238+
/// - Returns: A token provider that retrieves tokens from the authentication manager.
239+
@available(macOS 14.0, macCatalyst 17.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
240+
public static func oauth(manager: HuggingFaceAuthenticationManager) -> TokenProvider {
241+
return .oauth(getToken: { @MainActor in
242+
try await manager.getValidToken()
243+
})
244+
}
245+
}
246+
#endif
247+
212248
// MARK: - ExpressibleByStringLiteral & ExpressibleByStringInterpolation
213249

214250
extension TokenProvider: ExpressibleByStringLiteral, ExpressibleByStringInterpolation {

0 commit comments

Comments
 (0)