Skip to content

#52 - Additional Python snippets #64

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog], [markdownlint],
and this project adheres to [Semantic Versioning].

## [0.0.10] - 2025-08-11

### Added in 0.0.10

- New Python snippets

## [0.0.9] - 2025-07-23

### Changed in 0.0.9
Expand Down
2 changes: 1 addition & 1 deletion python/deleting/delete_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def futures_del(engine, input_file):

del futures[f]

print(f"\nSuccessfully deleted {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully deleted {success_recs:,} records, with {error_recs:,} errors")


try:
Expand Down
2 changes: 1 addition & 1 deletion python/deleting/delete_with_info_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def futures_del(engine, input_file, output_file):

del futures[f]

print(f"\nSuccessfully deleted {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully deleted {success_recs:,} records, with {error_recs:,} errors")
print(f"\nWith info responses written to {output_file}")


Expand Down
2 changes: 1 addition & 1 deletion python/information/get_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def futures_add(engine, input_file):

del futures[f]

print(f"\nSuccessfully loaded {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully loaded {success_recs:,} records, with {error_recs:,} errors")


try:
Expand Down
9 changes: 7 additions & 2 deletions python/initialization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
- Priming the Senzing engine before use loads resource intensive assets upfront.
- Without priming the first SDK call to the engine will appear slower than usual as it causes these assets to be loaded.
- **factory_destroy.py**
- Calls `destroy` on the abstract factory destroying the abstract factory and any Senzing objects it has created.
- Calls `destroy()` on the abstract factory destroying the abstract factory and any Senzing objects it has created.
- The abstract factory must exist for the life of Senzing objects it has created.
- If the abstract factory goes out of scope `destroy` is automatically called
- If the abstract factory goes out of scope `destroy()` is automatically called
- **purge_repository.py**
- **WARNING** This script will remove all data from a Senzing repository, use with caution! **WARNING**.
- It will prompt first, still use with caution!.
**signal_handler.py**
- Catches signal.SIGINT (ctrl + c) and exits cleanly
- Exiting cleanly on a signal ensures resource cleanup for the abstract factory is automatically called
- If sz_abstract_factory goes out of scope 'destroy()` is automatically called, if signals are not caught and handled automatic resource cleanup does not happen
- `destroy()` could also be called directly on the abstract factory by the signal handler
- **sz_engine_config_ini_to_json.py**
- The snippets herein utilize the `SENZING_ENGINE_CONFIGURATION_JSON` environment variable for Senzing abstract factory creation.
- If you are familiar with working with a Senzing project you may be aware the same configuration data is held in the sz_engine_config.ini file.
Expand Down
29 changes: 29 additions & 0 deletions python/initialization/signal_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#! /usr/bin/env python3

import os
import signal
import sys
from pathlib import Path

from senzing import SzError
from senzing_core import SzAbstractFactoryCore

INSTANCE_NAME = Path(__file__).stem
SETTINGS = os.getenv("SENZING_ENGINE_CONFIGURATION_JSON", "{}")


def handler(signum, frame):
print("\nCaught ctrl-c, exiting")
sys.exit(0)


signal.signal(signal.SIGINT, handler)

try:
sz_abstract_factory = SzAbstractFactoryCore(INSTANCE_NAME, SETTINGS)
sz_engine = sz_abstract_factory.create_engine()
# Do work...
print("\nSimulating work, press ctrl-c to exit...")
signal.pause()
except SzError as err:
print(f"\n{err.__class__.__name__} - {err}")
2 changes: 1 addition & 1 deletion python/loading/add_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def futures_add(engine, input_file):

del futures[f]

print(f"\nSuccessfully loaded {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully loaded {success_recs:,} records, with {error_recs:,} errors")


try:
Expand Down
2 changes: 1 addition & 1 deletion python/loading/add_with_info_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def futures_add(engine, input_file, output_file):

del futures[f]

print(f"\nSuccessfully loaded {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully loaded {success_recs:,} records, with {error_recs:,} errors")
print(f"\nWith info responses written to {output_file}")


Expand Down
4 changes: 2 additions & 2 deletions python/redo/add_with_redo.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def process_redo(engine):

success_recs += 1
if success_recs % 1 == 0:
print(f"Processed {success_recs:,} redo records, with" f" {error_recs:,} errors")
print(f"Processed {success_recs:,} redo records, with {error_recs:,} errors")
except SzBadInputError as err:
mock_logger("ERROR", err)
error_recs += 1
Expand All @@ -77,7 +77,7 @@ def process_redo(engine):
mock_logger("CRITICAL", err)
raise err

print(f"\nSuccessfully processed {success_recs:,} redo records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully processed {success_recs:,} redo records, with {error_recs:,} errors")


try:
Expand Down
12 changes: 10 additions & 2 deletions python/redo/redo_continuous.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/env python3

import os
import signal
import sys
import time
from pathlib import Path
Expand All @@ -12,6 +13,11 @@
SETTINGS = os.getenv("SENZING_ENGINE_CONFIGURATION_JSON", "{}")


def handler(signum, frame):
print("\nCaught ctrl-c, exiting")
sys.exit(0)


def mock_logger(level, error, error_record=None):
print(f"\n{level}: {error.__class__.__name__} - {error}", file=sys.stderr)
if error_record:
Expand All @@ -27,7 +33,7 @@ def process_redo(engine):
if not (response := engine.get_redo_record()):
print(
"No redo records to process, pausing for 30 seconds. Total"
f" processed {success_recs:,} . (CTRL-C to exit)..."
f" processed: {success_recs:,} (ctrl-c to exit)..."
)
time.sleep(30)
continue
Expand All @@ -36,7 +42,7 @@ def process_redo(engine):

success_recs += 1
if success_recs % 100 == 0:
print(f"Processed {success_recs:,} redo records, with" f" {error_recs:,} errors")
print(f"Processed {success_recs:,} redo records, with {error_recs:,} errors")
except SzBadInputError as err:
mock_logger("ERROR", err)
error_recs += 1
Expand All @@ -47,6 +53,8 @@ def process_redo(engine):
raise err


signal.signal(signal.SIGINT, handler)

try:
sz_factory = SzAbstractFactoryCore(INSTANCE_NAME, SETTINGS, verbose_logging=False)
sz_engine = sz_factory.create_engine()
Expand Down
12 changes: 10 additions & 2 deletions python/redo/redo_continuous_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import concurrent.futures
import os
import signal
import sys
import time
from pathlib import Path
Expand All @@ -13,6 +14,11 @@
SETTINGS = os.getenv("SENZING_ENGINE_CONFIGURATION_JSON", "{}")


def handler(signum, frame):
print("\nCaught ctrl-c, exiting")
sys.exit(0)


def mock_logger(level, error, error_record=None):
print(f"\n{level}: {error.__class__.__name__} - {error}", file=sys.stderr)
if error_record:
Expand Down Expand Up @@ -50,7 +56,7 @@ def redo_count(engine):


def redo_pause(success):
print("No redo records to process, pausing for 30 seconds. Total processed:" f" {success:,} (CTRL-C to exit)...")
print(f"No redo records to process, pausing for 30 seconds. Total processed: {success:,} (ctrl-c to exit)...")
time.sleep(30)


Expand Down Expand Up @@ -88,7 +94,7 @@ def futures_redo(engine):
else:
success_recs += 1
if success_recs % 100 == 0:
print(f"Processed {success_recs:,} redo records, with" f" {error_recs:,} errors")
print(f"Processed {success_recs:,} redo records, with {error_recs:,} errors")
finally:
if not shutdown and (record := get_redo_record(engine)):
futures[executor.submit(process_redo_record, engine, record)] = record
Expand All @@ -106,6 +112,8 @@ def futures_redo(engine):
futures[executor.submit(process_redo_record, engine, record)] = record


signal.signal(signal.SIGINT, handler)

try:
sz_factory = SzAbstractFactoryCore(INSTANCE_NAME, SETTINGS, verbose_logging=False)
sz_engine = sz_factory.create_engine()
Expand Down
13 changes: 9 additions & 4 deletions python/redo/redo_with_info_continuous.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@
SETTINGS = os.getenv("SENZING_ENGINE_CONFIGURATION_JSON", "{}")


def responses_message(signum, frame):
def handler(signum, frame):
print("\nCaught ctrl-c, exiting")
print(f"\nWith info responses written to {OUTPUT_FILE}")
sys.exit(0)


def responses_message(signum, frame):
sys.exit()


Expand All @@ -32,7 +37,7 @@ def mock_logger(level, error, error_record=None):


def redo_pause(success):
print("No redo records to process, pausing for 30 seconds. Total processed:" f" {success:,} (CTRL-C to exit)...")
print(f"No redo records to process, pausing for 30 seconds. Total processed: {success:,} (ctrl-c to exit)...")
time.sleep(30)


Expand All @@ -53,7 +58,7 @@ def process_redo(engine, output_file):
out_file.write(f"{response}\n")

if success_recs % 100 == 0:
print(f"Processed {success_recs:,} redo records, with" f" {error_recs:,} errors")
print(f"Processed {success_recs:,} redo records, with {error_recs:,} errors")
except SzBadInputError as err:
mock_logger("ERROR", err, redo_record)
error_recs += 1
Expand All @@ -65,7 +70,7 @@ def process_redo(engine, output_file):
raise err


signal.signal(signal.SIGINT, responses_message)
signal.signal(signal.SIGINT, handler)

try:
sz_factory = SzAbstractFactoryCore(INSTANCE_NAME, SETTINGS, verbose_logging=False)
Expand Down
2 changes: 1 addition & 1 deletion python/searching/search_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def futures_search(engine, input_file):

del futures[f]

print(f"\nSuccessfully searched {success_recs:,} records, with" f" {error_recs:,} errors")
print(f"\nSuccessfully searched {success_recs:,} records, with {error_recs:,} errors")


try:
Expand Down
Loading