Protocols & Interfaces
Relevant source files
The following files were used as context for generating this wiki page:
The Protocols & Interfaces system in flext-tap-ldif establishes a strictly typed contract for data extraction from LDIF (LDAP Data Interchange Format) files. It leverages Python's Protocol for structural subtyping, ensuring that components like file processors, data providers, and validation logic adhere to a unified interface while maintaining decoupling between the core tap logic and its dependencies.
The architecture relies on a Method Resolution Order (MRO) chain that composes functionality from flext-ldif (parsing) and flext-meltano (Singer tap infrastructure). This design facilitates a "Zero-Debt Baseline" where domain-specific protocols for the LDIF tap are minimized to only what is necessary for workspace consumption, relying primarily on established parent MRO facades for standard operations.
Sources: src/flext_tap_ldif/protocols.py:1-20, AGENTS.md:1-50, README.md:1-30
Protocol Architecture
The core protocol facade, FlextTapLdifProtocols, serves as the primary integration point. It does not define new methods locally but inherits from meltano_p (Flext Meltano Protocols) and FlextLdifProtocols. This composition allows the tap to handle Singer-specific stream operations and LDIF-specific parsing through a single unified interface.
Inheritance Structure
The following diagram illustrates the relationship between the tap's protocols and the underlying framework protocols.
The hierarchy ensures that the LDIF tap can utilize standard Singer tap interfaces while understanding specific LDIF data structures.
Sources: src/flext_tap_ldif/protocols.py:12-16, tests/protocols.py:16-20
Data Processing Interfaces
Internal utilities implement specific logic for handling the nuances of LDIF data, such as base64 encoded values and line continuations. While not all are exposed as public runtime_checkable protocols, they define the internal interface for data transformation.
LDIF Line Parsing
The LdifDataProcessing utility provides methods to handle different LDIF line formats, including standard attributes, base64 encoded values (::), and URL references (:<).
| Method | Input | Output | Description |
|---|---|---|---|
parse_ldif_line | str | p.Result[t.StrPair] | Decodes LDIF lines, including Base64 decoding for values preceded by ::. |
normalize_ldif_attribute_name | str | str | Converts LDAP attributes to JSON-safe keys (e.g., lowercasing, replacing invalid chars). |
build_record_from_lines | t.StrSequence | t.MutableAttributeMapping | Aggregates multi-line LDIF entries into a single record dictionary. |
Sources: src/flext_tap_ldif/_utilities/data_processing.py:14-105
Processing Flow
The Processor class acts as the bridge between the filesystem and the Singer stream, yielding validated records.
The processor uses the flext_ldif API to parse content and maps the resulting entries to the internal LdifEntry model.
Sources: src/flext_tap_ldif/_utilities/processor.py:22-65
Testing Protocols
Testing interfaces are separated into a dedicated TapLdif namespace within TestsFlextTapLdifProtocols. These protocols are runtime_checkable, allowing for robust mocking of file operations and data providers during unit and integration testing.
Key Test Protocols
| Protocol | Purpose | Key Methods |
|---|---|---|
MockLdifFile | Mocks file system interactions. | open_file, read_entries |
TestLdifDataProvider | Supplies static data for test scenarios. | test_entries, test_config |
TestLdifAssertion | Standardizes assertions for LDIF data. | assert_ldif_file_parsed, assert_ldif_entries_valid |
Sources: tests/protocols.py:32-98
Test Assertion Logic Snippet
@runtime_checkable
class TestLdifAssertion(Protocol):
"""Protocol for test LDIF assertions."""
def assert_ldif_file_parsed(self, entries: t.SequenceOf[t.JsonMapping]) -> None: ...
def assert_ldif_entries_valid(self, entries: t.SequenceOf[t.JsonMapping]) -> None: ...
Sources: tests/protocols.py:78-95
Model Interfaces
Data models in flext-tap-ldif define the schema for LDIF entries and file metadata. These models act as the data contract between the parser and the Singer output.
LdifEntry Model
The LdifEntry model represents a single LDAP object. It includes logic to automatically include objectClass values in the attribute mapping if they are provided separately.
| Field | Type | Description |
|---|---|---|
dn | str | The Distinguished Name (Required). |
attributes | t.MappingKV | Dictionary of attribute names to sequences of strings. |
object_classes | t.StrSequence | List of object classes associated with the entry. |
line_number | int | The starting line number in the source file. |
Sources: src/flext_tap_ldif/_models/entry.py:18-60
File Metadata Model
The LdifFile model tracks the state of file processing, supporting incremental syncs by recording the last processed line and file size.
Summary
The protocols and interfaces within flext-tap-ldif provide a structured, type-safe framework for extracting and validating LDIF data. By composing functionality from core libraries and enforcing strict models for entries and file metadata, the system ensures that data remains consistent from the raw file format through to the Singer-compatible JSON output. The use of clear namespaces for testing protocols further enhances the maintainability and testability of the extraction logic.