A newer version of the Gradio SDK is available:
6.1.0
Code Style Guide
Last Updated: 2025-12-06
This guide covers code style conventions and tooling for DeepBoner.
Quick Reference
# Auto-format code
make format
# Check linting
make lint
# Type check
make typecheck
# Run all checks
make check
Tooling
Ruff (Linting & Formatting)
Configuration in pyproject.toml:
[tool.ruff]
line-length = 100
target-version = "py311"
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"F", # pyflakes
"B", # flake8-bugbear
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"PL", # pylint
"RUF", # ruff-specific
]
MyPy (Type Checking)
Configuration in pyproject.toml:
[tool.mypy]
python_version = "3.11"
strict = true
ignore_missing_imports = true
disallow_untyped_defs = true
warn_return_any = true
Pre-commit Hooks
Hooks run automatically on commit:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
hooks:
- id: mypy
Python Style
Type Hints
All functions must have type annotations:
# Good
def search(query: str, limit: int = 10) -> list[Evidence]:
"""Search for evidence."""
pass
# Bad
def search(query, limit=10):
pass
Use modern type hint syntax (Python 3.11+):
# Good
def process(items: list[str] | None) -> dict[str, int]:
pass
# Avoid (old syntax)
from typing import List, Dict, Optional
def process(items: Optional[List[str]]) -> Dict[str, int]:
pass
Docstrings
Use Google-style docstrings for public APIs:
def search_pubmed(query: str, max_results: int = 10) -> SearchResult:
"""Search PubMed for biomedical literature.
Args:
query: The search query string.
max_results: Maximum number of results to return.
Returns:
SearchResult containing evidence and metadata.
Raises:
SearchError: If the API call fails.
RateLimitError: If rate limit is exceeded.
"""
pass
Class Documentation
class SearchHandler:
"""Orchestrates parallel searches across multiple sources.
This handler implements a scatter-gather pattern to query
multiple biomedical databases simultaneously.
Attributes:
sources: List of enabled search sources.
timeout: Timeout for each search in seconds.
Example:
handler = SearchHandler()
result = handler.search_all("testosterone therapy")
"""
def __init__(self, sources: list[str] | None = None) -> None:
"""Initialize the search handler.
Args:
sources: Optional list of sources to enable.
Defaults to all sources.
"""
pass
Imports
Imports are sorted by isort (via ruff):
# Standard library
import asyncio
from datetime import datetime
from typing import Any
# Third-party
import httpx
from pydantic import BaseModel
# Local
from src.utils.config import settings
from src.utils.exceptions import SearchError
Line Length
Maximum 100 characters. Break long lines:
# Good - break at logical points
result = very_long_function_name(
first_argument=value1,
second_argument=value2,
third_argument=value3,
)
# Good - string continuation
message = (
"This is a very long message that needs to be "
"split across multiple lines for readability."
)
Naming Conventions
| Type | Convention | Example |
|---|---|---|
| Classes | PascalCase | SearchHandler |
| Functions | snake_case | search_pubmed |
| Variables | snake_case | max_results |
| Constants | UPPER_SNAKE | MAX_ITERATIONS |
| Private | leading underscore | _internal_method |
| Type vars | PascalCase | T, ConfigT |
Exceptions
Custom exceptions in src/utils/exceptions.py:
from src.utils.exceptions import SearchError
# Raising
raise SearchError(f"API returned {status_code}")
# With cause
try:
response = client.get(url)
except httpx.HTTPError as e:
raise SearchError(f"Request failed: {e}") from e
Pydantic Models
Model Definition
from pydantic import BaseModel, Field
class Evidence(BaseModel):
"""A piece of evidence from search."""
content: str = Field(min_length=1, description="The evidence text")
relevance: float = Field(ge=0.0, le=1.0, default=0.0)
metadata: dict[str, Any] = Field(default_factory=dict)
model_config = {"frozen": True} # Make immutable
Settings
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
"""Application settings from environment."""
model_config = SettingsConfigDict(
env_file=".env",
case_sensitive=False,
)
max_iterations: int = Field(default=10, ge=1, le=50)
Async Code
Async Functions
async def search_async(query: str) -> SearchResult:
"""Async search implementation."""
async with httpx.AsyncClient() as client:
response = await client.get(url)
return parse_response(response)
Concurrent Execution
async def search_all(query: str) -> list[SearchResult]:
"""Search all sources concurrently."""
tasks = [
search_pubmed(query),
search_clinicaltrials(query),
search_europepmc(query),
]
return await asyncio.gather(*tasks, return_exceptions=True)
Comments
When to Comment
# Good: Explain WHY, not WHAT
# PubMed rate limits without API key - add delay to avoid 429
await asyncio.sleep(0.34)
# Bad: Obvious comment
# Increment counter
counter += 1
TODO Comments
# TODO(username): Description of what needs to be done
# TODO: Short-term fix, proper solution needs X
Ignored Rules
Some rules are disabled for good reasons:
ignore = [
"PLR0913", # Too many arguments (agents need many params)
"PLR0912", # Too many branches (complex orchestrator logic)
"PLR2004", # Magic values (statistical constants)
"PLW0603", # Global statement (singleton pattern)
"PLC0415", # Lazy imports for optional dependencies
]
File Organization
Module Structure
"""Module docstring explaining purpose."""
# Imports (sorted)
import ...
# Constants
MAX_RESULTS = 100
# Type definitions
ResultType = dict[str, Any]
# Classes
class MyClass:
pass
# Functions
def my_function():
pass
# Module-level code (minimize)
if __name__ == "__main__":
main()
Package Structure
src/tools/
βββ __init__.py # Public exports
βββ base.py # Base classes
βββ pubmed.py # PubMed implementation
βββ clinicaltrials.py
βββ search_handler.py
Code Review Checklist
Before submitting a PR:
- All functions have type hints
- Public APIs have docstrings
-
make checkpasses - No hardcoded credentials
- Error cases are handled
- Tests cover new code