Skip to content

v0.14.0

Latest

Choose a tag to compare

@Dennis5882 Dennis5882 released this 26 Jul 08:15

Two releases' worth of work, published together. Read the breaking changes
first — one of them was destroying data.

⚠️ Breaking

DbResource.delete() was deleting the entire table

Node.delete([101]) removed every node, not node 101 — and with them every
element attached to those nodes. One call could empty a model. It has behaved
this way since the first commit, through 11 releases, and no mocked test could
have caught it: the request shape was exactly what the manual documents.

The manual's ID-keyed DELETE {endpoint} body is ignored by the server. The
undocumented per-id URL, DELETE {endpoint}/{id}, removes exactly one record.
delete() now uses it, issuing one request per id.

  • Return type changed: {id: response} instead of a single response body.
  • Deleting an id that doesn't exist is a harmless no-op, so no need to check first.
  • The old whole-table behaviour is still available, deliberately named:
    DbResource.delete_all().

If you have code that called delete() expecting a single record to go, it was
doing something much worse than you thought — and it needs no change now beyond
the return value.

Hyper-S (-M1) endpoints are Civil NX only

Hyper-S is the solver MIDASIT introduced with Civil NX. The SDK offered all 21
-M1 endpoints to Gen clients as well, where the best possible outcome was a
404 for the caller to interpret. Live testing: 13/13 implemented endpoints
answer under Civil NX 2026 and 404 under Gen NX 2026, as do all 8 unimplemented
stubs.

A Gen client now raises ProductMismatchError before issuing the request. Use
the new HYPER_S_ONLY constant in db/base.py — kept separate from
CIVIL_ONLY because Hyper-S is expected to reach Gen NX eventually, and that
day this should be one line to widen.

Fixed

  • doc.analyze() no longer reports a failed solve as success. The solver
    reports failure as {"message": "... Analysis failed."} — the same key a
    success uses for "... command complete", with no error object, so
    v0.12.0's client-level check could not see it. Every result table would
    otherwise come back empty with nothing pointing at the cause.

Added

  • DbResource.delete_all() — empty a table on purpose.
  • HYPER_S_ONLY in db/base.py.
  • scripts/live_readonly_sweep.py — GETs every endpoint the SDK wraps against
    a live session. Read-only, so it is safe against an open model.
  • scripts/live_crud_check.py — create → read → update → delete round trips,
    verifying the server echoes back what was written. This is what found the
    delete() bug.

Verification

Live-verified endpoints went from 10/390 to 295/390, across both products,
recorded per endpoint in docs/coverage.json. Gen and Civil each reproduced
their earlier sweep numbers exactly, on a real 710-node analyzed model rather
than a blank one.

Write paths now have round-trip coverage on 10 resources: Civil 10/10,
Gen 9/9
.

Live-server behaviour worth knowing

All of this is new in docs/live_verification_notes.md:

  • Every path in this API resolves on the machine running NX, which is often
    not the machine running your code. EXPORT_PATH, /doc/SAVEAS, /doc/OPEN,
    report and image paths all go there. A path that doesn't exist on that machine
    raises a modal dialog there and blocks the session, while the HTTP call
    still answers command complete. Build paths from
    verify_connection()["user"]; verify a write with /doc/OPEN, never
    os.path.exists().
  • /db/CONS's CONSTRAINT must be 7 characters. Six is rejected; eight is
    silently truncated to seven, giving you a support you never asked for.
  • /db/STLD ignores the "Assign" key and renumbers sequentially, while
    /db/NODE honours it. Code that writes a record and reads it back by the key
    it sent will miss for load cases.
  • Error bodies arrive under 201 as well as 200.
  • /doc/NEW and the *-ANAL design checks can kill the application, with a
    licence dialog that holds the licence until the process is restarted properly.
    Seven hypotheses were tested and eliminated — including reopening the exact
    model that crashed — so there is no precondition to check. Don't point them at
    a session holding work that isn't saved.

Compatibility

Python 3.9+, requests only. 637 tests, no live server needed.