Skip to main content

EazyDraw Automation API — Python client

Python wrapper around the HTTP API documented in ../../API.md and ../../spec/openapi.yaml. A developer tool, not (yet) a shipped SDK.

Packaged as the eazydraw module:

eazydraw/
  __init__.py    public exports (EazyDraw, EazyDrawError, models)
  client.py      the EazyDraw HTTP client (returns raw dicts)
  models.py      pydantic v2 models mirroring spec/openapi.yaml
eazydraw_api.py  backward-compat shim (re-exports from eazydraw)

Setup

pip install -r requirements.txt        # requests + pydantic (+ dev: pyyaml, openapi-spec-validator)
# or, to install the package itself (editable):  pip install -e .
cp config.example.py config.py
# edit config.py and paste your bearer token from API Settings -> Reveal

Python 3.10+. config.py is gitignored so your real token stays on your machine; config.example.py is the committed placeholder.

Transport: TCP or UNIX socket

The direct EazyDraw build serves the API on localhost:52737. The App Store build is sandboxed and serves the same API on a UNIX-domain socket in its container instead. Pass socket_path to use it (API Settings shows the path; DEFAULT_SOCKET is the App Store app's):

from eazydraw import EazyDraw, DEFAULT_SOCKET
ed = EazyDraw(token="...", socket_path=DEFAULT_SOCKET)

Everything else is identical. The script tests run over the socket with EAZYDRAW_SOCKET=<path> python test_smoke.py (see conftest.py).

Quickstart

from eazydraw import EazyDraw          # (the old `from eazydraw_api import EazyDraw` still works)

# Paste your bearer token from API Settings -> Reveal
ed = EazyDraw(token="7b3f...")

ed.status()
# {'status': 'OK', 'version': '12.3.6', 'build': '51059'}

# Open a drawing, capture its uuid
d = ed.open_drawing("~/Documents/sketch.ezdjson")
print(d["uuid"], "newly opened" if ed.last_response.status_code == 201 else "already open")

# Walk down to graphics on the active layer
layers = ed.layers(d["uuid"])
gs = ed.layer_graphics(d["uuid"], layers[0]["uuid"])
print(len(gs), "graphics on layer 0")

# Place a library element into the drawing
libs = ed.libraries()
math_lib = next(l for l in libs if l["DisplayName"] == "Math")
els = ed.library_elements(math_lib["uuid"])
graphic_el = next(e for e in els if e["elementType"] == "graphic")
placed = ed.use_library_element(
    d["uuid"], layers[0]["uuid"], math_lib["uuid"], graphic_el["uuid"]
)
print("Placed", placed["class"], "as", placed["graphicUUID"])

# Export the drawing as a PNG to disk
ed.export_drawing(d["uuid"], "png", save_to="/tmp/sketch.png")

# Close it
ed.close_drawing(d["uuid"])

Typed models (optional)

The client returns raw dicts. For validation / IDE support, parse them with the pydantic models in eazydraw.models (these mirror spec/openapi.yaml):

from eazydraw import EazyDraw, Graphic, Text

ed = EazyDraw(token="7b3f...")
g = Graphic.model_validate(ed.graphic(D, L, G))
print(g.graphic_uuid, g.hidden_bounds.width, g.is_group)   # snake_case fields

# round-trips back to wire form (camelCase / PascalCase keys)
g.model_dump(by_alias=True)

Field names are snake_case with the wire keys as aliases; unknown server keys are preserved (extra="allow"), so a newer server field won't break parsing.

Error handling

Non-2xx responses raise EazyDrawError(status_code, message, body):

from eazydraw import EazyDraw, EazyDrawError

ed = EazyDraw(token="wrong-token")
try:
    ed.status()
except EazyDrawError as exc:
    print(exc.status_code, exc.message)  # 401 "Missing or invalid bearer token"

Status codes

Every method calls self.last_response = resp, so when the server's status code carries semantic meaning (201 vs 200 on POST, etc.), inspect it afterward:

d = ed.open_drawing(path)
already_open = (ed.last_response.status_code == 200)

Conventions

  • Methods take UUIDs as positional strings, in path order: ed.layer(D, L), ed.layer_graphics(D, L), etc.
  • Recursive group-traversal methods take a variadic list of UUIDs in chain order: ed.group_graphics(D, L, G1, G2, G3) reads as "drilling down".
  • export_* methods take fmt as a keyword argument (so the call site stays readable when there's a long UUID chain) and accept an optional save_to path; if given, bytes are written to that path and the path is returned. Otherwise raw bytes are returned.
  • Collection endpoints unwrap the envelope: ed.drawings() returns the list directly, not {"drawings": [...]}.
  • client.py is single-class; as we add API endpoints we add a method — no inheritance, no abstractions. models.py is plain pydantic data classes.

Not shipped

This lives in the repo for convenience but is not part of the EazyDraw app bundle. A versioned, published Python SDK is a future product decision; the eazydraw package here is the working basis for it (and for the semantic resolver + MCP server layers to come).

Release files for eazydraw 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eazydraw 1.1.2
File Size Uploaded
eazydraw-1.1.2.tar.gz 56.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for eazydraw 1.1.2
File Interpreter ABI Platform
eazydraw-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 112.1 kB

Release files / eazydraw-1.1.2.tar.gz

Download URL eazydraw-1.1.2.tar.gz
Size 56.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e45ff7c49d3dcf2dbb1a6f9580a0f5faf96ad4f456b7856ab471035ccf62e853
BLAKE2b-256 checksum
How to use checksums
b3b1e2d67d7567e287ee70ab129cf3174b9f88bc68e0d8f3bbf2b7e11120d1c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / eazydraw-1.1.2-py3-none-any.whl

Download URL eazydraw-1.1.2-py3-none-any.whl
Size 55.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5af8bc76f36efe10ca4f0ab178385ff9f932ce57ad67b18970fdc917289ba157
BLAKE2b-256 checksum
How to use checksums
3418e02367e9030df8c5cfa1a7ff585f89da332cd0908065c3fbbd356d4bebe4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

1.2.0

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

This release

1.1.2 This release

2 release files

1.1.0

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page