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

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.0
File Size Uploaded
eazydraw-1.1.0.tar.gz 54.7 kB Details

Built distribution (wheel)

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

Total release size: 108.6 kB

Release files / eazydraw-1.1.0.tar.gz

Download URL eazydraw-1.1.0.tar.gz
Size 54.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5c8332dcf104806ff8e0f9fed344e456f422293479c728f1d27494934d90ead3
BLAKE2b-256 checksum
How to use checksums
f2c870deae1f5cc502814fbdc49b0af3cee48d88585799472da5777a71133e98
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.0-py3-none-any.whl

Download URL eazydraw-1.1.0-py3-none-any.whl
Size 53.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef873c717acae02fe18154022f72b7fe4bcbcaee5b46ec2a231390902bf82e1c
BLAKE2b-256 checksum
How to use checksums
a649fc4a60de7a7554b002473e04286e2b6557d2bf0aaf4c98157695d9a96b17
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

1.1.2

2 release files

This release

1.1.0 This release

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