Agent skill

Python Guide

by lightly-ai in lightly-ai/lightly-studio

Read before writing or reviewing any Python code in this repository.

Apache-2.0Auto-check passedTesting & QA

Install Python Guide

skills CLI
$ npx skills add lightly-ai/lightly-studio --skill python-guide -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install lightly-ai/lightly-studio python-guide --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/lightly-ai/lightly-studio.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/python-guide .claude/skills/python-guide && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
python-guide
GitHub stars
896
Token cost
~3k tokens
SKILL.md length
1,070 words
Files
1
Skills in repo
6
Repo updated
First seen
Licence
Apache-2.0

At a glance

Read before writing or reviewing any Python code in this repository.

  • Tasks that involve Technical documentation
  • SKILL.md covers Imports, File layout, Protocols vs ABCs and TODOs, plus 6 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Tasks that involve Unit testing

What it does

Python Guide is an agent skill from lightly-ai/lightly-studio. Read before writing or reviewing any Python code in this repository. Covers import style (modules for functions, direct for classes), file layout ordering (private functions at the bottom), protocols vs ABCs, TODO and comment format, assertions, preference for keyword arguments, docstrings including tensor shapes, typing, and pytest conventions.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Technical documentation and Unit testing. It works with Python and pytest. The repository describes itself as: LightlyStudio - The Unified Data Platform for Multimodal ML. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Technical documentation
  • Tasks that involve Unit testing

Example prompts

  • “/python-guide”

Requirements

  • Python 3

What it can do on your machine

Read from SKILL.md and the folder at commit 66da613. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Python Guide loads about 3k tokens when it runs. Until then it costs about 90 tokens; SKILL.md has 1,070 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~90
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from lightly-ai/lightly-studio at commit 66da613, republished under its Apache-2.0 licence (© lightly-ai). 1,070 words, ~2,967 tokens.

Download SKILL.mdSave it as .claude/skills/python-guide/SKILL.md (or your agent's skills folder).
name
python-guide
description
Read before writing or reviewing any Python code in this repository. Covers import style (modules for functions, direct for classes), file layout ordering (private functions at the bottom), protocols vs ABCs, TODO and comment format, assertions, preference for keyword arguments, docstrings including tensor shapes, typing, and pytest conventions.

Python Code Guidelines

No rules here are hard, but they are strong recommendations. The golden rule is to make the code easy to understand and difficult to break.

We use the ruff code formatter and mypy type checker with custom settings. You don't need to check rules enforced by these tools like e.g. line length.

Code Style

Imports

  • For functions, import the containing module and call the function using dot notation
  • Import classes directly
  • Rationale: Using dot notation makes it obvious in the code when a function is external and leads to a more succinct import code. Classes are an exception, they are often used as type hints so less verbosity is preferred.
python
from mypackage import mymodule
from mypackage.mymodule import MyClass

mymodule.foo()
c = MyClass()

Exceptions from the guidelines:

  • We allow direct function import from typing, dataclasses, abc, sqlmodel, sqlalchemy

File layout

  • Put important functions at the top
    • Especially, put public functions before private ones
    • Classes should come before global functions
  • Rationale: The file should be easy to understand when read top-to-bottom. Important information should be towards the top of the file.
python
from x import y

class MyClass:
    def __init__(self):
        ...

    def foo(self):
        ...

    def _helper_method(self):
        ...

def bar(...):
    ...

def _helper_func(...):
    ...

Protocols vs ABCs

  • It’s ok to use ABCs when appropriate (consider nominal vs structural subtyping).
  • Prefer composition over inheritance.
    • Inheritance can introduce bi-directional flow of information between parent and child class.
    • Higher flexibility

TODOs

Use the following format: # TODO({name}, {mm}/{yyyy}): Blah blah

python
# TODO(Michal, 08/2023): Blah blah

Comments

Use ASD-STE100 Simplified Technical English, avoid bloat. Describe the current state, not the change. Prefer properly formatted comments with a leading capital and punctuation. Final full stop may be omitted for a single sentence.

python
# This is a proper comment. It spans multiple sentences.
...

# Single sentences can have the final full stop omitted
...

# we don't do this <-
...

Assertions

  • Avoid using assertions:
    • Don’t use assertions for user errors, raise an exception instead.
    • Assertions should never fail. If they do it is a bad internal error.
    • Don’t assert that a variable follows its typehint.

They can be used:

  • for invariants that are easy to check locally, like a minimum length
  • for typing (e.g. non-nullity)
  • To document what we expect a particular value to be. Here, expect means that there would need to be some logical error somewhere for the value to be different.
  • in a private function when the calling code makes the check

It’s ok to not test assertions as they’re not the intended behavior of a function.

Example:

python
def get_metrics(values: list[float]) -> Something:
    ...
    if len(values) < 2:
        std = 0 # Or an Error is raised.
    else:
        std = _get_std(values)
    ...

def _get_std(sequence: Sequence[float]) -> float:
    """Gets the standard deviation of a sequence

    Args:
        sequence:
            The sequence to get the std of.
            Must have a length >= 2.

    Returns:
            The standard deviation of a sequence.

    """

    assert len(sequence) >= 2
    return np.std(sequence)

Positional vs. Keyword Arguments

Call functions using keyword arguments, whether or not the arguments are declared keyword-only with *. Do not declare arguments as keyword-only with * in our code.

python
def fn(hello: str, person: str) -> None:
    ...

fn(hello="Grüezi", person="Bob")

The exception of using positional arguments is allowed for

  • if the keyword arguments are not known, e.g. because the function is only given through typing: transform: Callable[[Tensor], Tensor] must be called as transformed = transform(tensor)
  • for common standard library functions like e.g. print, math.exp, zip, isinstance, dict.get, etc.
  • For common functions from core frameworks such as datetime, pytest, numpy, pytorch, logging, etc.
  • For SQL ORM functions like select, col, etc.

__init__.py files

Don't put logic in __init__.py files. They should be preferrably empty, or just expose submodule symbols for convenience.

Exceptions may apply occasionally. Such logic should be accompanied by a comment explaining why it is done.

Docstrings

Function and method-level Docstrings

We use Google style docstrings.

python
def foo(bar: int) -> str:
    """Summary of function here.

    Longer function information...

    Args:
        bar: Description of the argument `bar`.

    Returns:
        Description of the return value.

    Raises:
        ValueError: Description of the error that may be raised.
    """
Class-level Docstrings

Document the functionality of the class and its public attributes if they are not already documented on the class level.

python
class SampleClass:
    """Summary of class here.

    Longer class information...

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    name: str
    """An example docstring."""
Tensor Shapes in Docstrings
  • The tensor shapes in the Args and Returns sections should be documented through capital letters in parentheses.
  • The explanation of these letters happens above in the method/function description.
  • Tensor dtypes must be documented unless the dtype is torch.float32 which is assumed to be the default.
python
    def forward(self, pointclouds: Tensor, index: Tensor) -> Tensor:
        """Propagates a batch of 3D point clouds through the model.
        
        B corresponds to the batch size, N is the number of points in each (padded)
        pointcloud and D is the output dimension of the extracted features.
        
        Args:
            pointclouds: Tensor of shape (B, N, 3).
            index: Binary index for the padded pointcloud of shape (B, N) of dtype
                `torch.bool`.
            
        Returns:
            Reduced point clouds of the shape (B, D).
        """
        self.likes_spam = likes_spam
        self.eggs = 0
Show full SKILL.md (497 more words)Show less

Typing

All our code must be typed.

  • Prefer Python 3.10+ syntax for built-ins

    • Good: lst: list[int], bad: lst: typing.List[int]
    • Good: path: str | None, bad: path: typing.Optional[str]
    • For python 3.8, you can get these by using from __future__ import annotations . To use also Pydantic, pip install eval_type_backport. Also typing_extensions package might be needed.
  • Use built in ABCs

    • Use Sequence and Mapping for immutable list and dict
    • Import from collections.abc:
      • Good: from collections.abc import Sequence, Mapping
      • Bad: from typing import Sequence, Mapping
      • Rationale: The latter is deprecated by PEP 585
  • Use abstract inputs and concrete outputs:

    • Good (note: toy example, it could accept and return Iterable in this case):

      python
      def add_suffix_to_list(lst: Sequence[str], suffix: str) -> list[str]:
          return [x + suffix for x in lst]
  • Be specific when ignoring a type error

    • Good: def foo(x: Any) -> None: # type: ignore[misc]
    • Bad: def foo(x: Any) -> None: # type: ignore
    • Rationale: Ignoring all type errors might miss an error that was not intended.
  • Torch typing

    • Type all tensors with from torch import Tensor
    • Note that things like FloatTensor and LongTensor should NOT be used as they are deprecated and cannot be typed by mypy.

Testing

Golden rule: Write code that is easy to test
  • Such code indicates good design - functionality is well isolated
  • Functions are easier to test than class methods
  • Single responsibility functions are easy to test
  • Code using dependency injection is easy to test
Write strong signal tests
  • From an information-theoretic point of view, we want to maximise P(correct|passes): The probability that an implementation is correct given the test passes.
  • Cover a typical case. Cover edge cases.
  • A good set of tests should cover all branches.
Use patching/mocking sparingly
  • Prefer blackbox testing with real objects
  • Mocking has its place though, especially for outside dependencies (e.g. db or network) or long-running subroutines
  • Mocking is also suitable for “thin” methods that make many subcalls
  • Spying can be an alternative to mocking
Tests must be easy to check by hand
  • Because tests are not tested
  • Keep tests small. Split larger tests that check multiple cases.
  • Prefer writing out test inputs instead of generating them
A test states every value that its assertions depend on
  • Put each value that decides the outcome (a dimension, a count, a space key, a limit) in one of these places:
    • the test body
    • a pytest.mark.parametrize decorator on the test
    • a constant of the test module
  • Do not keep such a value only inside a fixture, a helper or the code under test.
  • Write a relation between two values as the two values, not as a helper name such as "wider".
  • Rationale: A test that hides a value assumes that the value never changes, and the reader cannot check it.
python
# Bad: The first import stores dimension 3, the RandomEmbedder() default in patch_collection.
# The name "wider" is true only while that default is less than 4.
dataset.add_images_from_path(path=tmp_path / "first")
_register_wider_random_embedder(mocker=mocker)
with pytest.raises(ValueError, match=r"does not match"):
    dataset.add_images_from_path(path=tmp_path / "second")

# Good: The test body shows both dimensions.
_patch_registry(mocker=mocker, embedder=RandomEmbedder(dimension=3))
dataset.add_images_from_path(path=tmp_path / "first")
_patch_registry(mocker=mocker, embedder=RandomEmbedder(dimension=4))
with pytest.raises(ValueError, match=r"does not match"):
    dataset.add_images_from_path(path=tmp_path / "second")
Tests must use pytest (NOT unittest)
  • Don't import unittest. Pytest is more modern.
  • Use MockerFixture for mocking.
python
from pytest_mock import MockerFixture

def test_foo(mocker: MockerFixture):
    mock_bar = mocker.patch.object(mymodule, "bar", return_value=42)
    mock_bar.assert_called_once_with(...)

    mock_obj = mocker.MagicMock()

Test Naming and File Structure

Tests must be located in a folder structure parallel to src/{package_name} and use the following naming conventions:

python
# src/my_package/dir/source.py

class MyClass:
    def __init__(self): ...
    def foo(self): ...
    
class _InternalClass:
    def _helper_method(self): ...

def bar(...): ...
def _helper_func(...): ...
python
# tests/dir/test_source.py

class TestMyClass:
    def test_init(self): ...
    def test_init__some_special_case(self): ...
    def test_foo(self): ...
    
    def test_{method_name_underscores_stripped}{__{special_case} | ''}
    
class TestInternalClass:
    def test_helper_method(self): ...
    def test_helper_method__my_special_case(self): ...
        
def test_bar(): ...
def test_helper_func(): ...

Keep the order of test functions the same as the tested functions order.

© lightly-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/python-guide of lightly-ai/lightly-studio.

Open the folder on GitHubat commit 66da613

Compare with similar skills

Python Guide next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Python Guide compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Python Guide this skilllightly-ai/lightly-studio896—~3kAutomated safety check: PassApache-2.0
Leetcode Pywislertt/leetcode-py142—~1.4kAutomated safety check: PassApache-2.0
Python Testingmacalbert/envilder138—~3.1kAutomated safety check: PassMIT
Simple Modern Uvjlevy/simple-modern-uv301—~1.9kAutomated safety check: PassMIT
JS-in-HTML Testingliaohch3/claude-tap3.3k—~924Automated safety check: PassMIT
Python Helpershepherdjerred/monorepo112—~2.3kAutomated safety check: PassGPL-3.0

Similar skills

  • Leetcode Py

    wislertt/leetcode-py

    Generates Python LeetCode practice environments and manages a 307-problem catalog with the lcpy CLI.

    142 GitHub stars~1.4k tokensUpdated today
    Business, Finance & HRAuto-check passed
  • Python Testing

    macalbert/envilder

    Mandatory testing conventions including AAA pattern, test naming, assertions, and mocks.

    138 GitHub stars~3.1k tokensUpdated 2 days ago
    Testing & QAAuto-check passed
  • Simple Modern Uv

    jlevy/simple-modern-uv

    Start, selectively modernize, fully migrate, or update Python projects using simple-modern-uv practices: uv, ruff, BasedPyright, pytest, GitHub Actions CI, and tag-driven PyPI publishing.

    301 GitHub stars~1.9k tokensUpdated 1 mo ago
    Testing & QAAuto-check passed
  • JS-in-HTML Testing

    liaohch3/claude-tap

    Tests JavaScript embedded in an HTML file in two layers: pytest checks of the logic ported to Python, and Playwright runs in a real browser for the DOM.

    3.3k GitHub stars~924 tokensUpdated 15 days ago
    Testing & QAAuto-check passed
  • Python Helper

    shepherdjerred/monorepo

    Current Python development guidance for versions, uv and pip, packaging, typing, asyncio, pytest, Ruff, security, and runtime boundaries.

    112 GitHub stars~2.3k tokensUpdated today
    Testing & QAAuto-check passed
  • Adk Verify Snippets

    google/adk-python

    Official

    Checks that every Python code block in a Markdown file actually compiles and runs, by extracting each block to a temporary file, executing it in an isolated subprocess, and writing a pass/fail…

    22k GitHub stars~1.4k tokensUpdated today
    Testing & QAAuto-check passed

More from lightly-ai/lightly-studio

  • Backend Guide

    lightly-ai/lightly-studio

    Read before adding or changing backend code in lightlystudio - FastAPI routes, services, resolvers, SQLModel tables, or database access.

    896 GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Frontend Guide

    lightly-ai/lightly-studio

    Read before writing or reviewing any frontend code in lightlystudioview - Svelte, TypeScript, or SvelteKit files.

    896 GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Glossary

    lightly-ai/lightly-studio

    Read when naming anything user-facing - GUI text, docs, public Python API names, arguments, docstrings, or error messages.

    896 GitHub stars~482 tokensUpdated today
    Auto-check passed
  • Pull Requests

    lightly-ai/lightly-studio

    Read when opening a pull request, writing a PR description, splitting work into PRs, or deciding whether a change is too large to review.

    896 GitHub stars~709 tokensUpdated today
    Auto-check passed
  • Best Practices

    lightly-ai/lightly-studio

    Read when adding a new function, module, or component, or when a file is growing large enough that splitting it is worth considering.

    896 GitHub stars~424 tokensUpdated today
    Auto-check passed

Works with

Questions about Python Guide

What does Python Guide do?

Read before writing or reviewing any Python code in this repository. Python Guide is an agent skill from lightly-ai/lightly-studio. Read before writing or reviewing any Python code in this repository.

When should I use Python Guide?

Python Guide fits situations like: tasks that involve Technical documentation; tasks that involve Unit testing.

How do I install Python Guide in Claude Code?

Run `npx skills add lightly-ai/lightly-studio --skill python-guide -a claude-code`. Or copy the skill folder (.agents/skills/python-guide in lightly-ai/lightly-studio) into .claude/skills/python-guide in your project. Claude Code loads it when a task matches its description.

How do I install Python Guide in Codex?

Run `npx skills add lightly-ai/lightly-studio --skill python-guide -a codex`. Or copy the skill folder (.agents/skills/python-guide in lightly-ai/lightly-studio) into .agents/skills/python-guide in your project. Codex loads it when a task matches its description.

Can I use Python Guide in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add lightly-ai/lightly-studio --skill python-guide -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/python-guide, .gemini/skills/python-guide, .github/skills/python-guide and .opencode/skills/python-guide in your project.

What does Python Guide need to run?

SKILL.md names no scripts, command-line tools or credentials: Python Guide is instructions for the agent only. Our summary lists: Python 3.

Does Python Guide access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Python Guide safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Python Guide use?

Python Guide is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Python Guide use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Python Guide?

Skills that share tags, products or a category with Python Guide: Leetcode Py (wislertt/leetcode-py, 142 stars), Python Testing (macalbert/envilder, 138 stars), Simple Modern Uv (jlevy/simple-modern-uv, 301 stars) and JS-in-HTML Testing (liaohch3/claude-tap, 3.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Python Guide?

lightly-ai (a GitHub organization) maintains it in lightly-ai/lightly-studio, which has 896 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 7, 2026.

Source: lightly-ai/lightly-studio on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.