search-names
search-names prepares lists of personal names and searches them in CSV text
corpora. Its four-stage workflow cleans names, adds aliases and titles, creates
search patterns, and runs deterministic exact or fuzzy matching.
Name matching is approximate record linkage, not identity verification. Common names, aliases, OCR errors, and incomplete source data can create false matches or missed matches. Review matches in context; do not use them alone for consequential decisions or to infer protected or sensitive traits.
Installation
pip install search-names
The installation includes the name parsers, spaCy interface, Sentence Transformers interface, and CLI.
Search a corpus
The search input is a CSV or .csv.gz file. The names are (identifier, name)
pairs. Output contains one row per input row in the same order, fixed match
slots, and a count column.
from search_names import search_names
stats = search_names(
"articles.csv",
[("person-1", "Jane Doe"), ("person-2", "John Smith")],
"matches.csv",
text_column="article_text",
input_columns=("article_id", "article_text"),
max_results=10,
processes=4,
)
print(stats)
Fuzzy rules are (minimum name length, maximum edit distance) pairs. Later
rules take precedence for longer names:
stats = search_names(
"ocr_articles.csv.gz",
[("person-1", "Jane Doe"), ("person-2", "John Smith")],
"matches.csv",
fuzzy_rules=[(8, 1), (15, 2)],
processes=4,
)
To load a pattern table produced by the preprocessing stage:
from search_names.pipeline.step4_search import load_names_file
names = load_names_file(
"preprocessed_names.csv",
id_column="uniqid",
name_column="search_name",
)
CSV and compressed CSV are supported import/export boundaries. The package does not ship schema-less CSV runtime assets or learned model weights in its wheel.
Prepare names
from search_names import augment_names, clean_names, preprocess
clean_names(
input_file="raw_names.csv",
output_file="clean_names.csv",
name_column="Name",
keep_duplicates=False,
)
augment_names(
input_file="clean_names.csv",
prefix_column="seat",
name_column="FirstName",
output_file="augmented_names.csv",
prefix_file="prefixes.csv",
nickname_file="nick_names.txt",
)
preprocess(
input_file="augmented_names.csv",
patterns=["FirstName LastName", "NickName LastName", "Prefix LastName"],
output_file="preprocessed_names.csv",
edit_length_thresholds=[10, 15],
drop_patterns=["ambiguous pattern"],
)
The preprocessing stage’s edit-length thresholds are retained in its output.
The search API uses the explicit fuzzy_rules pairs shown above.
Parse names
NameParser combines nameparser with parsernaam. The latter returns a model
label (first, last, first_last, or last_first) and probability;
search-names converts that record to explicit components. Probabilities below
ml_threshold fall back to deterministic nameparser parsing. Deterministic
parses have model_score=None; the package does not invent a confidence value.
from search_names.enhanced_name_parser import NameParser
parser = NameParser(parser_type="parsernaam", ml_threshold=0.8)
parsed = parser.parse("Nakamura Hiro")
print(parsed.first_name, parsed.last_name, parsed.model_score)
DataFrame parsing returns a copy, preserves the input index, and replaces any colliding parsed-output columns deliberately:
result = parser.parse_dataframe(frame, name_column="full_name")
NLP components
The NLP module exposes spaCy NER, semantic similarity, and entity linking:
from search_names.nlp_engine import NLPEngine
engine = NLPEngine(
knowledge_base={"Jane Doe": {"aliases": ["J. Doe"]}},
enable_ner=True,
enable_similarity=True,
enable_linking=True,
)
result = engine.process_text("Jane Doe spoke today.", link_entities=True)
Entity-linking results identify the lookup method (exact, normalized, or
semantic). Only semantic matches have a numeric score, which is cosine
similarity rather than a calibrated probability.
The default Sentence Transformer is downloaded from an immutable 40-character
Hugging Face revision. The Hugging Face client automatically honors its normal
authentication settings, including HF_TOKEN; public downloads do not require
a token. The spaCy English model must be installed separately for NER:
python -m spacy download en_core_web_sm
Command line
search-names --help
search-names clean raw_names.csv --output clean_names.csv
search-names preprocess augmented_names.csv --output preprocessed_names.csv
search-names search articles.csv --names preprocessed_names.csv \
--output matches.csv --text-column text --processes 4
search-names search ocr_articles.csv --names preprocessed_names.csv \
--fuzzy-rule 8:1 --fuzzy-rule 15:2
Development
uv sync --all-groups
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv build
The API documentation is generated from this README and the package docstrings, so usage and reference material do not drift into separate hand-maintained copies.
License
MIT. See the repository's LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file search_names-0.6.0.tar.gz.
File metadata
- Download URL: search_names-0.6.0.tar.gz
- Upload date:
- Size: 25.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c32f43b4aa7faa85e38d8e7bc29a1b30129bed046d83703d847c815fd7aefec
|
|
| MD5 |
aee86c0cc0bfcacd800ccc2c23056987
|
|
| BLAKE2b-256 |
29cec36a4361b1624bba6b91a044eb238b5194044be13b422fc56a5e7a063fa9
|
Provenance
The following attestation bundles were made for search_names-0.6.0.tar.gz:
Publisher:
release.yml on appeler/search-names
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
search_names-0.6.0.tar.gz -
Subject digest:
6c32f43b4aa7faa85e38d8e7bc29a1b30129bed046d83703d847c815fd7aefec - Sigstore transparency entry: 2506768428
- Sigstore integration time:
-
Permalink:
appeler/search-names@cb4602d5c1889f92c112ca606818147dd9527eac -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/appeler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cb4602d5c1889f92c112ca606818147dd9527eac -
Trigger Event:
push
-
Statement type:
File details
Details for the file search_names-0.6.0-py3-none-any.whl.
File metadata
- Download URL: search_names-0.6.0-py3-none-any.whl
- Upload date:
- Size: 30.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0db41ede6d2c09ae2b944fe307cfece8ac0019832118caca43524dbc56b291a4
|
|
| MD5 |
875c0a7b2668c395bead5e4c9db05cdb
|
|
| BLAKE2b-256 |
6b092cf748e0809ab9610a829dc829ba67cb4be41e60d0ddbe04dd32bc3be649
|
Provenance
The following attestation bundles were made for search_names-0.6.0-py3-none-any.whl:
Publisher:
release.yml on appeler/search-names
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
search_names-0.6.0-py3-none-any.whl -
Subject digest:
0db41ede6d2c09ae2b944fe307cfece8ac0019832118caca43524dbc56b291a4 - Sigstore transparency entry: 2506768471
- Sigstore integration time:
-
Permalink:
appeler/search-names@cb4602d5c1889f92c112ca606818147dd9527eac -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/appeler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cb4602d5c1889f92c112ca606818147dd9527eac -
Trigger Event:
push
-
Statement type: