A Python code linter specifically designed for Xian smart contracts. It combines PyFlakes for general Python linting with a custom Contracting linter to ensure contract code follows specific rules and patterns.
The linter can be used in two ways:
- Inline/Programmatic: Import and use directly in your Python code without any server dependencies
- Standalone Server: Run as a FastAPI service with HTTP endpoints for remote linting
- Parallel execution of linters (PyFlakes + Contracting)
- Deduplication of error messages
- Configurable whitelist patterns for ignored errors
- Standardized error reporting format
- Base64 and Gzip encoded code input support (server mode)
- Input validation and size limits (server mode)
Install the base package without server dependencies:
pip install xian-linterInstall with the server extras to include FastAPI and uvicorn:
pip install xian-linter[server]# Clone the repository
git clone https://github.com/xian-network/xian-linter.git
cd xian-linter
# Install base dependencies using Poetry
poetry install
# Or install with server extras
poetry install --extras serverUse the linter directly in your Python code without running a server:
from xian_linter import lint_code_inline
# Your contract code as a string
contract_code = """
def transfer():
sender_balance = balances[ctx.caller]
balances[ctx.caller] -= amount
"""
# Lint the code
errors = lint_code_inline(contract_code)
# Check results
if errors:
for error in errors:
print(f"Line {error.position.line}: {error.message}")
else:
print("No errors found!")You can also provide custom whitelist patterns:
errors = lint_code_inline(
contract_code,
whitelist_patterns=['custom_pattern', 'another_pattern']
)Run the linter as a FastAPI service (requires [server] extras):
xian-linterpython -m xian_linteruvicorn xian_linter.server:app --host 0.0.0.0 --port 8000poetry run xian-linterThe server will start on http://localhost:8000 by default.
Expects base64-encoded Python code in the request body.
# Example using curl
base64 < contract.py > contract.py.b64
curl -X POST "http://localhost:8000/lint_base64" --data-binary "@contract.py.b64"Expects gzipped Python code in the request body.
# Example using curl
gzip -c contract.py > contract.py.gz
curl -X POST "http://localhost:8000/lint_gzip" -H "Content-Type: application/gzip" --data-binary "@contract.py.gz"whitelist_patterns: Comma-separated list of patterns to ignore in lint errors. Default patterns are provided for common Contracting keywords.
{
"success": false,
"errors": [
{
"message": "Error description",
"severity": "error",
"position": {
"line": 3,
"column": 1
}
}
]
}The position field is optional and may not be present for global errors.
The following patterns are ignored by default in Pyflakes checks:
export,constructHash,Variable,ForeignHash,ForeignVariablectx,now,block_num,block_hash,chain_idrandom,importlib,hashlib,datetime,crypto,decimalAny,LogEvent