Skip to content
Open
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
8 changes: 8 additions & 0 deletions docs/source/simple.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ Fields that can be repeated (e.g. ``view``, ``dimension``, or ``join``) are comb
{'name': 'amount', 'sql': '${TABLE}.amount'},
{'name': 'status', 'sql': '${TABLE}.status'}]}

The ``keep_prefix`` parameter preserves leading comments and whitespace in a ``_prefix`` field.

.. doctest::

>>> result = lkml.load("# comment\ndimension: id {}", keep_prefix=True)
>>> result['_prefix']
'# comment\n'

Here's an example of some LookML that has been parsed into a dictionary. Note that the repeated key ``join`` has been transformed into a plural key ``joins``: a list of dictionaries representing each join::

{
Expand Down
6 changes: 5 additions & 1 deletion lkml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ def parse(text: str) -> DocumentNode:
return tree


def load(stream: Union[str, IO]) -> dict:
def load(stream: Union[str, IO], keep_prefix: bool = False) -> dict:
"""Parse LookML into a Python dictionary.

Args:
stream: File object or string containing LookML to be parsed
keep_prefix: If True, include the raw string of comments and whitespace
at the top of the document under the "_prefix" key.

Raises:
TypeError: If stream is neither a string or a file object
Expand All @@ -50,6 +52,8 @@ def load(stream: Union[str, IO]) -> dict:
tree: DocumentNode = parse(text)
visitor = DictVisitor()
tree_as_dict: dict = visitor.visit(tree)
if keep_prefix:
tree_as_dict["_prefix"] = tree.prefix
return tree_as_dict


Expand Down
10 changes: 10 additions & 0 deletions tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,13 @@ def test_repeated_dump_does_not_mutate_input():
first = lkml.dump(parsed)
second = lkml.dump(parsed)
assert first == second


def test_load_with_prefix():
raw_text = (Path(__file__).parent / "resources" / "view_with_all_fields.view.lkml").read_text(encoding="utf-8")
prefix = "# This is a comment\n# and another comment\n"
raw_text = f"{prefix}{raw_text}"
parsed = lkml.load(raw_text, keep_prefix=True)
assert parsed["_prefix"] == prefix
parsed_without_prefix = lkml.load(raw_text)
assert "_prefix" not in parsed_without_prefix