SecInterp - Development Guide
[!note] Related guide A repo-facing companion guide (decoupled architecture + commit workflow) lives in
docs/docsec/DEVELOPMENT_GUIDE.md.
Welcome to the SecInterp development guide. This document outlines the standards, best practices, and workflows for contributing to the project.
🏗️ Technical Stack
Language: Python 3.10+ (QGIS 3.x compatible)
GUI Framework: PyQt5 (Native QGIS integration)
Geospatial Engine: PyQGIS API (
qgis.core,qgis.gui)Package Manager:
uv(recommended) orpipLinter & Formatter:
RuffTesting:
unittest(Standard Library)
🎨 Coding Standards
🧬 Design Principles
SOLID: Follow SRP, OCP, and DIP strictly.
Separation of Concerns: GUI code (Managers/UI) MUST NOT contain business logic. Delegating to
Core/Servicesis mandatory.DRY (Don’t Repeat Yourself): If a calculation or check is used twice, move it to a
core/utilsmodule.
📝 Naming Conventions
Classes:
CapWords(e.g.,ProfileService).Variables/Functions:
snake_case(e.g.,calculate_apparent_dip).Qt Overrides:
camelCase(MUST match the original C++ signature, e.g.,showEvent).Signals:
camelCase(PyQt style, e.g.,dataChanged).
🐍 Imports Ordering
Standard Library:
os,sys,math, etc.Third-Party:
numpy,pandas, etc.QGIS Core:
from qgis.core import ...QGIS GUI:
from qgis.gui import ...PyQt:
from qgis.PyQt.QtWidgets import ...(Always useqgis.PyQtshim).Local Modules:
from sec_interp.core import ...
⚡ Git Workflow
Conventional Commits
All commits MUST follow the Conventional Commits specification:
Format: <type>(<scope>): <description>
feat: A new feature (e.g.,feat(drill): add 3d projection)fix: A bug fix (e.g.,fix(gui): resolve range attribute error)refactor: Code change that neither fixes a bug nor adds a feature.docs: Documentation changes.test: Adding or correcting tests.chore: Build process or auxiliary tool changes.
Language: All commit messages must be in English.
🛠️ Tooling (Ruff)
We use Ruff for linting and formatting. It replaces Black, isort, and Flake8.
Basic Commands
# Lint and auto-fix
ruff check . --fix
# Format code
ruff format .
# Check everything (QA)
ruff check . && ruff format . --check
IDE Integration
It is highly recommended to install the Ruff extension in VS Code and enable “Format on Save”.
🧪 Testing
Running Tests (Local)
# Run all tests using the unified Makefile target
make test
Running Tests (Docker - Recommended)
To avoid dependency issues with QGIS, use the containerized environment:
# Build the image and run all tests in an isolated QGIS container
make docker-test
Mocking QGIS
When testing core services, use unittest.mock to avoid requiring a running QGIS instance. For integration tests in a headless environment, the project is configured to use QT_QPA_PLATFORM=offscreen.
📝 Documentation Standards
Docstrings
All public functions and methods MUST have docstrings in Google Style:
def process_data(self, layer: QgsVectorLayer, factor: float) -> Optional[list]:
"""
Processes the layer using the specified scaling factor.
Args:
layer: The input QGIS vector layer.
factor: The vertical exaggeration factor.
Returns:
A list of processed coordinates or None if invalid.
"""
Documentation Workflow
The project uses Sphinx to generate documentation. The build is automated and publishes the result to a separate GitHub repository (sec_interp_docs), which serves as the source for GitHub Pages.
Building and Publishing
make docs # → ./scripts/build_docs.sh
./scripts/build_docs.sh [DIR] # DIR defaults to ../sec_interp_docs
The script performs:
sphinx-apidoc -o docs/source . docs/ tests/ scripts/ help/ build/ --force --separate --module-first— regenerates one autodoc page per Python module of the plugin (core/,gui/,exporters/,plugin/,resources/and the root entry points). It excludestests/,scripts/,docs/,help/andbuild/.scripts/i18n/translate_docs.py compile— compiles the.pomessage catalogs to.mo.sphinx-build— builds HTML for 14 languages (en es fr pt_BR de ru zh_CN id it pl nl fi hi ja).Copies the HTML to
../sec_interp_docs/<lang>/.Syncs the offline manual into
help/html/<lang>(image dedup; search/API/sources stripped).If
../sec_interp_docs/.gitexists, commits (docs: auto-build from sec_interp@<hash>) and pushes togeociencio/sec_interp_docs(main).
Output repository
Item |
Value |
|---|---|
Local output |
|
Remote |
|
GitHub Pages |
https://geociencio.github.io/sec_interp_docs/ |
[!warning] Side effects
make docsregenerates the tracked.rststubs indocs/source/, leaving the working tree dirty — review and commit them.Step 6 performs a real
git pushto the external docs repo (there is no flag to skip it). To build without publishing, run steps 1–5 manually.
sphinx-apidoc --forcedoes not delete stubs for removed modules; delete orphan.rstfiles indocs/source/if the build warns about missing modules.
[!note] Shell note The language loop in the script assumes
bash. When replicating it in zsh, use an array (LOCALES=(en es fr …)) orbash -c, since zsh does not word-split a scalar variable.
Image Assets
Save all documentation images in docs/images/ using the following convention:
workflow_DESC.png: Step-by-step guides.ui_DESC.png: General interface screenshots.feature_DESC.png: Specific highlighted features.
📦 Deployment & Makefile
Use the Makefile for common development tasks:
make deploy: Installs the plugin into your local QGIS plugins folder.make zip: Creates a release-ready ZIP file.make test: Runs all unit and integration tests locally.make docker-build: Builds the testing Docker image.make docker-test: Builds and runs tests within a QGIS Docker container.make docus: Builds the Sphinx documentation.make clean: Removes temporary and compiled files.make transup: Updates.tsfiles and applies master data usingapply_full.py.make transcompile: Compiles.qmfiles.