Setup
Get your development environment ready to build neops function blocks.
Prerequisites
You need three things installed:
| Tool | Version | Purpose |
|---|---|---|
| Python | 3.12+ | Runtime for function blocks |
| uv | latest | Fast Python package manager |
| Code editor | any | VS Code or PyCharm recommended |
Installing uv
See docs.astral.sh/uv for other installation methods.
Project Setup
Scaffold a new project with uv:
Prefer pip?
If you prefer pip over uv, create a virtual environment and install manually:
Replace the generated pyproject.toml with a configuration tailored for neops development:
[project]
name = "my-neops-function-blocks"
version = "0.1.0"
description = "My first neops function blocks"
requires-python = ">=3.12"
dependencies = [
"neops_worker_sdk",
]
[project.optional-dependencies]
test = [
"pytest>=8.4.1",
"pytest-asyncio>=1.1.0",
"neops-remote-lab>=1.3.0",
]
[tool.ruff]
line-length = 120
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "UP", "B"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
This gives you:
- The
neops_worker_sdkruntime dependency - Test dependencies (
pytest,pytest-asyncio,neops-remote-lab) as optional extras - Sensible
ruffandpytestconfiguration
Install everything, including test dependencies:
Tooling
Linting & Formatting — Ruff
We use Ruff for linting and formatting. It is a
single, extremely fast tool (written in Rust) that replaces flake8, isort, and
Black. The pyproject.toml above already includes a good baseline configuration.
Add Ruff as a development dependency so every contributor uses the same version:
Then run it from your project:
Type Checking — Pyrefly
We use Pyrefly (by Meta) for type checking. It is a Rust-based type checker and language server that provides fast, accurate analysis for modern Python.
Add it as a development dependency:
Then run it:
Why typed Python matters
neops function blocks rely heavily on type annotations. Here is why that matters:
- Auto-completion — your editor understands parameter and return types
- Early bug detection — type checkers catch mismatches before runtime
- Schema generation — Pydantic models (used for parameters and results) derive JSON schemas from type hints automatically
Compare:
vs.
async def run(self, params: EchoParams, context: WorkflowContext) -> FunctionBlockResult[EchoResult]:
...
The typed version gives your editor, your tests, and the neops platform everything they need to validate your code before it ever touches a device.
IDE Recommendations
Recommended extensions:
| Extension | ID | Purpose |
|---|---|---|
| Python | ms-python.python |
Core Python support |
| Pyrefly | meta.pyrefly |
Type checking, auto-completion, go-to-definition |
| Ruff | charliermarsh.ruff |
Fast linting and formatting |
Pyrefly acts as a full language server — it provides inline type errors, hover information, and code navigation out of the box. It replaces Pylance for type analysis, so you only need one of the two.
Recommended settings (.vscode/settings.json):
Alternative: Pylance
If you prefer Microsoft’s Pylance
(ms-python.vscode-pylance), it works well too — add
"python.analysis.typeCheckingMode": "basic" to your settings.
Pyrefly disables Pylance by default when both are installed; keep only one
active to avoid duplicate diagnostics.
PyCharm has excellent built-in Python support — type checking, refactoring, and debugging work out of the box with fewer plugins.
Recommended plugins:
| Plugin | Purpose |
|---|---|
| Pydantic | Enhanced support for Pydantic models (auto-completion, validation) |
Configuration tips:
- Ruff integration: Go to Settings > Tools > External Tools, add a new
tool with program
uv, argumentsrun ruff check $FilePath$, and working directory$ProjectFileDir$. Add a second entry with argumentsrun ruff format $FilePath$for formatting. Assign keyboard shortcuts or configure file watchers to run on save. - Pyrefly for type checking: Add an external tool with program
uv, argumentsrun pyrefly check $FilePath$, and working directory$ProjectFileDir$. This gives you the same type analysis as CI, beyond PyCharm’s built-in inspector.
Environment Configuration
neops workers discover the platform and function blocks through environment variables.
Create a .env file in your project root:
| Variable | Description |
|---|---|
URL_BLACKBOARD |
URL of your neops instance’s blackboard API |
DIR_FUNCTION_BLOCKS |
Directory where the worker discovers your function block modules |
Tip
During local development with the test framework, these variables are not required – the test harness provides its own context.