Skip to content

Add SQL resource for TagoSQL stored queries - #65

Merged
FabianoEger merged 6 commits into
mainfrom
feat/tagosql-sql-resource
Jul 23, 2026
Merged

Add SQL resource for TagoSQL stored queries#65
FabianoEger merged 6 commits into
mainfrom
feat/tagosql-sql-resource

Conversation

@FabianoEger

@FabianoEger FabianoEger commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

TagoSQL shipped in server v10.3.0 with no SDK coverage, so applications and analyses had to call the /sql routes with raw requests. This adds a sql resource to Resources covering stored-query CRUD (list, create, info, edit, delete), version snapshots (getVersion), execution (execute with per-key param overrides and test mode), and schema discovery (tables). The legacy /sql/eval endpoint and the removed ad-hoc POST /sql/execute route (tago-io/server#1688) are intentionally not covered.

Stored-query info/list responses now expose a read-only, server-derived session_context boolean (true when the query text uses session functions; never accepted as input), and the tables catalog gains a functions array (SQLFunctionInfo: name, kind, args, description, and example on session entries) listing everything callable in a query (tago-io/server#1690).

Test plan

  • Pytest: tests/Resources/test_sql.py (requests-mock round trips for all methods)
  • uv run pytest tests/ passes (209 tests) and uv run ruff check is clean on the new files
  • Method signatures and wire shapes verified against the server contract in docs/TagoSQL.md (params as [{key, value}] arrays, execute envelope with served_from_cache, list fields allowlist); the tables substring filter is sent on the path because the shared doRequest expands object filters into filter[...] pairs

Risk (CIA)

Likelihood: 🟢 Low | Impact: 🟢 Low | Exposure: 🟢 Low

@felipefdl felipefdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block
Version bump is incomplete, and a few type/test edges should be fixed before merge.

In this PR

Solid additive SQL resource: routes, wire shapes, Cache clears, and date parsing match sibling Resources modules. Intentional omission of /sql/eval and ad-hoc POST /sql/execute is clean on the head.

Blockers

  • pyproject.toml:7 / uv.lock: project version is 5.1.4 in pyproject.toml but uv.lock still records 5.1.3. Prior release commits (for example 74e69fe) always bump both. Regenerate and commit uv.lock with the version bump.

Questions

  • pyproject.toml:7: this is a net-new public Resources.sql surface. Pure semver would be a minor (5.2.0). Is patch (5.1.4) intentional for this repo's release habit?
  • PR description (ad-hoc execute): body cites server#1688 as removing POST /sql/execute. Confirm that removal is shipped or queued so omitting an ad-hoc SDK method is the long-term contract, not premature.

Improvements

  • src/tagoio_sdk/modules/Resources/SQL_Types.py:20: SQLCreateInfo is total=False, so type checkers accept create({}) even though the server requires name and query on create/replace. Prefer required name/query (Secrets uses required fields on create; optional only on edit).
  • src/tagoio_sdk/modules/Resources/SQL_Types.py:59: filter: Optional[SQLInfo] is wider than the list filter (name / active / tags). A dedicated SQLFilter TypedDict (like SecretsFilter) would match the wire contract.
  • src/tagoio_sdk/modules/Resources/SQL_Types.py:32: SQLInfo omits response fields the server returns on create/info/edit (cache_version, versions if present on the live contract). Worth surfacing if clients need them.
  • src/tagoio_sdk/modules/Resources/SQL.py:48: if orderBy is present but None or short, indexing raises before the request. Guard for a real two-item pair (same footgun as other list helpers, still worth tightening here).
  • src/tagoio_sdk/modules/Resources/SQL.py:246: tables({"filter": None}) emits filter=None on the path instead of omitting the key. Only append when the value is a non-empty string.
  • tests/Resources/test_sql.py:129: tables({"filter": "sensor"}) never asserts the request URL/query includes filter=sensor, so a regression that drops the path workaround still passes. Assert the request.
  • docs/source/Resources/index.rst: no Sphinx toctree entry for SQL. Other Resources modules are listed; py.sdk.tago.io will not show this surface until docs are added.

Praise

  • Paths, verbs, [{key, value}] params, execute envelope (served_from_cache), and tables filter-on-path workaround all line up with the shared doRequest filter expansion behavior.
  • Mutating methods call Cache.clear_cache(); list/info/version use dateParser / dateParserList consistently with Devices/Dashboards.
  • Tests cover every public method with the right HTTP verbs and paths.

Risk (CIA)

Likelihood: 🟢 Low | Impact: 🟢 Low | Exposure: 🟢 Low.
Confirmed. Additive SDK client only; no auth or crypto changes. Residual risk is incomplete release bookkeeping and unasserted tables-filter wire shape, not production breakage.

@FabianoEger
FabianoEger requested a review from felipefdl July 23, 2026 17:21
Address review on PR #65:
- sync uv.lock tagoio-sdk version to 5.1.4 (matches pyproject)
- SQLCreateInfo requires name and query on create/replace; other fields optional
- SQLInfo becomes a standalone total=False response type; add cache_version and versions
- add dedicated SQLFilter (name/active/tags) for the list filter
- guard orderBy to a real two-item pair before building the string
- tables() only appends filter to the path for a non-empty string; None omits the key
- assert the tables request URL carries filter=sensor and add a None-filter omission test

Claude-Session: https://claude.ai/code/session_018B8uKfmuuoBf9p3z3GRfcN
Add docs/source/Resources/SQL index and type reference mirroring the
Secrets module, and register it in the Resources toctree so the surface
shows on py.sdk.tago.io.

Claude-Session: https://claude.ai/code/session_018B8uKfmuuoBf9p3z3GRfcN
@FabianoEger

Copy link
Copy Markdown
Member Author

All findings addressed in 1989cd6 and 152ebfb:

Blocker: uv.lock now records 5.1.4. The regen was done as a minimal version-only edit matching the prior bump pattern (74e69fe); a locally-generated lock had unrelated revision churn from a newer uv and was discarded.

Questions answered:

  • Patch vs minor: keeping 5.1.4 intentionally. This repo ships net-new public surface as patch bumps: v5.1.0 -> v5.1.1 added the entire Dashboard_Widgets Resources module (~6,900 lines of new methods) as a patch. Patch is the established habit.
  • Ad-hoc execute: server#1688 is merged on main, so POST /sql/execute is gone from the API permanently and queries must be stored to run. Omitting an ad-hoc SDK method is the long-term contract, not premature.

Improvements, all applied:

  • SQLCreateInfo now requires name and query (Secrets pattern); optional only on edit.
  • Dedicated SQLFilter TypedDict (name / active / tags). One deliberate deviation: it is total=False (all filter keys optional) rather than SecretsFilter's total=True, since a partial filter is the wire reality; say the word if strict parity is preferred.
  • SQLInfo gains cache_version and versions per the live contract.
  • orderBy only builds from a real two-item pair; malformed input is omitted instead of raising.
  • tables omits the filter key unless the value is a non-empty string.
  • The tables test now asserts the request URL contains filter=sensor.
  • Sphinx toctree entry added; sphinx-build exits 0 with no warnings on the SQL pages.

Gates: ruff clean on the changed files, 209 tests passing (TZ=UTC). Ready for re-review.

@FabianoEger
FabianoEger merged commit 52baa91 into main Jul 23, 2026
6 checks passed
@FabianoEger
FabianoEger deleted the feat/tagosql-sql-resource branch July 23, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants