Skip to content

Add CyteType docs site, fix results normalization, relicense as BSD-3 - #93

Merged
parashardhapola merged 2 commits into
masterfrom
docs-site-0.21.0
Oct 18, 2026
Merged

parashardhapola merged 2 commits into
masterfrom
docs-site-0.21.0

Conversation

@parashardhapola

Copy link
Copy Markdown
Member

Summary

SDK (release as 0.21.0)

  • Results:
    • The five legacy evidence fields are filled from fullOutput, using the same rules as the server.
    • New result keys reviewerConfidence, isHeterogeneous and heterogeneityType.
    • New obs column {prefix}_reviewerConfidence_{group_key}.
    • Results saved in older h5ad files are re-normalized when read.
  • New:
    • run(visibility=...).
    • The deepseek, nebius and together providers.
    • AUTHENTICATION_REQUIRED maps to AuthenticationError.
    • Exceptions are importable from cytetype, with the timeout error as CyteTypeTimeoutError.
  • Fixes:
    • The DuckDB temp directory.
    • A stale saved key after signing in again.
    • run() after cleanup().
    • marker_dotplot gene matching and empty groups.
    • Partial artifact files left after a failed build.
    • An early sign-in note.
    • The backed-mode hint now appears only from 100k cells.
    • NO_COLOR support.
  • Packaging:
    • Unused session-info and python-dotenv removed.
    • Only cytetype* is packaged.
    • Documentation URL added.
    • BSD 3-Clause license; the service terms moved to the README.

Docs site (docs/, served at https://docs.nygen.io/CyteType/)

  • MyST and Sphinx setup ported from CyteBase.
  • Content:
    • 30 pages covering the Python and R clients;
    • the Python API reference;
    • an R reference generated from CyteTypeR's help pages;
    • a quickstart notebook executed against the live service.
  • Tooling: a local notebook runner, docs tests, and the docs.yml and pages.yml workflows.

Testing

  • Python 3.12: 260 passed; ruff and mypy clean; uv lock --check passes.
  • Docs: 153 tests pass; BASE_URL=/CyteType make -C docs html passes.

Before merging

  • Settings → Pages → Source: GitHub Actions (no custom domain), and allow the github-pages environment to deploy from master.
  • The CyteTypeServer results change is deployed.

After merging

  • The "GitHub Pages" workflow has deployed https://docs.nygen.io/CyteType/ (run it manually if needed).
  • Release 0.21.0 (GitHub Release, tag 0.21.0) once the site is live.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Launch CyteType docs site and improve SDK results handling

✨ Enhancement 🐞 Bug fix 📝 Documentation ⚙️ Configuration changes 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Launch a tested Python and R documentation site with automated GitHub Pages deployment.
• Restore evidence in results, expose reviewer assessments, and normalize older saved results.
• Improve SDK authentication, artifacts, plotting, and sharing; relicense the Python client under
 BSD-3-Clause.
Diagram

graph TD
  Source["Docs sources"] --> Runner["Notebook runner"] --> MyST["MyST build"] --> Discovery["Discovery exports"] --> Site["Pages site"]
  Source --> Sphinx["Sphinx API"] --> MyST
  Pages["Pages workflow"] --> CI["Docs workflow"] --> Sphinx
  CI --> MyST
  Pages --> Site
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Single documentation generator
  • ➕ Simpler build and deployment pipeline
  • ➕ Fewer cross-generator links to maintain
  • ➖ Would sacrifice either the existing Sphinx autodoc capabilities or the chosen MyST notebook presentation
  • ➖ Requires more custom reference-generation work

Recommendation: Keep the MyST-plus-Sphinx approach: it serves the distinct notebook and API-reference needs, and the coverage checks address integration drift. Reviewers should pay particular attention to saved notebook provenance and the required server-side results change before release.

Files changed (74) +14708 / -238

Enhancement (6) +330 / -65
__init__.pyExpose SDK exceptions at the package root +29/-0

Expose SDK exceptions at the package root

• Exports public exception classes and aliases the timeout exception as CyteTypeTimeoutError to avoid shadowing the built-in.

cytetype/init.py

__init__.pyClarify API exception exports +8/-2

Clarify API exception exports

• Exports ClientDisconnectedError and the timeout alias while retaining direct access to the original timeout class.

cytetype/api/init.py

schemas.pyAdd providers and report visibility to schemas +8/-3

Add providers and report visibility to schemas

• Accepts DeepSeek, Nebius, and Together configurations and defines the visibility choices for annotation requests.

cytetype/api/schemas.py

payload.pyPass optional visibility in job payloads +4/-0

Pass optional visibility in job payloads

• Includes requested report visibility in the validated submission payload while omitting it when unset.

cytetype/core/payload.py

results.pyStore reviewer confidence and refresh saved results +52/-12

Store reviewer confidence and refresh saved results

• Adds a categorical reviewer-confidence obs column, records requested visibility, and normalizes results read from AnnData.

cytetype/core/results.py

main.pyHarden job submission and artifact lifecycle +229/-48

Harden job submission and artifact lifecycle

• Adds run visibility, fresh reads of saved credentials, early sign-in guidance, partial-artifact cleanup, and explicit behavior after cleanup().

cytetype/main.py

Bug fix (6) +393 / -74
client.pyNormalize annotations when fetching results +14/-37

Normalize annotations when fetching results

• Replaces inline result transformation with shared normalization, preserving raw annotations and filling structured evidence.

cytetype/api/client.py

exceptions.pyClassify required-authentication responses +2/-1

Classify required-authentication responses

• Maps AUTHENTICATION_REQUIRED to AuthenticationError.

cytetype/api/exceptions.py

normalization.pyUnify current and stored result normalization +201/-0

Unify current and stored result normalization

• Fills blank legacy evidence from structured output, adds reviewer fields, and re-normalizes older stored results without mutating them.

cytetype/api/normalization.py

config.pyHonor NO_COLOR in success logs +3/-0

Honor NO_COLOR in success logs

• Suppresses ANSI coloring for success messages when NO_COLOR is set.

cytetype/config.py

artifacts.pyUse private DuckDB spill directories +62/-24

Use private DuckDB spill directories

• Replaces the shared fixed spill path with a temporary directory, cleans up added columns, and limits backed-mode advice to large datasets.

cytetype/core/artifacts.py

dotplot.pyMatch plotted markers to available genes +111/-12

Match plotted markers to available genes

• Matches markers against the gene names Scanpy will use, handles case differences and missing annotations, and drops empty marker groups.

cytetype/plotting/dotplot.py

Tests (9) +4235 / -11
conftest.pyAdd reusable log capture fixture +21/-1

Add reusable log capture fixture

• Provides a fixture for asserting SDK log levels and messages.

tests/conftest.py

test_artifacts.pyCover artifact cleanup and spill behavior +190/-3

Cover artifact cleanup and spill behavior

• Extends tests around artifact generation, temporary paths, and failure handling.

tests/test_artifacts.py

test_cytetype_integration.pyExercise new SDK run and retrieval behavior +599/-7

Exercise new SDK run and retrieval behavior

• Expands integration coverage for credentials, visibility, artifacts, and stored or remote results.

tests/test_cytetype_integration.py

test_docs_execution.pyTest safe notebook execution +529/-0

Test safe notebook execution

• Checks kernel isolation, timing, page selection, source preservation, and rejection of incomplete executions.

tests/test_docs_execution.py

test_docs_render.pyTest site rendering and saved outputs +1439/-0

Test site rendering and saved outputs

• Covers execution provenance, staging, API links, output transforms, discovery exports, and revision metadata.

tests/test_docs_render.py

test_docs_structure.pyValidate documentation source structure +351/-0

Validate documentation source structure

• Checks navigation, links, reference targets, notebooks, and page conventions.

tests/test_docs_structure.py

test_logging.pyTest NO_COLOR log formatting +20/-0

Test NO_COLOR log formatting

• Verifies default success coloring and plain-text output when NO_COLOR is set.

tests/test_logging.py

test_public_api.pyTest exception and provider compatibility +106/-0

Test exception and provider compatibility

• Checks public exports, timeout aliases, required-authentication mapping, and the three added providers.

tests/test_public_api.py

test_results_normalization.pyCover historical and current result formats +980/-0

Cover historical and current result formats

• Tests evidence filling, reviewer fields, stored-result compatibility, obs columns, and marker plotting.

tests/test_results_normalization.py

Documentation (40) +7893 / -44
LICENSEAdd BSD 3-Clause client license +29/-0

Add BSD 3-Clause client license

• Introduces the BSD 3-Clause license for the Python client.

LICENSE

README.mdLink the site and clarify licensing +28/-14

Link the site and clarify licensing

• Links the new guides, corrects the quickstart preparation step, and separates BSD-licensed client code from service and generated-data terms.

README.md

AGENTS.mdDocument site authoring rules +152/-0

Document site authoring rules

• Defines conventions for notebooks, Python and R examples, links, references, and documentation builds.

docs/AGENTS.md

MAINTENANCE.mdTrack documentation follow-up work +38/-0

Track documentation follow-up work

• Records prospective screenshots and R-release documentation maintenance outside published pages.

docs/MAINTENANCE.md

development.mdRefresh contributor setup guidance +22/-9

Refresh contributor setup guidance

• Updates environment, testing, exception, and documentation-build instructions.

docs/development.md

examples.mdRefresh example report links +21/-21

Refresh example report links

• Points example reports to the current service host and corrects a description typo.

docs/examples.md

render_r_reference.RGenerate the R function reference +489/-0

Generate the R function reference

• Builds the R API page from CyteTypeR help files and exported functions using base R.

docs/render_r_reference.R

how-cytetype-works.mdExplain the annotation workflow +87/-0

Explain the annotation workflow

• Introduces the inputs, processing stages, review, and resulting report.

docs/source/getting-started/how-cytetype-works.md

installation.mdAdd Python and R installation guidance +224/-0

Add Python and R installation guidance

• Documents client installation and prerequisites for both supported languages.

docs/source/getting-started/installation.md

quickstart-r.mdAdd a Seurat quickstart +198/-0

Add a Seurat quickstart

• Walks R users through preparation, annotation, and inspection of results.

docs/source/getting-started/quickstart-r.md

sign-in.mdDocument sign-in and API keys +214/-0

Document sign-in and API keys

• Explains browser sign-in, saved credentials, and remote or headless authentication.

docs/source/getting-started/sign-in.md

automation.mdGuide scripted and remote execution +355/-0

Guide scripted and remote execution

• Covers automation patterns, HPC and CI environments, credentials, and job handling.

docs/source/guides/automation.md

large-datasets.mdGuide large-dataset preparation +215/-0

Guide large-dataset preparation

• Explains memory-conscious workflows and backed-data considerations.

docs/source/guides/large-datasets.md

llm-configuration.mdDocument model configuration +484/-0

Document model configuration

• Explains supported providers, custom model credentials, and configuration choices.

docs/source/guides/llm-configuration.md

prepare-data.mdExplain annotation input preparation +280/-0

Explain annotation input preparation

• Covers clusters, marker genes, gene symbols, and other required input data.

docs/source/guides/prepare-data.md

running-jobs.mdGuide job submission and reruns +273/-0

Guide job submission and reruns

• Documents run settings, progress, timeouts, artifacts, and rerunning annotations.

docs/source/guides/running-jobs.md

study-context.mdExplain biological context and metadata +140/-0

Explain biological context and metadata

• Shows how study context and report metadata inform and identify a run.

docs/source/guides/study-context.md

index.mdIntroduce and navigate the new site +104/-0

Introduce and navigate the new site

• Adds first-run examples for Python and R and links the site's major sections.

docs/source/index.md

llms.txtIndex documentation for text consumers +55/-0

Index documentation for text consumers

• Lists site pages and summaries in a plain-text discovery file.

docs/source/llms.txt

chat.mdDocument report-aware Chat +115/-0

Document report-aware Chat

• Explains Chat workflows and outputs connected to annotation results.

docs/source/platform/chat.md

dashboard.mdDocument dashboard workflows +221/-0

Document dashboard workflows

• Covers report management, sharing, API keys, and account views.

docs/source/platform/dashboard.md

limits.mdExplain usage limits and quotas +182/-0

Explain usage limits and quotas

• Describes account limits relevant to submitting annotation jobs.

docs/source/platform/limits.md

mcp.mdDocument the MCP connector +224/-0

Document the MCP connector

• Explains connecting AI assistants to CyteType through MCP.

docs/source/platform/mcp.md

sharing.mdExplain report visibility and sharing +115/-0

Explain report visibility and sharing

• Describes private, organization, and public visibility and related sharing behavior.

docs/source/platform/sharing.md

target-analysis.mdDocument target analysis +219/-0

Document target analysis

• Introduces the platform's target-analysis workflow and controls.

docs/source/platform/target-analysis.md

cytetype.mdReference the CyteType class +35/-0

Reference the CyteType class

• Documents the primary Python annotation interface and its public members.

docs/source/reference/api/cytetype.md

exceptions.mdReference public Python exceptions +76/-0

Reference public Python exceptions

• Documents the SDK's importable error classes.

docs/source/reference/api/exceptions.md

helpers.mdReference Python helper functions +48/-0

Reference Python helper functions

• Documents public helpers for plotting and data preparation.

docs/source/reference/api/helpers.md

index.mdIndex the Python API reference +21/-0

Index the Python API reference

• Provides the entry point to the Sphinx-generated reference sections.

docs/source/reference/api/index.md

llm-config.mdReference model configuration types +104/-0

Reference model configuration types

• Documents Python configuration interfaces for selecting LLM providers.

docs/source/reference/api/llm-config.md

cli.mdAdd command-line reference +308/-0

Add command-line reference

• Documents CyteType commands for authentication and related workflows.

docs/source/reference/cli.md

errors.mdAdd errors and codes reference +358/-0

Add errors and codes reference

• Explains client exceptions, service error codes, and recovery guidance.

docs/source/reference/errors.md

r-api.mdAdd generated R function reference +564/-0

Add generated R function reference

• Publishes CyteTypeR functions with their usage, arguments, return values, and examples.

docs/source/reference/r-api.md

interpreting-results.mdGuide interpretation of annotations +244/-0

Guide interpretation of annotations

• Explains evidence, reviewer confidence, and assessment of cell-type calls.

docs/source/results/interpreting-results.md

report.mdTour the interactive report +274/-0

Tour the interactive report

• Describes report navigation, annotation evidence, quality control, and study views.

docs/source/results/report.md

results-in-your-data.mdDocument stored Python and R results +419/-0

Document stored Python and R results

• Explains result columns and metadata in AnnData and Seurat, including reviewer fields.

docs/source/results/results-in-your-data.md

citing.mdExplain citation and version reporting +129/-0

Explain citation and version reporting

• Provides guidance on citing CyteType and recording client and analysis versions.

docs/source/support/citing.md

faq.mdAdd frequently asked questions +156/-0

Add frequently asked questions

• Answers common questions about clients, runs, and results.

docs/source/support/faq.md

security-and-privacy.mdDocument security and privacy +156/-0

Document security and privacy

• Explains data handling, authentication, and visibility considerations.

docs/source/support/security-and-privacy.md

troubleshooting.mdExpand troubleshooting guidance +517/-0

Expand troubleshooting guidance

• Consolidates remedies for sign-in, input, upload, job, and result problems.

docs/source/support/troubleshooting.md

Other (13) +1857 / -44
docs.ymlTest and build the documentation in CI +74/-0

Test and build the documentation in CI

• Adds a reusable workflow that runs documentation tests, builds the site, and uploads either a preview or a Pages artifact.

.github/workflows/docs.yml

pages.ymlDeploy documentation through GitHub Pages +46/-0

Deploy documentation through GitHub Pages

• Builds the master commit through the reusable docs workflow and deploys its artifact to GitHub Pages.

.github/workflows/pages.yml

pytest.ymlRoute documentation-only changes to docs CI +9/-0

Route documentation-only changes to docs CI

• Skips the regular test workflow for documentation-only changes covered by the new docs workflow.

.github/workflows/pytest.yml

.gitignoreIgnore generated MyST output +6/-1

Ignore generated MyST output

• Excludes the documentation source build directory while keeping source notebooks trackable.

.gitignore

MakefileProvide documentation build commands +25/-0

Provide documentation build commands

• Adds reference checks, production and preview builds, and an explicit local notebook-execution target.

docs/Makefile

build_docs.pyStage, validate, and render the documentation site +689/-0

Stage, validate, and render the documentation site

• Checks saved notebook execution, stages MyST sources and API links, builds HTML, and produces discovery and text exports.

docs/build_docs.py

check_reference_coverage.pyCheck public API documentation coverage +96/-0

Check public API documentation coverage

• Compares the Sphinx inventory with package exports and public CyteType members, reporting missing or duplicate coverage.

docs/check_reference_coverage.py

execute_docs.pyExecute selected notebooks locally +197/-0

Execute selected notebooks locally

• Runs notebooks in isolated temporary directories and saves outputs and timing only after validating their source and execution.

docs/execute_docs.py

render_outputs.pyRender saved notebook HTML as MyST nodes +163/-0

Render saved notebook HTML as MyST nodes

• Converts supported saved tables, progress text, and timing output into site-native content.

docs/render_outputs.py

myst.ymlConfigure the MyST documentation site +97/-0

Configure the MyST documentation site

• Defines navigation, theme, static assets, and the saved-output rendering plugin.

docs/source/myst.yml

conf.pyConfigure the Sphinx API reference +64/-0

Configure the Sphinx API reference

• Sets up autodoc, type hints, the reference theme, and public timeout-alias documentation.

docs/source/reference/api/conf.py

pyproject.tomlConfigure docs dependencies and BSD packaging +34/-6

Configure docs dependencies and BSD packaging

• Adds the docs dependency group and documentation URL, removes unused dependencies, restricts package discovery, and declares BSD-3-Clause.

pyproject.toml

uv.lockLock the documentation dependency set +357/-37

Lock the documentation dependency set

• Records new documentation and notebook-build dependencies and removes packages no longer required by the SDK.

uv.lock

@qodo-code-review

qodo-code-review Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Wildcard imports miss API timeouts ✓ Resolved
Description
Removing TimeoutError from cytetype.api.__all__ means from cytetype.api import * no longer
imports the exception that the client raises. Existing callers that use that import and catch
TimeoutError instead catch Python's built-in exception, which does not match CyteType's timeout
exception.
Code

cytetype/api/init.py[54]

-    "TimeoutError",
+    "ClientDisconnectedError",
+    "CyteTypeTimeoutError",
Evidence
The API previously exported TimeoutError through __all__, but the changed list omits it; the new
test confirms a wildcard import does not define that name. The transport raises the custom
exception, which derives from CyteTypeError, not Python's built-in TimeoutError.

cytetype/api/init.py[31-34]
cytetype/api/init.py[56-62]
cytetype/api/transport.py[38-40]
cytetype/api/exceptions.py[1-2]
cytetype/api/exceptions.py[53-60]
tests/test_public_api.py[59-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Removing `TimeoutError` from the API's wildcard exports breaks existing timeout handlers that import the API with `*`.
## Fix Focus Areas
- cytetype/api/__init__.py[31-62]
## Recommended Fix
Keep `TimeoutError` in `cytetype.api.__all__` alongside the new `CyteTypeTimeoutError` alias, and add a regression test that verifies both wildcard-imported names refer to the custom exception.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Executed quickstart notebook can leak secrets into docs ✓ Resolved
Description
execute_notebook builds the kernel environment as {**os.environ, **KERNEL_ENVIRONMENT} and
passes the full process environment to NotebookClient.execute, then main overwrites the source
notebook with the executed output. If any cell in the quickstart notebook prints or inspects
environment variables while running on a machine with CYTETYPE_API_KEY or other secrets set, that
value is captured in cell output and written back into the committed .ipynb file served on the
docs site.
Code

docs/execute_docs.py[R130-140]

+    kernel_manager = AsyncKernelManager(
+        kernel_name=kernelspec.get("name", ""),
+        kernel_spec_manager=KernelSpecManager(kernel_dirs=[]),
+    )
+    with TemporaryDirectory(prefix="cytetype-docs-") as working_directory:
+        NotebookClient(
+            notebook,
+            km=kernel_manager,
+            timeout=TIMEOUT_SECONDS,
+            allow_errors=False,
+            record_timing=True,
Evidence
The executor passes the entire environment to the kernel rather than an explicit allowlist, and the
same process then persists executed outputs over the source notebook, so any secret echoed by a cell
becomes part of the published documentation artifact.

docs/execute_docs.py[120-180]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The notebook executor merges the full `os.environ` into the kernel environment before running the quickstart notebook and then overwrites the source notebook with the executed output, so any secret environment variable echoed by a cell would be committed to the published docs.

## Fix Focus Areas
- docs/execute_docs.py[130-140]

## Recommended Fix
Build the kernel environment from an explicit allowlist of required variables (e.g. `CYTETYPE_API_URL`, any needed API key) plus `KERNEL_ENVIRONMENT`, instead of spreading the whole `os.environ`. Optionally scan generated outputs for known secret patterns before writing the notebook back to disk.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. A pending org-only job wastes a large upload before rejection ✓ Resolved
Description
run(visibility="org") submits the job only after _upload_artifacts has already uploaded
vars.h5 and obs.duckdb, per the new docstring stating the server rejects the job "after the
artifacts are uploaded" when a personal API key is used with visibility="org". For large datasets
this means a multi-gigabyte upload completes before the user discovers the visibility request is
invalid for their key, wasting time and bandwidth.
Code

cytetype/main.py[R640-645]

+            visibility (Literal["private", "org", "public"] | None, optional): Who can view the
+                report. Defaults to None, which uses the server default ("private"). "org" shares
+                the report with your organization and must be submitted with an organization API
+                key; with a personal key, the server rejects the job after the artifacts are
+                uploaded. "public" makes the report viewable by anyone with the link, and any
+                signed-in CyteType user can find it in Chat's report search.
Evidence
The docstring added in this PR documents that with a personal API key, requesting org visibility is
rejected only after artifacts are uploaded, but the code performs the upload (_upload_artifacts)
before job submission (submit_annotation_job) with no earlier validation of key/visibility
compatibility.

cytetype/main.py[690-790]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Requesting `visibility="org"` with a personal API key is only rejected by the server after the (potentially large) artifact upload completes, wasting time and bandwidth for large datasets.

## Fix Focus Areas
- cytetype/main.py[690-745]

## Recommended Fix
If the server exposes a cheap way to determine whether an API key belongs to an organization (e.g. part of the auth/credentials response), check it before calling `_upload_artifacts` when `visibility=="org"`, and raise early with a clear error instead of waiting for the post-upload rejection.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: Auto: 🧠 Deep: Broad SDK, CI, docs tooling, and normalization changes create many independent defect opportunities.

Grey Divider

Tip of the day
💡 Did you know, you can move or hide resolved findings to focus on what still needs action

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread cytetype/api/__init__.py
Comment thread docs/execute_docs.py
Comment thread cytetype/main.py Outdated
@parashardhapola parashardhapola mentioned this pull request Oct 18, 2026
@parashardhapola
parashardhapola merged commit 6ce97c5 into master Oct 18, 2026
2 checks passed
@parashardhapola
parashardhapola deleted the docs-site-0.21.0 branch October 18, 2026 22:50
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.

1 participant