Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ OpenShell as the runtime.
- `docs/dev-notes/` contains research engineering updates, release notes, and
build logs worth sharing.
- `docs/dev-notes/authors.json` contains reusable Dev Notes author metadata.
- `projects/` contains self-contained research projects and a reusable Python
project template.
- `scripts/render-dev-notes.py` renders Dev Notes cards, post bylines, and
navigation entries from post front matter.
- `zensical.toml` configures the documentation site.
Expand Down
10 changes: 10 additions & 0 deletions projects/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Projects

This directory contains self-contained research projects. Each project should
live in its own subfolder with its own dependencies, runtime notes, and source
layout.

Current projects:

- `python-project-template`: Minimal, production-ready Python project scaffold
managed with uv.
24 changes: 24 additions & 0 deletions projects/python-project-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Python-generated files
__pycache__/
*.py[cod]
*.egg-info/
build/
dist/

# Environments and tool caches
.venv/
.coverage
htmlcov/
.pytest_cache/
.ruff_cache/
.ty/

# Local configuration
.env
.env.*
!.env.example

# Editors and operating systems
.idea/
.vscode/
.DS_Store
1 change: 1 addition & 0 deletions projects/python-project-template/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10
58 changes: 58 additions & 0 deletions projects/python-project-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Python Project Template

A minimal Python package template for OpenShell research projects. It uses a
`src` layout, uv for dependency and environment management, Ruff for linting and
formatting, ty for type checking, and pytest for tests and coverage.

## Start a project from this template

Copy this directory, then update the distribution name, import package,
description, and command entry point in `pyproject.toml`. Keep `uv.lock` and the
generated `requirements.txt` committed.

## Develop

Install [uv](https://docs.astral.sh/uv/), then create the locked development
environment:

```sh
uv sync --locked
```

Run the example command:

```sh
uv run python-project-template --name OpenShell
```

Run all local checks:

```sh
uv run ruff format --check .
uv run ruff check .
uv run ty check
uv run pytest
uv build
```

## Manage dependencies

Use `uv add <package>` for runtime dependencies and `uv add --dev <package>` for
development tools. uv updates `pyproject.toml` and `uv.lock` together.

nSpect needs a resolved dependency manifest it can inspect. `uv.lock` remains
the source of truth for installs, while `requirements.txt` is a generated,
hash-pinned export of runtime dependencies for the scanner. Do not edit the
export by hand. Regenerate it after every runtime dependency update:

```sh
uv export \
--format requirements.txt \
--no-dev \
--no-emit-project \
--locked \
--output-file requirements.txt
```

CI and deployments should install from the lockfile with `uv sync --locked` or
`uv sync --frozen`, never resolve dependencies afresh.
54 changes: 54 additions & 0 deletions projects/python-project-template/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[project]
name = "python-project-template"
version = "0.1.0"
description = "Minimal uv-managed Python project template for OpenShell research."
readme = "README.md"
requires-python = ">=3.10"
license = "Apache-2.0"
authors = [
{ name = "NVIDIA CORPORATION & AFFILIATES" },
]
dependencies = [
"click>=8.1,<9",
]

[project.scripts]
python-project-template = "python_project_template.cli:main"

[project.urls]
Repository = "https://github.com/NVIDIA/OpenShell-Research"

[dependency-groups]
dev = [
"pytest>=8,<10",
"pytest-cov>=5,<8",
"ruff>=0.12,<1",
"ty>=0.0.53",
]

[build-system]
requires = ["uv_build>=0.11.8,<0.12.0"]
build-backend = "uv_build"

[tool.pytest.ini_options]
addopts = [
"--strict-config",
"--strict-markers",
"--cov=python_project_template",
"--cov-report=term-missing",
"--cov-fail-under=100",
]
testpaths = ["tests"]

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = ["B", "E", "F", "I", "RUF", "SIM", "UP"]

[tool.ty.src]
include = ["src", "tests"]

[tool.uv]
required-version = ">=0.8.0"
10 changes: 10 additions & 0 deletions projects/python-project-template/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file was autogenerated by uv via the following command:
# uv export --format requirements.txt --no-dev --no-emit-project --locked --output-file requirements.txt
click==8.4.2 \
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
# via python-project-template
colorama==0.4.6 ; sys_platform == 'win32' \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
# via click
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Example package for the OpenShell Python project template."""

from python_project_template.cli import greeting

__all__ = ["greeting"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Command-line interface for the example project."""

import click


def greeting(name: str) -> str:
"""Build a greeting for ``name``."""
return f"Hello, {name}!"


@click.command()
@click.option("--name", default="world", show_default=True, help="Name to greet.")
def main(name: str) -> None:
"""Print a friendly greeting."""
click.echo(greeting(name))
21 changes: 21 additions & 0 deletions projects/python-project-template/tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Tests for the example command-line interface."""

from click.testing import CliRunner

from python_project_template.cli import greeting, main


def test_greeting() -> None:
"""Build a greeting from the supplied name."""
assert greeting("OpenShell") == "Hello, OpenShell!"


def test_main() -> None:
"""Expose the greeting through the console entry point."""
result = CliRunner().invoke(main, ["--name", "OpenShell"])

assert result.exit_code == 0
assert result.output == "Hello, OpenShell!\n"
Loading