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

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.4
File Size Uploaded
eazydraw-1.1.4.tar.gz 58.3 kB Details

Built distribution (wheel)

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

Total release size: 115.8 kB

Release files / eazydraw-1.1.4.tar.gz

Download URL eazydraw-1.1.4.tar.gz
Size 58.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5276ca472063abec521bc645ffceeb3385ac0fed13d791e08c5992e59a434b8f
BLAKE2b-256 checksum
How to use checksums
2f0b064b5cdf6e14e082cdd278f4693c2999325d03e9a88e4c0f49666e357c88
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.4-py3-none-any.whl

Download URL eazydraw-1.1.4-py3-none-any.whl
Size 57.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d086e5adf7f080b289ac7024ec4be96f497ab7288c093b2529fdb528b15936e
BLAKE2b-256 checksum
How to use checksums
0ed74a447f5da3224c2ef9fc611b7e8aab6365c099b1bb25f47c784b88c84477
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

This release

1.1.4 This release

2 release files

1.1.3

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