Views and Backends¶
This page explains a core httk₂ design pattern used in httk.core.datastream and applicable to other domains (for example, structures).
For detailed datastream usage and API-oriented examples, see Datastreams.
The Pattern¶
The pattern has three pieces:
XBackend: internal carrier for one representation of data (TextstreamFilename,TextstreamString,BytestreamBytes, …).XView: user-facing interface for how you want to work with that data right now (TextstreamStringView,BytestreamFileView, …).XLike: union type accepted by API functions so callers can pass many natural inputs.
Typical flow inside a function:
Accept
XLike.Convert once to a specific view that matches your algorithm.
Write the algorithm only against that view.
This keeps APIs flexible for callers and keeps implementation logic simple and consistent.
Why This Is Useful¶
Callers can use whichever representation they already have:
a filename
an open file object
raw in-memory data (
str,bytes)an existing backend or view
Function code still stays clean because it normalizes to a single view immediately.
Concrete Example: Datastreams¶
Datastream normalization uses this pattern:
text data:
TextstreamLike->Textstream...View->Textstream...Backend
byte data:
BytestreamLike->Bytestream...View->Bytestream...Backend
In both cases, function authors can immediately normalize input into one view and then write logic against that one interface only.
from httk.core import TextstreamFileView, TextstreamLike
def process_text(slike: TextstreamLike, **hints: object) -> list[str]:
stream = TextstreamFileView(slike, **hints)
return [line.strip() for line in stream]
Generalization: Other Domains (Structures)¶
The same pattern applies to richer domains such as structures:
from httk.atomistic import StructureLike, ASEAtomsView
def compute_bandpath(slike: StructureLike) -> list[tuple[float, float, float]]:
atoms = ASEAtomsView(slike)
# Algorithm only depends on the ASE Atoms view interface.
cell = atoms.cell
...
StructureLike is the accepted input union, while ASEAtomsView is the normalized working interface.
As with datastreams, this lets callers pass many natural representations without complicating algorithm code.
Views are usually lazy: construction stores only the backend, and presentation state converts on first access and is kept. Views where that is impossible — immutable builtin subclasses, external mutable objects, or documented construction-time validation — stay eager.
Design Guidance¶
When introducing a new domain (X), keep these rules:
Define a clear
XLiketype for accepted inputs.Keep
XBackendfocused on representation and state.Keep
XViewfocused on interface ergonomics.In user-facing functions, normalize early (
xview = XSomeView(xlike)).Document ambiguity hints when one raw type can represent multiple meanings.