Python client and MCP server for the EazyDraw Automation API
Project description
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.
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 takefmtas a keyword argument (so the call site stays readable when there's a long UUID chain) and accept an optionalsave_topath; 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.pyis single-class; as we add API endpoints we add a method — no inheritance, no abstractions.models.pyis 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).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eazydraw-1.0.0.tar.gz.
File metadata
- Download URL: eazydraw-1.0.0.tar.gz
- Upload date:
- Size: 28.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2196adfc6212653bc08ef6e6a977bb9a27c8ae8d2eac1a5b6666e9681d54368b
|
|
| MD5 |
7de6112454fd91622bf96bee192bb703
|
|
| BLAKE2b-256 |
e30722fd05d18c61cda99696437158389576dcd9f5bbfa6c73243248f30b8e12
|
File details
Details for the file eazydraw-1.0.0-py3-none-any.whl.
File metadata
- Download URL: eazydraw-1.0.0-py3-none-any.whl
- Upload date:
- Size: 28.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6109d112d877b77e25aee8c55f9939886c32d3ffa2a64e8f2e21d73b4c0f888
|
|
| MD5 |
0aacaa8c8e8fe1ab8b9c326b3fc1e706
|
|
| BLAKE2b-256 |
f4a34fe4891046fdf85547ce7e6417f85f809f3884ac976dddc11215399722a7
|