Metadata-Version: 2.2
Name: cf-basic-io
Version: 0.2.2
Summary: Cogniflow basic I/O StepPackage with thin declarative source/sink steps.
Author-Email: ODEA Project <info@odea-project.org>
License: Apache-2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Provides-Extra: duckdb
Requires-Dist: duckdb>=0.10; extra == "duckdb"
Provides-Extra: all
Requires-Dist: duckdb>=0.10; extra == "all"
Provides-Extra: test
Requires-Dist: pytest>=7.4; extra == "test"
Requires-Dist: rdflib<8,>=7; extra == "test"
Description-Content-Type: text/markdown

# cf-basic-io

Cogniflow I/O StepPackage providing data source and sink steps.

## Steps

| Step | Category | Description |
|------|----------|-------------|
| `cfio:HandleSinkStep` | sink | Persist data to DuckDB, CSV, or other handles |
| `cfio:OpcuaReaderStep` | source | Declare a one-shot OPC UA snapshot request for the pipeline runtime |
| `cfio:JsonFieldSelectStep` | structural | Extract one field from a JSON payload |
| `cfio:TimestampToEpochStep` | structural | Convert ISO-8601 timestamp to epoch seconds |
| `cfio:EpochToTimestampStep` | structural | Convert epoch seconds to ISO-8601 timestamp |
| `cfio:ReportChartStep` | sink | Render chart output for reporting |
| `cfio:ReportTableStep` | sink | Render table output for reporting |
| `cfio:StatsRowStep` | structural | Assemble structured row outputs |

Dev/demo steps (`cfbd:InlineSource`, `cfbd:OpcuaPhSource`) now live in [`cf-basic-dev`](../cf_basic_dev/README.md).
Data hive parquet persistence now lives in [`cf-basic-sinks`](../cf_basic_sinks/README.md) as `cfsink:DataHiveParquetSinkStep`.

## Pipeline backend operations

The package also registers pipeline backend operations:

| Operation | Type | Description |
|-----------|------|-------------|
| `handle_sink` | python | Persist via duckdb:// or csv:// handles |
| `duckdb_checkpoint` | cpp | Checkpoint pipeline state to DuckDB |
| `duckdb_resume_from_checkpoint` | cpp | Resume from checkpoint |
| `duckdb_sql` | cpp | Execute SQL on checkpoint data |

## Installation

```bash
pip install cf-basic-io
```

With optional dependencies:

```bash
pip install cf-basic-io[duckdb]   # DuckDB sink support
pip install cf-basic-io[all]      # All optional deps (currently duckdb)
```

### Virtual OPC UA pH server

The demo OPC UA server lives in the separate `cf-opcua-server` package.

```bash
pip install cf-opcua-server
cf-opcua-server start --interval 0.5
# or:
python -m cf_opcua_server.cli start --interval 0.5
# server runs at opc.tcp://127.0.0.1:4840/VirtualPhServer with pH/temperature nodes under ns=2
```

`cfbd:OpcuaPhSource` (from `cf-basic-dev`) is a pure reader and does not start servers; run the demo server externally.

## C++ Extensions

Native plugin surfaces for high-performance pipeline operations that stay owned by `cf-basic-io`:

- `_duckdb_backend_ops` - DuckDB checkpoint/resume (requires DuckDB C++ library)

Build with C++ extensions:

```bash
CF_BASIC_IO_ENABLE_DUCKDB_CPP=1 pip install .
```

`cfio:OpcuaReaderStep` no longer links an OPC UA SDK inside `cf-basic-io`. The step stays declarative in this package and is executed by `cf-pipeline-engine` through the owner surface exported by `cf-opcua-server`.

## Usage

```python
from cf_basic_io.steps import handle_sink

# Write to DuckDB
handle_sink({"value": 42}, "duckdb:///output.duckdb?table=results")
```

## StepPackage Integration

This package registers with Cogniflow via the `cogniflow.steps` entry point and ships `steps.nq` as its sole manifest. The `cf:StepPackage` node declares `cf:packageId` `cf.basic.io`.

## Publishing

`cf_basic_io` is published with the dedicated Windows workflow:

- Workflow: `.github/workflows/cf_basic_io_windows_publish.yml`
- Package directory: `sandcastle/cf_basic_steps/cf_basic_io`
- PyPI tag: `cf-basic-io-v<version>`
- TestPyPI tag: `cf-basic-io-v<version>-test`

The publish path validates the default package build. OPC UA execution now lives behind the runtime-owned `cf-opcua-server` boundary, so no `open62541` toggle is required for `cf-basic-io` publishing.

Local preflight:

```powershell
powershell -ExecutionPolicy Bypass -File scripts/mimic_windows_python_publish_workflow.ps1 `
  -WorkflowFile .github/workflows/cf_basic_io_windows_publish.yml `
  -PackageDir sandcastle/cf_basic_steps/cf_basic_io `
  -PythonExe py `
  -PythonVersion 3.14
```

Queue a dry-run dispatch:

```powershell
powershell -ExecutionPolicy Bypass -File scripts/queue_windows_python_publish_workflow.ps1 `
  -WorkflowFile .github/workflows/cf_basic_io_windows_publish.yml `
  -PackageDir sandcastle/cf_basic_steps/cf_basic_io `
  -PublishTarget testpypi `
  -Ref main `
  -RequireLocalPass `
  -DryRun
```

Watch queued runs:

```powershell
gh run list --workflow cf_basic_io_windows_publish.yml --limit 10
gh run watch --exit-status
```

