📄⚙️ Pyvider HCL
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
CtyValueobjects for pyvider compatibility - 🎯 Simplified API - Clean interface for parsing HCL and creating Terraform structures
- 🔍 Automatic Type Inference - Infer
CtyTypefrom 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.
- Install:
uv add pyvider-hcl - Read the Getting Started guide.
- Try the examples in examples/README.md.
Documentation
- User Guide: Detailed usage examples and patterns
- API Reference: Complete API documentation
- Architecture: System design and data flow diagrams
- Contributing: Guidelines for contributors
- Changelog: Version history and release notes
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 aCtyValueobject 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→CtyStringnumber(int/float) →CtyNumberbool→CtyBoollist→CtyList(CtyDynamic())object→CtyObjectwith 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
- pyvider-cty: CTY type system for Python
- pyvider: Terraform provider framework for Python
- provide-foundation: Foundation services and utilities
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)
| File | Size | Uploaded | |
|---|---|---|---|
| pyvider_hcl-0.6.4.tar.gz | 39.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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