Skip to main content

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eazydraw-1.0.2.tar.gz (35.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eazydraw-1.0.2-py3-none-any.whl (34.9 kB view details)

Uploaded Python 3

File details

Details for the file eazydraw-1.0.2.tar.gz.

File metadata

  • Download URL: eazydraw-1.0.2.tar.gz
  • Upload date:
  • Size: 35.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for eazydraw-1.0.2.tar.gz
Algorithm Hash digest
SHA256 c3bc0e455a837892fe42f016094cca5d03744104c31baf2e2386ac93c7825d6d
MD5 6e2feaf3e3547e92724b1755b038b07b
BLAKE2b-256 91901dd3c666e8b06dfeb378d0a1245f11975b22e78457ba0daae6acabceaaca

See more details on using hashes here.

File details

Details for the file eazydraw-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: eazydraw-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 34.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for eazydraw-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a264c6b5ff9542c88e5af2c749c8e19e0c1a3e3ccc1a25323f8b0177042a8009
MD5 06b5aab416edb73fde3355f0d9af286b
BLAKE2b-256 403a16da387c315021d7a8300460c9eae294105ee53549945560b2dc46b38ab4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page