|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +`cmem-plugin-graphql` is a [Corporate Memory (CMEM)](https://documentation.eccenca.com) plugin that executes GraphQL queries/mutations against an endpoint and saves results to a JSON dataset. It is generated from the [`eccenca/cmem-plugin-template`](https://github.com/eccenca/cmem-plugin-template). |
| 8 | + |
| 9 | +## Quick Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Install dependencies |
| 13 | +poetry install |
| 14 | + |
| 15 | +# Run all checks (linters + tests) |
| 16 | +task check |
| 17 | + |
| 18 | +# Run only unit tests (no CMEM server required) |
| 19 | +task check:pytest |
| 20 | + |
| 21 | +# Lint / format |
| 22 | +task check:ruff # lint only (non-fatal --exit-zero) |
| 23 | +task check:mypy # type checking |
| 24 | +task check:deptry # unused/missing deps |
| 25 | +task check:trivy # vulnerability scan |
| 26 | +task format:fix # auto-format + safe fixes |
| 27 | +task format:fix-unsafe # auto-format + unsafe fixes |
| 28 | + |
| 29 | +# Build distribution |
| 30 | +task build # poetry build + export requirements.txt |
| 31 | + |
| 32 | +# Install/uninstall plugin in a CMEM workspace |
| 33 | +task install # build + cmemc admin workspace python install |
| 34 | +task uninstall # cmemc admin workspace python uninstall |
| 35 | +``` |
| 36 | + |
| 37 | +Tests that require a live CMEM server are guarded with `@needs_cmem` (skips unless `CMEM_BASE_URI` is set). The lone non-CMEM test is `test_is_string_jinja_template` and `test_dummy`. |
| 38 | + |
| 39 | +## Architecture |
| 40 | + |
| 41 | +``` |
| 42 | +cmem_plugin_graphql/ |
| 43 | + __init__.py # package marker (empty) |
| 44 | + workflow/ |
| 45 | + graphql.py # GraphQLPlugin — the single WorkflowPlugin entry point |
| 46 | + utils.py # jinja template detection, entity/dict conversion helpers |
| 47 | +tests/ |
| 48 | + test_graphql.py # integration tests against a public test GraphQL endpoint |
| 49 | +``` |
| 50 | + |
| 51 | +### Key module: `workflow/graphql.py` |
| 52 | + |
| 53 | +- **`GraphQLPlugin`** — decorated with `@Plugin(...)` to register as a CMEM workflow task. Parameters: `graphql_url`, `graphql_query`, `graphql_variable_values`, `graphql_dataset` (optional), `oauth_access_token` (optional). |
| 54 | +- Query validation: detects Jinja templates via `is_jinja_template()` (renders and checks for substitution); otherwise validates as pure GraphQL syntax with `gql()`. |
| 55 | +- Variable values validation: detects Jinja templates or validates as JSON. |
| 56 | +- **`execute()`** branching logic: |
| 57 | + - If Jinja is detected in either query or variables → iterates over input `Entities`, renders per-entity, executes per entity via `process_entities()`. |
| 58 | + - Otherwise → single-shot execution against the endpoint with static variables. |
| 59 | +- Results are collected into a list; if `graphql_dataset` is set, payload is written to that CMEM dataset via `write_to_dataset()`. |
| 60 | + |
| 61 | +### Key module: `workflow/utils.py` |
| 62 | + |
| 63 | +- **`is_jinja_template(value)`** — renders through Jinja's `Environment`; if the rendered output differs from the input, Jinja variables were present. |
| 64 | +- **`get_dict(entities)`** — iterator that flattens `Entities` into per-entity dicts keyed by schema path. |
| 65 | +- **`get_entities_from_list(data)` / `create_entity(paths, dict_)`** — bidirectional helpers for converting between `list[dict]` and `Entities`. |
| 66 | + |
| 67 | +## Dependencies |
| 68 | + |
| 69 | +| Category | Key packages | |
| 70 | +|----------|-------------| |
| 71 | +| Runtime | `graphql-core`, `gql[all]`, `Jinja2`, `validators` | |
| 72 | +| CMEM base | `cmem-plugin-base ^4.19.0` (declared as a Poetry `[tool.poetry.dependencies.cmem-plugin-base]` extra) | |
| 73 | +| Dev | `ruff`, `mypy`, `deptry`, `trivy-py-ecc`, `pytest` + cov, html, memray, dotenv | |
| 74 | + |
| 75 | +Python version: **3.13** (pinned in `.python-version`). |
| 76 | + |
| 77 | +## CI/CD |
| 78 | + |
| 79 | +- `.github/workflows/check.yml` — runs mypy, ruff, pytest, deptry, trivy on PRs/pushes to `main`/`develop`. |
| 80 | +- `.github/workflows/publish.yml` — publishes to PyPI on tag push or manual dispatch. |
| 81 | +- Pre-commit hooks mirror the CI linters (ruff, poetry-check, poetry-lock) plus trivy. |
0 commit comments