A command line tool for analyzing FreeCAD documents. FC-Audit helps you understand how your FreeCAD models are structured by extracting and analyzing:
- Property names used in objects
- Cell aliases in spreadsheets
- Expressions and their dependencies
- References between objects and spreadsheet cells
This is particularly useful for:
- Debugging complex parametric models
- Finding dependencies between parts
- Auditing spreadsheet usage
- Analyzing model structure
fc-audit only reads FreeCAD documents and does not modify them.
The recommended way to install fc-audit is using pipx, which installs the tool in an isolated environment.
-
First, install pipx:
Linux:
Using package managers:
# Ubuntu/Debian sudo apt update sudo apt install pipx pipx ensurepath # Fedora sudo dnf install pipx pipx ensurepath # Arch Linux sudo pacman -S python-pipx pipx ensurepath
Or using pip:
python3 -m pip install --user pipx python3 -m pipx ensurepath
macOS:
brew install pipx pipx ensurepath
Windows:
py -3 -m pip install --user pipx py -3 -m pipx ensurepath
-
Then install fc-audit:
pipx install fc-audit
After installation, verify it works:
fc-audit --versionRequirements:
- Python 3.11 or higher
- FreeCAD documents in FCStd format
Extract cell aliases from spreadsheet(s) in one or more FreeCAD documents:
You should include at least one document with at least one spreadsheet as aliases are defined only in spreadsheets.
# get list of aliases from one file
fc-audit aliases file1.FCStd
# which is the same as specifying text output from two files
fc-audit aliases --text file1.FCStd file2.FCStd
# get a filtered list of aliases from all FreeCAD documents in a directory
fc-audit aliases --filter "Fan*" cad_proj/*.FCStd
# output the list of alias to a json file from all FreeCAD documents in the current directory
fc-audit aliases --json *.FCStd > aliases.json
# output the list of aliases that end in Width or Length to a csv file
fc-audit aliases --csv --filter "*Width,*Length" *.FCStd > aliases.csvExtract unique property names from one or more FreeCAD documents:
fc-audit properties *.FCStdYou can output properties in different formats:
# Simple list of properties (default)
fc-audit properties *.FCStd
# Output as JSON
fc-audit properties --json *.FCStd
# Output as CSV
fc-audit properties --csv *.FCStd
# Filter properties by pattern
fc-audit properties --filter "Shape*" *.FCStdExtract and analyze alias references from expressions in FreeCAD documents. For each alias, show which objects reference it and their expressions.
You should include at least one document with at least one spreadsheet as aliases are defined only in spreadsheets.
By default, all discovered aliases will be shown unless filtered:
# Show all aliases found in the documents
fc-audit references *.FCStdThe --by-alias, --by-object, and --by-file options allow you to group the output by alias, object, or file, respectively. These output as formatted text with different groupings.
The --json and --csv options allow you to output the results in JSON or CSV format, respectively.
Use --filter to filter and show only specific aliases:
# Filter to show only specific aliases
fc-audit references --filter alias1,alias2 *.FCStdFilterOption:
--filter: Optional. Comma-separated list of aliases to show. When not specified, all discovered aliases will be shown. Supports wildcards like*and?(e.g.,Fan*matches all aliases starting with "Fan"). Note, you should quote the list of aliases if you are using shell wildcards, for example:--filter "Fan*"
Output Format Options: You must choose exactly one of these output formats:
--by-alias: Group output by alias (default)--by-object: Group output by file and object--by-file: Group output by file and alias--json: Output in JSON format for programmatic use--csv: Output as comma-separated values (CSV)
Note: These format options are mutually exclusive - you cannot use more than one at a time.
Examples:
# Show all Fan-related aliases (default format) from two FreeCAD document files
fc-audit references --filter "Fan*" file1.FCStd file2.FCStd
# Show all Fan-related aliases grouped by file from all FreeCAD documents in a directory
fc-audit references --by-file --filter "Fan*" cad_proj/*.FCStd
# Show all Fan-related aliases grouped by object
fc-audit references --by-object --filter "Fan*" *.FCStd
# Get JSON output for programmatic use
fc-audit references --json --filter "Fan*" *.FCStd > fan_refs.json
# Get CSV output for spreadsheet analysis
fc-audit references --csv --filter "Fan*" *.FCStd > fan_refs.csv
# Show Hull width and length
fc-audit references --filter "Hull[WL]*" *.FCStd
# Show multiple aliases
fc-audit references --filter "Fan*,Hull*" *.FCStdFor more information on available commands:
fc-audit --helpGroups references by alias name, then by file and object:
Alias: FanDiameter
File: DriveFans.FCStd
Object: Sketch
Expression: <<params>>.FanDiameter
Expression: <<params>>.FanDiameter + 2 * <<params>>.WallThickness
Object: Sketch002
Expression: <<params>>.FanDiameter
Groups references by file, then by alias and object:
File: DriveFans.FCStd
Alias: FanDiameter
Object: Sketch
Expression: <<params>>.FanDiameter
Expression: <<params>>.FanDiameter + 2 * <<params>>.WallThickness
Object: Sketch002
Expression: <<params>>.FanDiameter
Groups references by object, then by file and alias:
Object: Sketch
File: DriveFans.FCStd
Alias: FanDiameter
Expression: <<params>>.FanDiameter
Expression: <<params>>.FanDiameter + 2 * <<params>>.WallThickness
The CSV output has the following columns:
alias: The name of the parameterfilename: The FreeCAD file containing the referenceobject_name: The name of the object using the parameterexpression: The expression containing the parameter reference
Example CSV output:
alias,filename,object_name,expression
"FanDiameter","file.FCStd","Sketch","<<params>>.FanDiameter"
"FanHeight","file.FCStd","Pad001","<<params>>.FanHeight"
{
"alias_name": [
{
"filename": "filename.FCStd",
"object_name": "object_name",
"expression": "expression",
"spreadsheet": "spreadsheet_name",
"alias": "alias_name"
}
]
}The JSON output is organized by:
filename: The FCStd file containing the referencesobject_name: The object within the file using the aliasalias_name: The alias being referencedexpressions: List of expressions using the alias
This example uses uv, but you can use any tool (hatch, poetry, etc.) you prefer.
# Create and activate virtual environment
uv venv
source .venv/bin/activate
# Install for development
uv pip install -e ".[dev]"After installing in development mode, you can run fc-audit directly:
# Run from the project root
uv python -m fc_audit --help
# Or use the entry point script in your virtual environment's bin directory
fc-audit --helpThe use of Task is optional, but recommended for development. Task is used to run the CI checks and other development tasks defined in Taskfile.yaml.
# Show all available tasks
task --list-all
# Run all CI checks (recommended before committing)
task ciThe task ci command runs the following checks:
- Code quality checks (pre-commit, ruff and mypy)
- Code metrics (radon)
- Tests with coverage report (pytest)
- Documentation build (mkdocs)
- Package build (build)
and is equivalent to:
task lint
task metrics
task test:coverage
task docs:build
task buildwhich is equivalent to:
uv run pre-commit run --all-files
uv run ruff check src tests
uv run mypy src tests
uv run radon cc src
uv run pytest -vv --cov --cov-report=term-missing
uv run mkdocs serve
uv run python -m build --wheelYou can also run individual tasks:
# Run tests
task test
# Run tests with coverage report
task test:coverage
# Run linting
task lint
# or just mypy
task lint:mypy
# Format code
task format
# Build documentation
task docs:build
# Serve documentation locally
task docspre-commit hooks run automatically on git commit to ensure code quality and consistency. To set up:
# Install pre-commit in your environment
uv pip install pre-commit
# Optional: Run hooks on all files
pre-commit run --all-files
# Run specific hooks
pre-commit run ruff --all-files
pre-commit run mypy --all-filesNote: If you get a "No module named pre_commit" error, try running pre-commit install in your virtual environment.
Resetting your virtual environment may cause this error.
File Formatting and Validation:
- Trailing whitespace removal
- End of file fixing (ensures files end with newline)
- YAML/TOML validation
- Large file checks
- Merge conflict detection
- Debug statement detection
- Case conflict detection
- Mixed line ending fixing
Code Style (ruff):
- PEP 8 style guide enforcement
- Code formatting
- Import sorting
- Dead code elimination
Type Checking (mypy):
- Static type checking
- Strict mode enabled
- Type stub validation
To bypass pre-commit hooks in emergency situations:
git commit -m "message" --no-verifyNote: Using --no-verify is discouraged as it skips important quality checks.
We use MkDocs with the Material theme for documentation. The documentation includes:
- User Guide
- API Reference
- Development Guide
# Build and serve documentation locally
task docs# Install documentation dependencies
uv pip install -e ".[dev]"
# Build the documentation
uv run mkdocs build
# Serve documentation locally
uv run mkdocs serveAfter running mkdocs serve, visit http://127.0.0.1:8000 to view the documentation.
The tool provides detailed error messages and handles common issues:
- Invalid FCStd files
- Missing or corrupted Document.xml
- Invalid XML content
- Missing attributes or elements
Use the -v or --verbose flag for detailed logging:
fc-audit -v references file.FCStdOptionally, log to a file:
fc-audit --log-file audit.log references file.FCStdThank you for your interest in contributing to fc-audit! This document provides guidelines and instructions for contributing to the project.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and quality checks:
task ci
- Update documentation if needed
- Submit a pull request
This project uses several tools to maintain code quality:
-
pre-commit: For automated code quality checks on git commits. Run hooks manually with:
task hooks
-
ruff: For linting and code formatting. Run checks with:
task lint:ruff
-
mypy: For static type checking. Run checks with:
task lint:mypy
-
pytest: For running tests. Run the test suite with:
task test -
radon: For code complexity metrics. Run analysis with:
task metrics
-
mkdocs: For building documentation. Build and serve docs with:
task docs:build task docs # builds and serves at http://127.0.0.1:8000 -
build: For building Python packages. Create distributions with:
task build # creates both wheel and sdist
You can run all quality checks at once with:
task ciNote: Package publishing should only be performed by the official package maintainer. If you need a new release, please open an issue or submit a pull request.
The project uses twine for publishing to PyPI and TestPyPI. While uv publish is available, we use twine because:
- It's more mature and reliable for package publishing
- It handles first-time package uploads better
- It provides better error messages and upload status feedback
To publish the package, you need to:
- Set up your PyPI credentials in
~/.pypircand secure it:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = your-pypi-token
[testpypi]
username = __token__
password = your-testpypi-tokenMake sure to restrict access to the credentials file:
chmod 600 ~/.pypirc- Publish the package:
# Publish to TestPyPI first (automatically runs build task)
task publish-test-pypi
# If everything looks good, publish to PyPI (automatically runs build task)
task publish-pypiNote: Both publish tasks have deps: [build] configured, so they will automatically run the build task which cleans the dist/ directory and creates fresh wheel and sdist distributions.
The package will be available at: