Provider: iCloud Photos #13

Open
opened 2026-03-27 21:56:52 +00:00 by antialias · 0 comments
Owner

iCloud Photos provider for accessing Apple Photos library.

The Hard Truth

Apple provides no official API for iCloud Photos. There are three approaches, each with significant tradeoffs:

Option A: pyicloud (unofficial reverse-engineered API)

{
  "apple_id": { "type": "string", "required": true },
  "password": { "type": "string", "secret": true },
  "album": { "type": "string", "description": "Album name (empty = all)" }
}

Pros: Full access to the photo library including albums, metadata, and full-res downloads.

Cons:

  • Uses undocumented Apple endpoints — breaks every few months when Apple changes their API
  • Requires 2FA code entry on first auth and periodically thereafter (session expires)
  • Apple may flag/lock accounts that use unofficial API access
  • pyicloud library maintenance is spotty
  • Session cookies expire, requiring re-authentication via the web UI

Implementation:

  • pyicloud.PyiCloudService(apple_id, password) for auth
  • service.photos.albums to list albums
  • Album iteration yields photo assets with download URLs
  • 2FA flow needs a web UI modal: "Enter the code sent to your devices"

Option B: iCloud Shared Albums (public RSS)

If the user creates a public iCloud Shared Album, Apple generates an RSS feed and hosted thumbnails.

Pros: No auth needed, no unofficial API, stable.

Cons: Only works with Shared Albums (not the main library). User must manually add photos to the shared album. Limited metadata.

Implementation:

  • Parse the shared album's public URL → extract album token
  • Fetch https://p{xx}-sharedstreams.icloud.com/{token}/sharedstreams/webstream API
  • Returns photo metadata + CDN URLs for various sizes

Not really a "provider" — the user manually pushes photos from their phone via the Share Sheet shortcut. Photos land in the local provider. No pull-based sync.

Pros: Most reliable, no API breakage, works with any photo.

Cons: Manual, not a real provider integration.

Recommendation

Implement Option A (pyicloud) as the provider, with clear warnings in the UI:

  • "This uses an unofficial Apple API and may require re-authentication periodically"
  • "Consider using the iOS Shortcut (see Settings) for a more reliable experience"

Implement Option B (Shared Albums) as a separate lightweight provider if there's demand.

Continue recommending Option C (iOS Shortcut + local provider) as the most reliable path.

Dependencies

  • pyicloud added to requirements.txt

2FA Flow

The web UI needs a special flow for iCloud:

  1. User enters Apple ID + password
  2. Server calls pyicloud.PyiCloudService()
  3. If 2FA required, server returns {"status": "2fa_required", "devices": [...]}
  4. Web UI shows a modal: "Enter the 6-digit code sent to your devices"
  5. User enters code, POST to /api/providers/{id}/2fa
  6. Server calls service.validate_2fa_code(code)
  7. Session cookies stored for future use

Depends on #9 (core architecture).

iCloud Photos provider for accessing Apple Photos library. ## The Hard Truth Apple provides **no official API** for iCloud Photos. There are three approaches, each with significant tradeoffs: ### Option A: `pyicloud` (unofficial reverse-engineered API) ```json { "apple_id": { "type": "string", "required": true }, "password": { "type": "string", "secret": true }, "album": { "type": "string", "description": "Album name (empty = all)" } } ``` **Pros:** Full access to the photo library including albums, metadata, and full-res downloads. **Cons:** - Uses undocumented Apple endpoints — **breaks every few months** when Apple changes their API - Requires 2FA code entry on first auth and periodically thereafter (session expires) - Apple may flag/lock accounts that use unofficial API access - `pyicloud` library maintenance is spotty - Session cookies expire, requiring re-authentication via the web UI **Implementation:** - `pyicloud.PyiCloudService(apple_id, password)` for auth - `service.photos.albums` to list albums - Album iteration yields photo assets with download URLs - 2FA flow needs a web UI modal: "Enter the code sent to your devices" ### Option B: iCloud Shared Albums (public RSS) If the user creates a **public iCloud Shared Album**, Apple generates an RSS feed and hosted thumbnails. **Pros:** No auth needed, no unofficial API, stable. **Cons:** Only works with Shared Albums (not the main library). User must manually add photos to the shared album. Limited metadata. **Implementation:** - Parse the shared album's public URL → extract album token - Fetch `https://p{xx}-sharedstreams.icloud.com/{token}/sharedstreams/webstream` API - Returns photo metadata + CDN URLs for various sizes ### Option C: iOS Shortcut bridge (recommended in #6) Not really a "provider" — the user manually pushes photos from their phone via the Share Sheet shortcut. Photos land in the local provider. No pull-based sync. **Pros:** Most reliable, no API breakage, works with any photo. **Cons:** Manual, not a real provider integration. ## Recommendation Implement **Option A** (`pyicloud`) as the provider, with clear warnings in the UI: - "This uses an unofficial Apple API and may require re-authentication periodically" - "Consider using the iOS Shortcut (see Settings) for a more reliable experience" Implement **Option B** (Shared Albums) as a separate lightweight provider if there's demand. Continue recommending **Option C** (iOS Shortcut + local provider) as the most reliable path. ## Dependencies - `pyicloud` added to `requirements.txt` ## 2FA Flow The web UI needs a special flow for iCloud: 1. User enters Apple ID + password 2. Server calls `pyicloud.PyiCloudService()` 3. If 2FA required, server returns `{"status": "2fa_required", "devices": [...]}` 4. Web UI shows a modal: "Enter the 6-digit code sent to your devices" 5. User enters code, POST to `/api/providers/{id}/2fa` 6. Server calls `service.validate_2fa_code(code)` 7. Session cookies stored for future use Depends on #9 (core architecture).
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: antialias/eink-photo-frame#13