Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions .github/workflows/python-darwin-snippets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: python darwin snippets

on:
pull_request:
schedule:
- cron: "15 7 * * *"
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
sdk-versions:
runs-on: ubuntu-latest
outputs:
senzingsdk-versions: ${{ steps.cfg.outputs.senzingsdk-versions }}
steps:
- id: cfg
uses: senzing-factory/build-resources/sdk-versions@v4

python-darwin-snippets:
needs: sdk-versions
permissions:
contents: read
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.14"]
senzingsdk-version: ${{ fromJSON(needs.sdk-versions.outputs.senzingsdk-versions) }}

steps:
- name: checkout repository
uses: actions/checkout@v7.0.1
with:
persist-credentials: false

- name: set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7.0.0
with:
python-version: ${{ matrix.python-version }}

- name: install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --group test

- name: Mint staging tap token
if: matrix.senzingsdk-version != 'production-v4'
id: staging-token
uses: actions/create-github-app-token@v3.2.0
with:
client-id: ${{ secrets.SENZINGSDK_STAGING_CLIENT_ID }}
private-key: ${{ secrets.SENZINGSDK_STAGING_APP_KEY }}
owner: senzing-factory # zizmor: ignore[github-app]
repositories: homebrew-senzingsdk-staging
permission-contents: read

- name: install Senzing SDK
uses: senzing-factory/github-action-install-senzing-sdk@v5
with:
senzingsdk-version: ${{ matrix.senzingsdk-version }}
senzingsdk-token: ${{ steps.staging-token.outputs.token || github.token }}

- name: configure environment
run: |
SENZING_PATH="${HOME}/senzing"
{
echo "SENZING_PATH=${SENZING_PATH}"
echo "DYLD_LIBRARY_PATH=${SENZING_PATH}/er/lib:${SENZING_PATH}/er/lib/macos"
echo "PYTHONPATH=${SENZING_PATH}/er/sdk/python"
} >> "$GITHUB_ENV"

- name: run python snippets
run: |
python -m pytest -rs

- name: Notify Slack on failure
if: (failure() || cancelled()) && github.event_name == 'schedule'
uses: senzing-factory/build-resources/slack-failure-notification@v4
with:
job-status: ${{ job.status }}
slack-channel: ${{ secrets.SLACK_CHANNEL }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
additional-info: "SDK: ${{ matrix.senzingsdk-version }}, Python: ${{ matrix.python-version }}"
74 changes: 74 additions & 0 deletions .github/workflows/python-linux-snippets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: python linux snippets

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "15 7 * * *"
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
sdk-versions:
runs-on: ubuntu-latest
outputs:
senzingsdk-versions: ${{ steps.cfg.outputs.senzingsdk-versions }}
steps:
- id: cfg
uses: senzing-factory/build-resources/sdk-versions@v4

python-linux-snippets:
needs: sdk-versions
permissions:
contents: read
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
senzingsdk-version: ${{ fromJSON(needs.sdk-versions.outputs.senzingsdk-versions) }}

steps:
- name: checkout repository
uses: actions/checkout@v7.0.1
with:
persist-credentials: false

- name: set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7.0.0
with:
python-version: ${{ matrix.python-version }}

- name: install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --group test

- name: install Senzing runtime
uses: senzing-factory/github-action-install-senzing-sdk@v5
with:
packages-to-install: "senzingsdk-runtime senzingsdk-setup"
senzingsdk-version: ${{ matrix.senzingsdk-version }}

- name: run python snippets
env:
LD_LIBRARY_PATH: "/opt/senzing/er/lib"
PYTHONPATH: "/opt/senzing/er/sdk/python"
run: |
python -m pytest -rs

- name: Notify Slack on failure
if: (failure() || cancelled()) && github.event_name == 'schedule'
uses: senzing-factory/build-resources/slack-failure-notification@v4
with:
job-status: ${{ job.status }}
slack-channel: ${{ secrets.SLACK_CHANNEL }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
additional-info: "SDK: ${{ matrix.senzingsdk-version }}, Python: ${{ matrix.python-version }}"
84 changes: 84 additions & 0 deletions .github/workflows/python-windows-snippets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: python windows snippets

on:
pull_request:
schedule:
- cron: "15 7 * * *"
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
sdk-versions:
runs-on: ubuntu-latest
outputs:
senzingsdk-versions: ${{ steps.cfg.outputs.senzingsdk-versions }}
steps:
- id: cfg
uses: senzing-factory/build-resources/sdk-versions@v4

python-windows-snippets:
needs: sdk-versions
permissions:
contents: read
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.14"]
senzingsdk-version: ${{ fromJSON(needs.sdk-versions.outputs.senzingsdk-versions) }}

steps:
- name: checkout repository
uses: actions/checkout@v7.0.1
with:
persist-credentials: false

- name: set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7.0.0
with:
python-version: ${{ matrix.python-version }}

- name: install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --group test

- name: Mint staging bucket token
if: matrix.senzingsdk-version != 'production-v4'
id: staging-token
uses: actions/create-github-app-token@v3.2.0
with:
client-id: ${{ secrets.SENZINGSDK_STAGING_CLIENT_ID }}
private-key: ${{ secrets.SENZINGSDK_STAGING_APP_KEY }}
owner: senzing-factory # zizmor: ignore[github-app]
repositories: scoop-senzingsdk-staging
permission-contents: read

- name: install Senzing SDK
uses: senzing-factory/github-action-install-senzing-sdk@v5
with:
senzingsdk-version: ${{ matrix.senzingsdk-version }}
senzingsdk-token: ${{ steps.staging-token.outputs.token || github.token }}

- name: configure environment
run: |
Add-Content $env:GITHUB_PATH "$Env:USERPROFILE\senzing\er\lib"
Add-Content $env:GITHUB_ENV "PYTHONPATH=$Env:USERPROFILE\senzing\er\sdk\python"

- name: run python snippets
run: |
python -m pytest -rs

- name: Notify Slack on failure
if: (failure() || cancelled()) && github.event_name == 'schedule'
uses: senzing-factory/build-resources/slack-failure-notification@v4
with:
job-status: ${{ job.status }}
slack-channel: ${{ secrets.SLACK_CHANNEL }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
additional-info: "SDK: ${{ matrix.senzingsdk-version }}, Python: ${{ matrix.python-version }}"
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ dmypy.json
*.code-workspace
.history

# Output folder used by examples
resources/output/
# Output folder used by examples; keep the folder, ignore its contents
resources/output/*
!resources/output/.gitkeep

csharp/snippets/**/bin
csharp/snippets/**/obj
Expand Down
5 changes: 5 additions & 0 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"accessibilities",
"analysing",
"antaenc",
"autouse",
"Axxxx",
"barrycaceres",
"bugtracker",
Expand All @@ -22,6 +23,7 @@
"Dsenzing",
"DSRC",
"DYLD",
"executescript",
"findsecbugs",
"fpvs",
"glassfish",
Expand All @@ -44,11 +46,13 @@
"pylint",
"pypa",
"pytest",
"PYTHONPATH",
"RESOURCEPATH",
"Retryable",
"roslynator",
"Rotorville",
"schemaname",
"SENZ",
"Senzing",
"senzingsdk",
"setuptools",
Expand All @@ -64,6 +68,7 @@
"taskkill",
"temurin",
"terashuf",
"testpaths",
"tpascalcase",
"truthset",
"unresolve",
Expand Down
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,26 @@ All notable changes to this project will be documented in this file.
The changelog format is based on [Keep a Changelog] and [CommonMark].
This project adheres to [Semantic Versioning].

## [Unreleased]
## [0.0.11] - 2026-10-09

### Added in Unreleased
### Added in 0.0.11

- Java Migration Guide (`java/Migration.md`) covering the version 3.x to 4.0 SDK changes
- Python snippet tests (`python/tests`) running every snippet end to end against a temporary SQLite repository
- GitHub Actions workflows running the Python snippet tests on Linux, macOS and Windows

### Changed in 0.0.11

- Python snippets exit with status 1 and report to stderr when a Senzing error stops them
- `resources/output/` is now part of the repository so snippets writing with-info output work on a fresh clone
- `add_queue.py` uses a producer thread instead of separate processes, matching the Java and C# snippets
- `signal_handler.py` waits with a sleep loop instead of `signal.pause()`, which isn't available on Windows

### Fixed in 0.0.11

- `redo_with_info_continuous.py` raised a `TypeError` instead of exiting when a Senzing error occurred
- `add_queue.py` loaded no records but exited successfully on macOS, Windows and Python 3.14+, and could stop early if the
queue was momentarily empty

## [0.0.10] - 2025-08-11

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ test = [
"coverage==7.16.1; python_version > '3.11'",
]

[tool.pytest.ini_options]
testpaths = ["python/tests"]

[tool.setuptools]
package-dir = { "" = "python" }

Expand Down
14 changes: 14 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
# Python Snippets

## Running the tests

`python/tests` runs every snippet end to end as a subprocess, each against its own temporary SQLite repository, and checks it exits cleanly with nothing on stderr. Your `SENZING_ENGINE_CONFIGURATION_JSON` is not used and your repository is not touched.

```bash
export PYTHONPATH=/opt/senzing/er/sdk/python
export LD_LIBRARY_PATH=/opt/senzing/er/lib
python -m pytest
```

Senzing install locations default to `/opt/senzing/er`, `/opt/senzing/data` and `/etc/opt/senzing`; override them with the same environment variables the Java SnippetRunner uses: `SENZING_PATH`, `SENZING_DIR`, `SENZING_SUPPORT_DIR`, `SENZING_RESOURCE_DIR` and `SENZING_CONFIG_DIR`.

Snippets are discovered automatically. A snippet needing data loaded, registered data sources, console input or a ctrl-c to stop it gets an entry in `SNIPPETS` in `tests/test_snippets.py`.
1 change: 1 addition & 0 deletions python/configuration/get_config_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
print(response)
except SzError as err:
print(f"{err.__class__.__name__} - {err}", file=sys.stderr)
sys.exit(1)
1 change: 1 addition & 0 deletions python/configuration/get_data_source_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
print(response)
except SzError as err:
print(f"{err.__class__.__name__} - {err}", file=sys.stderr)
sys.exit(1)
1 change: 1 addition & 0 deletions python/configuration/init_default_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
print(f"New default config ID: {new_config_id}")
except SzError as err:
print(f"{err.__class__.__name__} - {err}", file=sys.stderr)
sys.exit(1)
1 change: 1 addition & 0 deletions python/configuration/register_data_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@
print(f"New default config ID: {new_config_id}")
except SzError as err:
print(f"{err.__class__.__name__} - {err}", file=sys.stderr)
sys.exit(1)
1 change: 1 addition & 0 deletions python/deleting/delete_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@ def futures_del(engine, input_file):
futures_del(sz_engine, INPUT_FILE)
except SzError as err:
mock_logger("CRITICAL", err)
sys.exit(1)
1 change: 1 addition & 0 deletions python/deleting/delete_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ def del_records_from_file(engine, input_file):
del_records_from_file(sz_engine, INPUT_FILE)
except SzError as err:
mock_logger("CRITICAL", err)
sys.exit(1)
1 change: 1 addition & 0 deletions python/deleting/delete_with_info_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ def futures_del(engine, input_file, output_file):
futures_del(sz_engine, INPUT_FILE, OUTPUT_FILE)
except SzError as err:
mock_logger("CRITICAL", err)
sys.exit(1)
Loading
Loading