Skip to content

DesignPipe/swift-penpot-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

swift-penpot-api

CI License: MIT

A Swift client for the Penpot RPC API with async/await, automatic retry with exponential backoff, and SVG shape reconstruction.

Features

  • Penpot RPC API client (get-file, get-profile, get-file-object-thumbnails)
  • Automatic retry with exponential backoff (429/5xx)
  • SVG reconstruction from shape trees (path, rect, circle, group, frame, bool)
  • Component thumbnail downloads via presigned URLs
  • Swift 6 strict concurrency
  • Linux compatible

Requirements

  • Swift 6.1+
  • macOS 13+ / Linux (Ubuntu 22.04+)

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/DesignPipe/swift-penpot-api.git", from: "0.1.0"),
]

Then add PenpotAPI to your target dependencies:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "PenpotAPI", package: "swift-penpot-api"),
    ]
)

Usage

import PenpotAPI

// Create a client
let client = BasePenpotClient(
    accessToken: "your-penpot-token",
    baseURL: "https://design.penpot.app/"
)

// Fetch a file with colors, typographies, and components
let file = try await client.request(GetFileEndpoint(fileId: "file-uuid"))

// Access colors
for (_, color) in (file.data.colors ?? [:]).sorted(by: { $0.key < $1.key }) {
    print("\(color.name): \(color.color ?? "gradient")")
}

// Access typographies
for (_, typo) in (file.data.typographies ?? [:]).sorted(by: { $0.key < $1.key }) {
    print("\(typo.name): \(typo.fontFamily) \(typo.fontSize)")
}

// Render component SVG from shape tree
if let page = file.data.pagesIndex?[component.mainInstancePage ?? ""],
   let objects = page.objects {
    let svg = PenpotShapeRenderer.renderSVG(objects: objects, rootId: component.mainInstanceId ?? "")
}

// Download component thumbnail
let data = try await client.download(path: "assets/by-id/\(thumbnailId)")

// Get current user profile
let profile = try await client.request(GetProfileEndpoint())

Architecture

  • PenpotEndpoint protocol — RPC-style: POST /api/main/methods/<commandName>
  • PenpotClient protocol + BasePenpotClient — URLSession, auth, retry
  • PenpotAPIError — LocalizedError with recovery suggestions
  • PenpotShapeRenderer — SVG reconstruction from Penpot's shape tree

API Path

Two equivalent paths exist:

  • /api/main/methods/<name> — used by this library; works with URLSession against design.penpot.app
  • /api/rpc/command/<name> — official docs path; blocked by Cloudflare JS challenge on design.penpot.app

Self-hosted Penpot instances (without Cloudflare) accept both paths.

License

MIT

About

A Swift client for the Penpot RPC API with async/await, retry, and SVG reconstruction

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages