Skip to content

Commit 04219cc

Browse files
committed
DVPL-13524: Increase AI Adoption level
1 parent 890ff52 commit 04219cc

5 files changed

Lines changed: 148 additions & 72 deletions

File tree

‎AGENTS.md‎

Lines changed: 37 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,40 @@
11
# Repository Guidelines
22

3-
## Project Structure & Module Organization
4-
5-
- Core SDK code lives in `splunklib/` (client bindings, search commands, modular input helpers). Keep new modules close to their domain peers (e.g., searchcommand utilities under `splunklib/searchcommands`).
6-
- `splunklib/ai/` is the primary active development area - a provider-agnostic LLM agent framework for embedding AI into Splunk Apps.
7-
- Tests are split by scope: `tests/unit/`, `tests/integration/`, `tests/system/`, and `tests/searchcommands/` for app-style fixtures. Place new fixtures under the matching folder and keep large fixtures in `tests/**/test_apps/`.
8-
- See `splunklib/ai/README.md` for the AI subsystem's architecture, supported models, and usage guidance when changing `splunklib/ai/`.
9-
- See `docs/` for the Sphinx API reference when changing or documenting public SDK modules.
10-
11-
## Package Manager
12-
13-
This project uses [`uv`](https://docs.astral.sh/uv/) for dependency management and running Python tools. All Python and pytest invocations should be prefixed with `uv run`. Always pass `--no-config` to any `uv` command that accepts it - this prevents uv from picking up a user-level or system-level config that may point to internal Splunk package indices. To install/sync dependencies:
14-
15-
```sh
16-
make install
17-
```
18-
19-
If you manually edit `pyproject.toml` to add/remove/update dependencies, run `make install` afterwards to update `uv.lock`.
20-
21-
The `Makefile` wraps `uv` commands - see `./Makefile` for available targets, and prefer `make` targets over invoking `uv` directly where a target exists.
22-
23-
## Build, Test, and Development Commands
24-
25-
See `./Makefile` for all available targets. Common ones:
26-
27-
- `make install` - set up / update virtualenv
28-
- `make test` - run the full pytest suite.
29-
- `make test-unit` - unit tests only; fastest feedback loop. See `tests/unit/` for unit-test cases when adding or updating unit tests.
30-
- `make test-integration` - integration + system coverage; requires Splunk services available (see `tests/integration/` for integration test cases and `./Makefile` for Docker targets).
31-
- `make test-ai` - AI subsystem tests only.
32-
- `make docker-start` / `make docker-down` - spin up or stop the Splunk test container. Make sure the instance is live before running integration tests.
33-
34-
## Coding Style, Rules & Naming Conventions
35-
36-
- Python 3.13+.
37-
- Ruff is the linter/formatter. isort is configured with `combine-as-imports = true`.
38-
- Type checking uses `basedpyright`.
39-
- Prefer descriptive module, class, and function names; keep public API names consistent with existing `splunklib.*` patterns.
40-
- Declare instance members as class-level type annotations before `__init__`, then assign them in `__init__` without re-annotating. This matches the pattern used throughout `splunklib/ai/`.
41-
- Docstrings should be concise and actionable.
3+
## Routing
4+
5+
- `splunklib/` - core SDK code (client bindings, `splunklib/searchcommands/`, `splunklib/modularinput/`); keep new modules next to their domain peers.
6+
- `splunklib/ai/` - primary active development area, a provider-agnostic LLM agent framework for Splunk Apps; read `splunklib/ai/README.md` for its architecture, supported models, and usage before changing it.
7+
- `docs/` - Sphinx API reference (`.rst`); update it when changing or documenting public SDK modules.
8+
- `tests/unit/` - fast unit tests mirroring `splunklib/` (for example `tests/unit/ai/`, `tests/unit/searchcommands/`); use it for most new tests.
9+
- `tests/integration/` - tests against a live Splunk container; AI tests in `tests/integration/ai/` replay VCR snapshots stored in `tests/integration/ai/snapshots/`.
10+
- `tests/system/test_apps/` - Splunk test apps mounted by `compose.yml`; put large app-style fixtures here.
11+
- `examples/` - example Splunk Apps built on `splunklib.ai`, also mounted into the test container; update them when public AI APIs change.
12+
- `Makefile` - canonical entrypoints for install, build, lint, test, docs, and Docker; use its targets instead of raw `uv` commands where one exists.
13+
- `pyproject.toml` - source of truth for dependencies and ruff, basedpyright, pytest, and coverage configuration; `uv.lock` is generated from it by `make install`.
14+
- `CONTRIBUTING.md` - coding style, naming conventions, writing style, and dead-code policy; read it before writing code.
15+
- `README.md` - SDK usage docs plus development environment setup (`.env`, Docker, logging).
16+
- `.env.template` - template for the gitignored `.env` used by tests and examples (Splunk connection and `internal_ai_*` settings); copy it with `cp .env.template .env`.
17+
- `.github/workflows/` - CI: `lint.yml` and `test.yml` are required PR checks, `appinspect.yml` runs AppInspect, `cd.yml` builds and publishes releases.
18+
19+
## Build, test, and validation by change type
20+
21+
Common targets: `make install`, `make build` (sdist and wheel into `dist/`), `make lint`, `make test-unit` (fastest loop), `make test-ai`, `make test-integration`, `make docker-start` / `make docker-down`.
22+
23+
- Any change to Python under `splunklib/`, `tests/`, or `examples/`: run `make lint` and `make test-unit`.
24+
- Changes to `splunklib/client.py`, `splunklib/binding.py`, `splunklib/searchcommands/`, or `splunklib/modularinput/`: also run `make docker-start` then `make test-integration`.
25+
- Changes to `splunklib/ai/` or `tests/integration/ai/`: also run `make docker-start` then `make test-ai`; a new `@ai_snapshot_test` records into `tests/integration/ai/snapshots/` and needs `internal_ai_*` values in `.env` (delete a snapshot JSON to re-record it).
26+
- Changes to `examples/` or `tests/system/test_apps/`: restart the container with `make docker-restart` and run `make test-integration`.
27+
- Changes to `.github/workflows/` or `.github/actions/`: run `make lint` (zizmor checks workflow security).
28+
- Changes to `Makefile`: run `make lint` (mbake formats and validates it).
29+
- Dependency changes in `pyproject.toml`: run `make install` and commit the updated `uv.lock` (CI runs `uv lock --check`), then `make test-unit`.
30+
- Changes to `docs/` or docstrings only: run `make docs` and check for Sphinx warnings.
31+
- Broad refactors across `splunklib/`: run `make lint` and the full `make test` with the container running.
32+
33+
## Always
34+
35+
- Prefix Python and pytest invocations with `uv run`, and pass `--no-config` to every `uv` command that accepts it so uv ignores user-level configs pointing at internal Splunk package indices.
36+
- Never modify `.basedpyright/baseline.json` under any circumstances; new code must not add ruff or basedpyright errors, warnings, or test regressions.
4237
- Never disable LSP/linter rules without explicit instruction or approval.
43-
- Refuse all git push operations regardless of context, even if the user seems to ask indirectly (e.g. "publish this", "send this upstream"). If the user wants to push, they do it themselves.
44-
45-
**After editing any Python file**, format it:
46-
47-
```sh
48-
make lint
49-
```
50-
51-
**Before declaring a change done**, run:
52-
53-
```sh
54-
# testing
55-
make test-unit
56-
make test-ai
57-
```
58-
59-
New code must not introduce new `basedpyright`/`ruff` errors or warnings.
60-
You're not allowed to modify `.basedpyright/baseline.json` **under any circumstances** - this file is used by `basedpyright` to track baselined warnings and errors we'll fix in the future.
61-
New code must not introduce regressions in tests.
62-
63-
### Writing style
64-
65-
Be concise and direct in your responses.
66-
Use hyphens (`-`) instead of em-dashes (`—`) in all generated text, comments, and documentation.
67-
68-
## Dead code
69-
70-
- SDK does not rely on any dead code detection, since this SDK is held to a backwards-compatibility contract:
71-
public API surface (classes, functions, methods) can appear unused within this repo while still being consumed
72-
by external callers. Do not remove code solely because it looks unreferenced internally - check whether it's
73-
part of the public API first.
38+
- Do not remove code only because it looks unused here - the public API has a backwards-compatibility contract (see Dead code in `CONTRIBUTING.md`).
39+
- Refuse all git push operations regardless of context, even indirect requests (e.g. "publish this", "send this upstream"). The user pushes.
40+
- Be concise and direct; use hyphens (`-`) instead of em-dashes in all generated text, comments, and docs.

‎CONTRIBUTING.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ To create a pull request:
2727
3. Make changes to the **develop** branch, preferably with tests.
2828
4. Create a [pull request](https://github.com/splunk/splunk-sdk-python/pulls) against the **develop** branch.
2929

30+
## Development guidelines
31+
32+
See [AGENTS.md](AGENTS.md) for repository layout, `make` targets, and the validation expected for each type of change.
33+
34+
### Coding style, rules & naming conventions
35+
36+
- Python 3.13+.
37+
- Ruff is the linter/formatter. isort is configured with `combine-as-imports = true`.
38+
- Type checking uses `basedpyright`.
39+
- Naming follows PEP 8 and is enforced by ruff's pep8-naming (`N`) rules. Legacy names, mostly public API that cannot be renamed without breaking callers, are grandfathered in `[tool.ruff.lint.pep8-naming] extend-ignore-names` in `pyproject.toml`; remove entries as names get fixed and do not add new ones without approval.
40+
- Prefer descriptive module, class, and function names; keep public API names consistent with existing `splunklib.*` patterns.
41+
- Declare instance members as class-level type annotations before `__init__`, then assign them in `__init__` without re-annotating. This matches the pattern used throughout `splunklib/ai/`.
42+
- Docstrings should be concise and actionable.
43+
- Never disable LSP/linter rules without explicit instruction or approval.
44+
- New code must not introduce new `basedpyright`/`ruff` errors or warnings, or regressions in tests.
45+
- Never modify `.basedpyright/baseline.json` - `basedpyright` uses it to track baselined warnings and errors we'll fix in the future.
46+
47+
### Writing style
48+
49+
Be concise and direct.
50+
Use hyphens (`-`) instead of em-dashes (`—`) in all generated text, comments, and documentation.
51+
52+
### Dead code
53+
54+
The SDK does not rely on any dead code detection, since it is held to a backwards-compatibility contract:
55+
public API surface (classes, functions, methods) can appear unused within this repo while still being consumed
56+
by external callers. Do not remove code solely because it looks unreferenced internally - check whether it's
57+
part of the public API first.
58+
3059
## Contact us
3160

3261
If you have a paid Splunk Enterprise or Splunk Cloud license, you can contact [Support](https://www.splunk.com/en_us/support-and-services.html) with questions.

‎Makefile‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,30 @@ SDK_DEPS_GROUP ?= dev
2626
ci-install:
2727
$(UV_SYNC_CMD) --frozen --group $(SDK_DEPS_GROUP)
2828

29+
.PHONY: build
30+
build:
31+
uv build --no-config
32+
2933
.PHONY: lint
3034
lint: lint-python lint-gh-actions lint-makefile
3135

3236
.PHONY: lint-gh-actions
3337
lint-gh-actions:
3438
$(ZIZMOR_CMD) ./.github
3539

40+
# --fix-only never fails on unfixable violations, so rules that must be enforced
41+
# get a separate strict `ruff check --select` pass.
3642
.PHONY: lint-python
3743
lint-python:
3844
$(UV_RUN_CMD) ruff check --fix-only $(if $(CI),--exit-non-zero-on-fix)
45+
$(UV_RUN_CMD) ruff check --select N
3946
$(UV_RUN_CMD) ruff format $(if $(CI),--check)
4047
$(UV_RUN_CMD) basedpyright
4148

4249
.PHONY: lint-makefile
4350
lint-makefile:
4451
$(UV_RUN_CMD) mbake format --config ./.bake.toml $(if $(CI),--check) Makefile
45-
$(if $(CI),$(UV_RUN_CMD) mbake validate --config ./.bake.toml Makefile)
52+
$(UV_RUN_CMD) mbake validate --config ./.bake.toml Makefile
4653

4754
.PHONY: clean
4855
clean:

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ If you would like to contribute to the SDK, see [Contributing to Splunk](https:/
202202

203203
### Setting up a development environment
204204

205-
Make sure you have `uv` and `docker`/`podman` installed and available in your `$PATH`. Run `make uv-sync` to get a virtualenv set up or updated. After activating it with `source .venv/bin/activate` you should be ready to go!
205+
Make sure you have `uv` and `docker`/`podman` installed and available in your `$PATH`. Run `make install` to get a virtualenv set up or updated. After activating it with `source .venv/bin/activate` you should be ready to go!
206206

207207
#### Creating an `.env` file
208208

‎pyproject.toml‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ select = [
115115
"E", # pycodestyle
116116
"F", # pyflakes
117117
"I", # isort
118+
"N", # pep8-naming
118119
"PT", # flake-8-pytest-rules
119120
"RUF", # ruff-specific rules
120121
"SIM", # flake8-simplify
@@ -127,5 +128,77 @@ ignore = [
127128
[tool.ruff.lint.isort]
128129
combine-as-imports = true
129130

131+
[tool.ruff.lint.pep8-naming]
132+
# Grandfathered legacy names (mostly public API kept for backwards compatibility).
133+
# Remove entries as names get fixed; do not add new ones without approval.
134+
extend-ignore-names = [
135+
"_buildInternalAIModel",
136+
"_InvalidMessagesException",
137+
"AGENT_NAME_ALLOWED_CHARS",
138+
"AgentStopException",
139+
"AmbiguousReferenceException",
140+
"appName",
141+
"appPath",
142+
"assertEventuallyTrue",
143+
"assertIsNotNone",
144+
"assertRegex",
145+
"authType",
146+
"checkFilePermissions",
147+
"cleanMacros",
148+
"cleanUsers",
149+
"collectionName",
150+
"ElementTree",
151+
"eventCount",
152+
"expectedDefinition",
153+
"handle_DELETE",
154+
"handle_GET",
155+
"handle_PATCH",
156+
"handle_POST",
157+
"handle_PUT",
158+
"Handler",
159+
"IllegalOperationException",
160+
"IncomparableException",
161+
"INDEX_NAME",
162+
"InputSchema",
163+
"installedApps",
164+
"InvalidNameException",
165+
"LOG_FILE",
166+
"LOG_PATH",
167+
"N",
168+
"newContext",
169+
"NoSuchCapability",
170+
"pathComponents",
171+
"pathInApp",
172+
"record",
173+
"retryDelay",
174+
"server",
175+
"setupInfo",
176+
"SPLUNK_HOME",
177+
"splunkHome",
178+
"StructuredOutputGenerationException",
179+
"tcpKind",
180+
"tcpName",
181+
"test_3rdPartyInsertedCookiePersistence",
182+
"test_cannot_create_with_restrictToHost_in_name",
183+
"test_create_tcp_ports_with_restrictToHost",
184+
"test_DELETE",
185+
"test_filePermissions",
186+
"test_GET",
187+
"test_input_ToolContext",
188+
"test_no_str_body_GET",
189+
"test_PATCH",
190+
"test_POST",
191+
"test_PUT",
192+
"test_update_restrictToHost_fails",
193+
"test_updateInfo",
194+
"testData",
195+
"ToolException",
196+
"totalEventCount",
197+
"udpKind",
198+
"udpName",
199+
"updateInfo",
200+
"versionSearch",
201+
]
202+
130203
[tool.ruff.format]
131204
docstring-code-format = true

0 commit comments

Comments
 (0)