{"id":4613,"library":"lkml","title":"lkml Python LookML Parser","description":"lkml is a speedy LookML parser and serializer implemented in pure Python. It parses LookML strings into Python dictionaries and serializes Python dictionaries back into LookML strings. The library is actively maintained with frequent minor releases to support new LookML syntax and improve parsing/serialization accuracy.","status":"active","version":"1.3.7","language":"en","source_language":"en","source_url":"https://github.com/joshtemple/lkml","tags":["LookML","parser","serializer","data modeling","Looker"],"install":[{"cmd":"pip install lkml","lang":"bash","label":"Install lkml"}],"dependencies":[],"imports":[{"symbol":"load","correct":"from lkml import load"},{"symbol":"dump","correct":"from lkml import dump"}],"quickstart":{"code":"import lkml\n\nlookml_content = '''\nview: users {\n  sql_table_name: `analytics.users`;;\n  dimension: id {\n    primary_key: yes\n    type: number\n    sql: ${TABLE}.id ;;\n  }\n}\n'''\n\n# Parse LookML to a Python dictionary\nparsed_lookml = lkml.load(lookml_content)\nprint(\"Parsed LookML:\", parsed_lookml)\n\n# Modify the dictionary (e.g., change dimension type)\nfor view in parsed_lookml.get('views', []):\n    if view.get('name') == 'users':\n        for dimension in view.get('dimensions', []):\n            if dimension.get('name') == 'id':\n                dimension['type'] = 'string'\n\n# Serialize the Python dictionary back to LookML\nmodified_lookml = lkml.dump(parsed_lookml)\nprint(\"\\nModified LookML:\\n\", modified_lookml)","lang":"python","description":"This quickstart demonstrates how to parse a LookML string into a Python dictionary using `lkml.load()`, modify the resulting dictionary, and then serialize it back into a LookML string using `lkml.dump()`. This mirrors the common pattern for programmatic LookML manipulation."},"warnings":[{"fix":"For simple parsing/serialization, accept the opinionated formatting. For precise control, utilize the lower-level `lkml.parse()` to get a `DocumentNode` and manipulate the parse tree directly, then use `lkml.tree.DocumentNode.to_lookml()`.","message":"`lkml.load()` discards comments and most original whitespace by default. When a dictionary is serialized back to LookML using `lkml.dump()`, the output will follow lkml's opinionated formatting, losing any original comments or custom whitespace. For lossless round-trip parsing that preserves comments and whitespace, direct manipulation of the parse tree (`lkml.tree`) is required.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Thoroughly test and validate the structure of the Python dictionaries before serializing them with `lkml.dump()` to ensure they conform to LookML syntax rules.","message":"`lkml.dump()` does not perform semantic validation of the generated LookML. It only guarantees that the output can be successfully parsed by `lkml.load()`. It is the developer's responsibility to ensure the input Python dictionary represents valid LookML constructs to avoid generating malformed or non-functional LookML.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade `lkml` to version `1.3.2` or later. If unable to upgrade, pass a copy of the dictionary to `lkml.dump()` (e.g., `lkml.dump(my_dict.copy())`) to prevent mutations of the original object.","message":"In versions prior to `1.3.1` and `1.3.2`, `lkml.dump()` could unexpectedly mutate the input Python dictionary. This behavior was fixed, preventing unintended side effects on the original data structure.","severity":"breaking","affected_versions":"< 1.3.1"},{"fix":"When working with the parsed Python dictionary, always expect repeated LookML fields to be represented as lists under their pluralized key names. Consult `lkml.keys` for a definitive list of pluralized keys and special cases.","message":"LookML keys that can be repeated (e.g., `dimension`, `view`, `join`) are automatically converted into pluralized lists (e.g., `dimensions`, `views`, `joins`) when parsed into a Python dictionary. Special handling exists for keys like `allowed_value` and contents of the `query` block, which might also be lists but are not pluralized.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}