Install
$ agentstack add skill-probabl-ai-skills-python-api ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
python-api
Discover the public API of any installed Python package, cache what matters, never trust training-data memory.
Three durable rules:
- Lookup against the installed version, never memory.
Recognition is not a lookup. The version may have renamed / re-signatured / deprecated the symbol you remember.
- Cache to
scratch/api///.mdso the
next agent doesn't repeat the probe.
- Bundled
references/≠ workspace cache. Bundled refs are
durable workflow patterns; cache files are per-version extracts.
Next-step pointers
| Came here for… | After lookup, next is… | |---|---| | Symbol signature for code about to be written | → continue caller's flow (e.g. build-ml-pipeline § next step) | | "Which library / which entry?" | → continue with the picked symbol; cache lands | | Bootstrap turn (first workspace) | → required minimum cache lands; see references/bootstrap_cache.md | | Failure debugging (KeyError / AttributeError) | → see Stop condition "Lookup failure ≠ artifact missing" |
What kind of question? → Shape
Pick the shape by question type before picking a tool. Wrong shape produces a wrong-looking cache file and burns a turn.
| The user's question is shaped like… | Shape | |---|---| | "What's in scratch/api///?" (always check first) | 0 cache hit | | "Which entry point for <task>?" | Stack orientation below, then Shape 1 / 1b to confirm | | "What's the signature of X?" / "What args does X take?" / "What's the return type?" | 1b LSP hover (fast) → fall through to 1 if hover is sparse | | "What does X do?" / "Full docstring of X?" (need Parameters / Examples / See Also) | 1 symbol card (pydoc) | | "What's in module Y?" (open-ended discovery) | 2 module surface | | "Search for symbols matching foo* across the env" | 2b LSP workspace symbol | | "How does X work?" / "Which of A or B should I use?" | 3 narrative | | "What does X return when ` is `?" | 3 narrative | | "What's the recommended pattern for …?" | 3 narrative |
**Shape 3 is the right answer when the question depends on a condition over an argument.** help() carries a Returns section but typically does not enumerate dispatch behaviour under each argument value — that lives in narrative docs.
Shape 1b vs Shape 1. Pyright hover gives the type signature (richer inferred return types than inspect.signature) + the first paragraph of the docstring — fast, no Python execution. Pydoc gives the full docstring with all sections — slower but authoritative. Default escalation: 1b first for "what's the signature"; fall through to 1 if hover is empty / one-liner.
Prerequisites for Shape 1b / 2b (LSP shapes). Pyright available via opencode LSP AND pyrightconfig.json pointing at the lsp env. If either is missing, LSP shapes are unavailable — use Shape 1 / 2 directly. The agent feature: installed row in JOURNAL.md Status Workspace decisions is the precondition; see python-env-manager § Agent feature.
Stop conditions — read before any lookup
- No symbols from memory. Every function / class / method / arg
must come from a lookup this turn — inspect.signature, a scratch/api/// file, or a fresh WebFetch. Recognition does not count. Sticky named cases — full list in references/named_traps.md:
- skrub:
tabular_learner→tabular_pipelinein 0.7+. - skrub:
mark_as_y(target_column)→ signature dropped the
positional arg in 0.9+; use .skb.select("...") before mark.
- skore:
Project.get(...)is by id, not user-facingkey;
enumerate via project.summarize() first.
- Never fabricate a probe result. If the probe hasn't executed,
the Signature / help() sections must remain blank or marked ``. Same rule for Shape 3: do not paraphrase docs from memory; cache file holds verbatim extracts.
- Version-correct first. Resolve
.__version__before any
lookup. The version subfolder is the cache freshness key.
- Cache hit before fresh fetch. List
scratch/api/// before Shape 1 / 2 / 3.
- Lookup failure ≠ artifact missing. A
KeyError/
AttributeError on a registry-style API (project.get(key), getattr(obj, name), dict[key]) is almost always the lookup shape (id vs key, wrong accessor) — not a missing artifact. Named instance: skore.Project.get(...) resolves by id, not by user-facing key; project.summarize() enumerates (key, id) pairs. Never substitute by re-creating the artifact — that lands a duplicate row.
- **All Python execution goes to
scratch/__.py. No exceptions.** Every Python command — pixi run python -c, python -c, heredoc-style python _.py. Applies to version checks, import smokes, signature lookups, module surface dumps, docstring extraction, anything. If you catch yourself typing python -c — STOP and write the file.
- **
inspect.signature/dir(...)/pydoc.render_doc/
help(...) executed inline is NOT a python-api consultation.** These are the exact APIs this skill wraps. Running them via python -c does NOT satisfy the "python-api consulted" pre-flight row in sibling skills. The deliverable is a scratch/api///.md file written this turn.
pydoc.render_doc, not__doc__.__doc__is empty /
misleading on properties, descriptors, decorated callables, and accessors — exactly the cases the cache disambiguates.
- Narrative findings get cached. A WebFetch result read and
discarded is forbidden. Land it in scratch/api///.md with the source URL on the first line.
- A probe without a cache write is not a completed lookup.
Probe records the investigation; cache file records the conclusion. Turn end without scratch/api///.md on disk = incomplete.
Forbidden shortcuts
| Shortcut | Why it's wrong | |---|---| | Recognise the symbol name from training data → write the call | Memory keyed to arbitrary version; install may have renamed / re-signatured | | Probe ran, answer on screen → stop without writing the cache | Probe is investigation; cache is conclusion. Next session repeats the probe | | Bundled references/X.md exists → treat as the cache | References are workflow patterns; cache is per-version extracts. Both must exist | | Version subfolder missing → write into the latest existing one | Subfolder is the freshness key. Create the right one | | Multi-symbol → string several inspect.signature into one inline python -c | All Python execution goes to scratch — no inline -c allowance. Multi-symbol → one scratch file → one consolidated cache file | | Used python -c "import ; print(.__version__)" for a quick version check | Rule is unconditional. Length is not the criterion — traceability is. Version checks go to scratch/_version_.py | | Cache exists for the topic; ran inline inspect.signature(X) to re-confirm one arg name | No inline single-signature carve-out exists. Every Shape 1 lookup uses the probe template | | Used python -c "...inspect.signature..." instead of writing the Shape 1 probe | Probe records the investigation; cache records the conclusion. Next session needs the file, not your transcript | | User pasted a docs URL → treat as the answer | Lookup still requires inspect or WebFetch + cache write. URLs are leads | | Use __doc__ instead of pydoc.render_doc | __doc__ is empty on many accessors; cache file must be readable standalone |
First action — every turn that triggers this skill
- Resolve the version. Write
scratch/__version_.py with import ; print(.__version__), run via pixi run python scratch/_version_.py. No inline python -c.
- List the cache:
ls scratch/api///. - Cache hit? Read the matching file. Done.
- Cache miss? Classify the question (table above) → run Shape
1 / 1b / 2 / 2b / 3.
- Emit the pre-flight checklist with each box marked.
Pre-flight — emit before any lookup
Pre-flight (python-api):
- [ ] Package version resolved this turn:
Evidence: Write scratch/_version_.py (this turn) +
`pixi run python scratch/_version_.py` output.
**Inline `python -c "..."` is NOT evidence.**
- [ ] Cache listed this turn (Shape 0): `ls scratch/api///`
Evidence: tool output (paste the listing, even if empty)
- [ ] Question shape classified: signature | module surface | narrative
Evidence: name the shape + one phrase from the question
- [ ] Lookup decision: cache hit (Read ) | Shape 1 | 1b | 2 | 2b | 3
Evidence: name the file Read, probe script written, LSP
operation requested, or URL fetched
- [ ] (Shape 1b / 2b only) LSP preconditions confirmed:
`agent feature: installed` in JOURNAL.md AND
`pyrightconfig.json` at project root pointing at the `lsp` env
Evidence: Read journal/JOURNAL.md + Read pyrightconfig.json
(this turn) | "n/a — not an LSP shape"
- [ ] Cache file lands on disk before turn end
Evidence: Write scratch/api///.md (this turn)
| "n/a — cache hit, already on disk + Read this turn"
| "n/a — Shape 2b ad-hoc discovery"
**Inline `inspect.signature(...)` / `dir(...)` / `pydoc.render_doc(...)`
WITHOUT a corresponding cache file is NOT evidence. Re-do as Shape 1.**
- [ ] If Shape 1 / 1b: Usage section filled in (Call / Don't call / Trap / Returns)
Evidence: Edit scratch/api///.md (this turn)
| "n/a — cache hit / Shape 2 / 2b / 3"
- [ ] Pre-flight re-emitted with evidence before final message.
Evidence: this checklist appears in the end-of-turn summary.
The four shapes
Shape 0 — cache hit
ls scratch/api/// 2>/dev/null
Topic-matching file present → Read it. First line carries the source URL or inspect: ref; re-verify against live docs if a file looks suspicious. Cache miss → Shape 1 / 2 / 3.
Shape 1 — symbol card (pydoc → cache file)
One probe script does both: introspects the symbol AND writes the cache file in a single execution. Small follow-up Edit fills the Usage bullets (Call / Don't call / Trap / Returns).
Probe template: → references/probe_templates.md § Shape 1.
Multi-symbol consolidation. Several symbols sharing a topic (e.g. Project.put / Project.get / Project.summarize under project_local) → iterate over a tuple of dotted paths inside the probe and concatenate sections into one .md. **One topic file per topic, not per symbol.**
No inline carve-out for single-signature checks. Even when a cache exists and you want to re-confirm one arg, run a fresh probe (or Read the existing cache).
Shape 1b — LSP hover (no Python execution)
Pyright via the opencode LSP returns hover info (type signature + first paragraph of docstring) for a symbol at a file:line:character position. First stop for "what's the signature" questions when Shape 1b is known available this session (see Step 0 below); fall through to Shape 1 otherwise, or when the hover output is sparse.
Step 0 — probe LSP availability (mandatory, once per session)
The opencode LSP server reads pyrightconfig.json once at session startup. Mid-session edits do NOT reload. If the LSP returns (import) : Unknown for every external library, the config was written after the LSP initialized — Shape 1b is unavailable this session. Sticky decision: use Shape 1 for ALL signature questions until next opencode session.
Probe procedure + interpretation table + every footgun (session-startup ordering, conda-style envs, character offset, scratch-excluded paths, C-extension types): → references/shape1b_lsp_setup.md.
After availability is confirmed
- Write a probe file (under
tests/orsrc//—scratch/
is excluded from pyright's analysis). Template: → references/probe_templates.md § Shape 1b.
- Call
lsp(operation="hover", filePath=..., line=..., character=...). - Cache the result at
scratch/api///.md with Source: lsp-hover: . @ and a ## LSP hover section.
- Escalate to Shape 1 if hover is empty / one-liner.
Shape 2 — module surface
Scratch probe that dumps both top-level surface and submodule list, then writes surface.md directly. No inline python -c.
Probe template: → references/probe_templates.md § Shape 2.
One topic per file. Replace only on a version bump.
Shape 2b — LSP workspace symbol (cross-package search)
Given a query string, return all matching symbols across the lsp env's site-packages. Use for discovery before committing to a dotted path; faster than dir() on every candidate module.
lsp(
operation="workspaceSymbol",
filePath="",
line=1, character=1,
query="",
)
(filePath/line/character are ignored by pyright for workspaceSymbol; only used to select the LSP server.)
Return: list of (name, kind, location) tuples. NOT a Shape-2 replacement (doesn't enumerate a full module surface). Use as a discovery aid before running Shape 1 / Shape 2 on the right dotted path. Cache only if the search becomes recurring.
Shape 3 — narrative
Conceptual questions where the signature alone doesn't answer it — "how does X work?", "which of A/B should I use?", "what does X return when ` is `?". Procedure:
- WebSearch for the versioned docs URL. Query:
docs . Don't construct URLs from memory.
- WebFetch the most relevant result whose URL contains the
installed version (/0.18/, /0.18.0/). Reject any URL with /latest/ or /stable/ — those drift on republish.
- Cache verbatim to
scratch/api///.md:
```markdown #
Source: Fetched:
```
Cache filename: snake_case mirror of the docs URL slug. One topic per file. Replace only on version bump.
Cache file contract
Every scratch/api///.md follows a four-section shape:
#
Source: inspect: . @ |
Probed:
## Signature
## help() (or "## Docs extract" for Shape 3, "## LSP hover" for 1b)
## Usage (agent synthesis)
- **Call:** import path + arg shape (2-3 line snippet)
- **Don't call:** named substitutes that look right from memory
- **Trap:** version-specific rename / deprecation / footgun (empty if none)
- **Returns:** return type + the one accessor the next caller needs
Bootstrap turns have a required minimum cache to leave behind — file list + audit procedure: → references/bootstrap_cache.md.
Cache layout & lifecycle
scratch/api/
├── skrub/0.9.0/
│ ├── data_ops.md # Shape 3 narrative
│ ├── tabular_pipeline.md
│ └── surface.md # Shape 2 dir() dump
├── skore/0.18.0/
│ ├── evaluate.md
│ └── project_local.md
└── sklearn/1.8.0/
└── cv_splitters.md
- Version subfolder ==
.__version__exactly. No
abbreviation (0.18.0 ≠ 0.18).
- First line is the source URL or
inspect:ref. - Gitignored by the existing
scratch/*rule. Regenerable. - Append-on-success. Once written, frozen. Replace only on
version bump (the version-subfolder convention handles this).
- Cache miss in a stale subfolder is impossible by construction.
Shape 0 reads by version; old subfolder content is invisible.
scratch/ conventions — probes vs. cache
Two structured uses of scratch/, both gitignored:
| | Ad-hoc probes | API doc cache | |---|---|---| | Path | scratch/__.py | scratch/api///.md | | What | Multi-line inspect walks, sanity checks, metric extraction | Signature / help() / docs extract per topic | | Naming | Timestamped (chronological) | Topic-organised | | Lifecycle | Append-only after success; overwrite on error in same loop | Append-on-success; replace on version bump | | Inline cap | No inline python -c. All execution goes to scratch | n/a (probes write the cache) |
Never edit an experiment script to add agent-only print(...) calls for inspection. Inspection goes in `scratch/
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: probabl-ai
- Source: probabl-ai/skills
- License: BSD-3-Clause
- Homepage: https://probabl.ai/skills
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.