Skip to main content

📄⚙️ Pyvider HCL

License Python 3.11+ uv Ruff CI

Python library for parsing HCL into pyvider.cty types

pyvider-hcl provides a simple and intuitive way to work with HCL (HashiCorp Configuration Language) data in your Python applications, with seamless integration into the pyvider ecosystem.

✨ Key Features

  • 🔄 CTY Integration - Parses HCL directly into CtyValue objects for pyvider compatibility
  • 🎯 Simplified API - Clean interface for parsing HCL and creating Terraform structures
  • 🔍 Automatic Type Inference - Infer CtyType from HCL data without explicit schemas
  • ✅ Schema Validation - Validate HCL data against CTY type schemas
  • 🏭 Factory Functions - Create Terraform variables and resources programmatically
  • 🖨️ Pretty Printing - Debug-friendly output for CTY values

Quick Start

Note: pyvider-hcl is in pre-release (v0.x.x). APIs and features may change before 1.0 release.

  1. Install: uv add pyvider-hcl
  2. Read the Getting Started guide.
  3. Try the examples in examples/README.md.

Documentation

Development

Quick Start

# Set up environment
uv sync

# Run common tasks
we run test       # Run tests
we run lint       # Check code
we run format     # Format code
we tasks          # See all available commands

See CLAUDE.md for detailed development instructions and architecture information.

For contribution guidelines, see CONTRIBUTING.md.

Format and lint

uv run ruff format .
uv run ruff check .

Contributing

See CONTRIBUTING.md for contribution guidelines.

License

Apache-2.0 License - see LICENSE for details.

Installation

To install pyvider-hcl, you can use uv:

uv add pyvider-hcl

Usage

Here's a simple example of how to use pyvider-hcl to parse an HCL string:

from pyvider.hcl import parse_hcl_to_cty, pretty_print_cty
from pyvider.cty import CtyString

hcl_string = """
  name = "Jules"
  age = 30
"""

cty_value = parse_hcl_to_cty(hcl_string)

pretty_print_cty(cty_value)

You can also parse an HCL file:

from pyvider.hcl import parse_hcl_to_cty, pretty_print_cty

with open("my_config.hcl", "r") as f:
    hcl_content = f.read()
    cty_value = parse_hcl_to_cty(hcl_content)
    pretty_print_cty(cty_value)

Schema Validation

You can validate HCL data against a CtyType schema:

from pyvider.hcl import parse_hcl_to_cty, pretty_print_cty
from pyvider.cty import CtyObject, CtyString, CtyNumber

schema = CtyObject({
    "name": CtyString(),
    "age": CtyNumber(),
})

hcl_string = """
  name = "Jules"
  age = "thirty" # Invalid type
"""

try:
    cty_value = parse_hcl_to_cty(hcl_string, schema=schema)
except Exception as e:
    print(e)

Complex Cty Integration Examples

Here are some more complex examples of how to use pyvider-hcl with pyvider.cty:

Parsing a list of objects

from pyvider.hcl import parse_hcl_to_cty, pretty_print_cty
from pyvider.cty import CtyObject, CtyList, CtyString, CtyNumber

hcl_string = """
  users = [
    {
      name = "Jules"
      age  = 30
    },
    {
      name = "Vincent"
      age  = 40
    }
  ]
"""

schema = CtyObject({
    "users": CtyList(
        element_type=CtyObject({
            "name": CtyString(),
            "age": CtyNumber(),
        })
    )
})

cty_value = parse_hcl_to_cty(hcl_string, schema=schema)

pretty_print_cty(cty_value)

Parsing nested objects

from pyvider.hcl import parse_hcl_to_cty, pretty_print_cty
from pyvider.cty import CtyObject, CtyString, CtyNumber

hcl_string = """
  config = {
    server = {
      host = "localhost"
      port = 8080
    }
    database = {
      host = "localhost"
      port = 5432
    }
  }
"""

schema = CtyObject({
    "config": CtyObject({
        "server": CtyObject({
            "host": CtyString(),
            "port": CtyNumber(),
        }),
        "database": CtyObject({
            "host": CtyString(),
            "port": CtyNumber(),
        }),
    })
})

cty_value = parse_hcl_to_cty(hcl_string, schema=schema)

pretty_print_cty(cty_value)

Creating Terraform Variables and Resources

You can use the factory functions to create CtyValue objects for Terraform variables and resources:

from pyvider.hcl import (
    parse_hcl_to_cty,
    pretty_print_cty,
    create_variable_cty,
    create_resource_cty,
)

# Create a variable
variable_cty = create_variable_cty(
    name="my_variable",
    type_str="string",
    default_py="my_default_value",
)

pretty_print_cty(variable_cty)

# Create a resource
resource_cty = create_resource_cty(
    r_type="my_resource",
    r_name="my_instance",
    attributes_py={
        "name": "my_resource_name",
        "value": 123,
    },
)

pretty_print_cty(resource_cty)

FAQ

How do I parse an HCL file?

Currently, you need to read the file manually and pass the content to parse_hcl_to_cty():

from pathlib import Path
from pyvider.hcl import parse_hcl_to_cty

hcl_content = Path("config.hcl").read_text()
result = parse_hcl_to_cty(hcl_content)

Can this library generate HCL output?

Yes. cty_to_hcl() renders an object- or map-typed CtyValue back into formatted HCL text:

from pyvider.hcl import cty_to_hcl, parse_hcl_to_cty

print(cty_to_hcl(parse_hcl_to_cty('name = "example"\nport = 8080\n')))

Everything is emitted as an attribute — a CtyValue carries no notion of HCL blocks, so block structure cannot be recovered from one. Unknown values and marked (e.g. sensitive) values are refused rather than rendered.

For a human-readable rendering rather than HCL, use format_cty() (returns a string) or pretty_print_cty() (prints it).

Does this support HCL expressions like var.name or length(list)?

Not yet. The library currently parses static HCL data. Expression evaluation (variables, functions, conditionals) is not implemented.

What's the difference between parse_hcl_to_cty() and parse_with_context()?

  • parse_hcl_to_cty(): Returns a CtyValue object with full type information. Use this for most cases.
  • parse_with_context(): Returns raw Python dict/list from the parser. Use this when you need the raw data structure or want enhanced error context without CTY conversion.

How do I validate HCL against a specific structure?

Pass a CTY schema to parse_hcl_to_cty():

from pyvider.hcl import parse_hcl_to_cty
from pyvider.cty import CtyObject, CtyString, CtyNumber

schema = CtyObject({
    "name": CtyString(),
    "port": CtyNumber(),
})

result = parse_hcl_to_cty(hcl_content, schema=schema)
# Raises HclParsingError if validation fails

Can I use this with Terraform configurations?

Yes! The library parses HCL syntax used by Terraform. The create_variable_cty() and create_resource_cty() factory functions help create Terraform-specific structures. Full Terraform-specific validation (provider blocks, module blocks, etc.) is limited.

What HCL version is supported?

The library uses python-hcl2 which supports HCL 2.x (the version used by Terraform 0.12+).

How do I handle parsing errors?

Wrap your parsing calls in a try/except block:

from pyvider.hcl import parse_hcl_to_cty, HclParsingError

try:
    result = parse_hcl_to_cty(hcl_content)
except HclParsingError as e:
    print(f"Parsing failed: {e}")
    # e.source_file, e.line, e.column available if set

Can I parse multiple HCL files at once?

You need to parse each file individually. For multi-file Terraform projects, parse each file separately and combine the results as needed.

What types can be automatically inferred?

When no schema is provided, the library automatically infers:

  • string → CtyString
  • number (int/float) → CtyNumber
  • bool → CtyBool
  • list → CtyList(CtyDynamic())
  • object → CtyObject with inferred field types

How do I contribute or report bugs?

See CONTRIBUTING.md for contribution guidelines. For bugs, please open an issue on the GitHub repository with:

  • The HCL content that fails
  • The error message
  • Expected vs. actual behavior

Related Projects

Copyright (c) provide.io LLC.

Metadata

Release files for pyvider-hcl 0.6.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyvider-hcl 0.6.4
File Size Uploaded
pyvider_hcl-0.6.4.tar.gz 39.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyvider-hcl 0.6.4
File Interpreter ABI Platform
pyvider_hcl-0.6.4-py3-none-any.whl Python 3 none any Details

Total release size: 75.5 kB

Release files / pyvider_hcl-0.6.4.tar.gz

Download URL pyvider_hcl-0.6.4.tar.gz
Size 39.0 kB
Tags Source
SHA-256 checksum
How to use checksums
18f7c5f8ad727317145f2b879a9ae16c042927f927fd579767905da15a72bef9
BLAKE2b-256 checksum
How to use checksums
8dfb9b71e60809aebf6a4d88a76a65cd2a9a5386182331ea942dca46df643f8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / pyvider_hcl-0.6.4-py3-none-any.whl

Download URL pyvider_hcl-0.6.4-py3-none-any.whl
Size 36.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9dc312e097c360b377200eb46414e177026dbe10c9cbc1f491e149f1350e41b3
BLAKE2b-256 checksum
How to use checksums
1acc5d663edc74830692489bb43864a1978fcefee499e3094fdd54ac6a25f3ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.4 This release

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page