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.3

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.3
File Size Uploaded
eazydraw-1.1.3.tar.gz 57.7 kB Details

Built distribution (wheel)

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

Total release size: 114.6 kB

Release files / eazydraw-1.1.3.tar.gz

Download URL eazydraw-1.1.3.tar.gz
Size 57.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ead100c6f6e5ea0f3fcdf958e328dac937f1d38e48a734a58fdb87b27885776a
BLAKE2b-256 checksum
How to use checksums
ded8b6d3e966e0003e323c41de854c6f9844e2f443491f1ed7771e79fe32f220
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.3-py3-none-any.whl

Download URL eazydraw-1.1.3-py3-none-any.whl
Size 56.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f34633700031bc6353c244315896ae180cf3de652b00178e10a9053fbce1ab27
BLAKE2b-256 checksum
How to use checksums
2a1d038708a1b01a41418a6134aa0245c361adab34900cbae8b8407f686699f6
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

This release

1.1.3 This release

2 release files

1.1.2

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