Skip to content

atacan/AnthropicAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AnthropicAPI

a Swift client for the Anthropic API, generated with swift-openapi-generator.

What You Get

  • Strongly typed request/response models from OpenAPI
  • Async client transport via OpenAPIAsyncHTTPClient
  • Built-in authentication middleware (x-api-key, anthropic-version, optional anthropic-beta)
  • Support for both JSON responses and SSE streaming (text/event-stream)

Requirements

  • Swift 5.9+
  • Supported platforms: macOS 14+, iOS 16+, tvOS 16+, watchOS 9+

Install

dependencies: [
    .package(url: "https://github.com/atacan/AnthropicAPI", branch: "main")
],
targets: [
    .target(
        name: "YourTarget",
        dependencies: [
            .product(name: "AnthropicAPI", package: "AnthropicAPI"),
            .product(name: "AnthropicAPITypes", package: "AnthropicAPI")
        ]
    )
]

Quick Start

import AnthropicAPI
import AnthropicAPITypes
import OpenAPIAsyncHTTPClient
import OpenAPIRuntime
import Foundation

let client = Client(
    serverURL: URL(string: "https://api.anthropic.com")!,
    transport: AsyncHTTPClientTransport(),
    middlewares: [
        AuthenticationMiddleware(apiKey: ProcessInfo.processInfo.environment["API_KEY"]!)
    ]
)

let response = try await client.messages_post(
    .init(
        body: .json(
            .init(
                model: .init(value1: Model.haiku4_5.alias ?? Model.haiku4_5.rawValue),
                messages: [
                    .init(
                        content: .init(value1: "Hello, Claude!"),
                        role: .user
                    )
                ],
                max_tokens: 256
            )
        )
    )
)

switch response {
case .ok(let ok):
    let message = try ok.body.json
    for block in message.content {
        if case .text(let text) = block {
            print(text.text)
        }
    }
case .clientError(let statusCode, let err):
    let errorBody = try err.body.json
    print("Client error \(statusCode): \(errorBody._type)")
case .undocumented(let statusCode, _):
    print("Undocumented response status: \(statusCode)")
}

Streaming Responses (SSE)

let response = try await client.messages_post(
    .init(
        body: .json(
            .init(
                model: .init(value1: Model.haiku4_5.alias ?? Model.haiku4_5.rawValue),
                messages: [
                    .init(content: .init(value1: "Say hello in exactly 3 words."), role: .user)
                ],
                max_tokens: 100,
                stream: true
            )
        )
    )
)

switch response {
case .ok(let ok):
    let stream = try ok.body.text_event_hyphen_stream
        .asDecodedServerSentEventsWithJSONData(of: Components.Schemas.MessageStreamEvent.self)

    for try await event in stream {
        guard let data = event.data else { continue }
        if case .content_block_delta(let delta) = data,
           case .text_delta(let textDelta) = delta.delta {
            print(textDelta.text, terminator: "")
        }
    }
case .clientError(let statusCode, _):
    print("Client error: \(statusCode)")
case .undocumented(let statusCode, _):
    print("Undocumented response: \(statusCode)")
}

Tool Use Pattern

Tool use is a multi-step flow:

  1. Send tools and tool_choice in the request.
  2. Read tool_use blocks from the model response.
  3. Execute your local tool.
  4. Send a follow-up message with a tool_result block.

End-to-end examples are in:

  • Tests/AnthropicAPITests/AnthropicAPITests.swift

Authentication Middleware

AuthenticationMiddleware sets:

  • x-api-key (required)
  • anthropic-version (default: 2023-06-01)
  • anthropic-beta (optional list)

Example:

let middleware = AuthenticationMiddleware(
    apiKey: "...",
    anthropicVersion: .v2023_06_01,
    anthropicBeta: [.interleavedThinking2025_05_14]
)

Model Selection

Use Model from AnthropicAPITypes instead of hardcoded strings:

let versioned = Model.sonnet4_5.rawValue           // fixed snapshot
let alias = Model.sonnet4_5.alias                  // moving alias, optional
let recommended = Model.current                     // current models
let legacy = Model.legacy                           // older models

For production stability, prefer rawValue (versioned model ID).

Run Tests Locally

Create .env in the repository root:

API_KEY=your-anthropic-api-key
# Optional
BASE_URL=https://api.anthropic.com

Then run:

swift test

Project Structure

  • Sources/AnthropicAPITypes/GeneratedSources/: generated schema/types
  • Sources/AnthropicAPI/GeneratedSources/: generated client operations
  • Sources/AnthropicAPITypes/AuthenticationMiddleware.swift: custom auth middleware
  • Tests/AnthropicAPITests/AnthropicAPITests.swift: real integration-style usage examples

Do not edit files under GeneratedSources/ directly.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors