Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
32a9abc
feat(teams): Updated and Added models for List, Create and Update opt…
isivaselvan Mar 16, 2026
6c9a015
feat(teams): Added List method to the teams resource
isivaselvan Mar 16, 2026
308139b
feat(teams): Added create method for team resources
isivaselvan Mar 17, 2026
f8dda5e
feat(teams): Added update method for the team resource
isivaselvan Mar 17, 2026
cf818e8
feat(teams): Added read method for team resource
isivaselvan Mar 17, 2026
efa5203
feat(teams): Added delete method for team resource
isivaselvan Mar 17, 2026
72bb761
feat(teams): Added unit test cases for teams resource
isivaselvan Mar 17, 2026
b811f60
feat(team-project-access): Added models for the team-project-access
isivaselvan Mar 17, 2026
cd218a3
feat(team-project-access): Added resource and examles file
isivaselvan Mar 20, 2026
446f6db
feat(team-project-access): Added models for the team project access r…
isivaselvan Apr 14, 2026
393f0ec
feat(team-project-access): Added list, remove, add, update and read m…
isivaselvan Apr 14, 2026
333a68b
feat(team-project-access): Added invalid team project access id error…
isivaselvan Apr 14, 2026
c6fb4fc
feat(team-project-access): Added examples for the team project access…
isivaselvan Apr 14, 2026
eb2f2db
feat(team-project-access): Added unit testcases for the team project …
isivaselvan Apr 14, 2026
05f2543
feat(stacks): Created models and resource for Stack resource
isivaselvan Apr 16, 2026
b0d25d5
feat(stacks): Added examples for stack resource
isivaselvan Apr 16, 2026
f3e8e00
feat(stacks): Added unit testcases for stack resource
isivaselvan Apr 16, 2026
0cce22b
feat(stacks): Fixed fmt and lints
isivaselvan Apr 16, 2026
2bd04d5
feat(explorer): add explorer support for HCP/TFE 🚀
jasodeep Apr 24, 2026
b95204c
:wrench: explorer fixes
jasodeep Apr 27, 2026
827a738
Improved overall test coverage for Explorer 🔍✨
jasodeep Apr 28, 2026
32b4343
♻️ Refactor Explorer codebase for improved quality and maintainability
jasodeep Apr 28, 2026
4d3cce2
📚✨Improved docstrings coverage better clarity and maintainability
jasodeep Apr 28, 2026
970fe63
Merge pull request #118 from hashicorp/feature/teams
isivaselvan Apr 30, 2026
bd11baa
Merge branch 'next-1.0.0' into feature/team-project-access
isivaselvan Apr 30, 2026
7e21b71
Fixed the fmt and lint
isivaselvan May 4, 2026
0bcfc6b
Merge pull request #127 from hashicorp/feature/team-project-access
isivaselvan May 4, 2026
926bc7a
Merge pull request #128 from hashicorp/feature/stack
isivaselvan May 4, 2026
d420fd2
Add organization token support with models, resources, examples, and …
NimishaShrivastava-dev May 5, 2026
6ac8ec6
feat: update organization token APIs and related files
NimishaShrivastava-dev May 5, 2026
4c6dba7
Merge pull request #141 from NimishaShrivastava-dev/feature/org-token…
isivaselvan May 6, 2026
be0394f
Merge pull request #142 from hashicorp/main
isivaselvan May 6, 2026
d0b826c
Add user API support and current-user endpoints
TanyaSingh369-svg May 6, 2026
6b926b6
feat(registry-provider-platform): Added the errors and models for the…
isivaselvan May 7, 2026
8f1c80a
feat(registry-provider-platform): Added create, list, read and delete…
isivaselvan May 7, 2026
809a77e
feat(registry-provider): Removed the validate function, utilized mode…
isivaselvan May 7, 2026
32c3e94
feat(registry-provider-version): Removed the validate function, updat…
isivaselvan May 7, 2026
598d4d0
feat(registry-provider-platform): Added and updated unit testcases of…
isivaselvan May 7, 2026
436ade5
feat(registry-provider-platform): Added example file for the feature
isivaselvan May 7, 2026
99c6e7a
Fixed lint and fmt
isivaselvan May 7, 2026
f6bf013
Merge pull request #144 from hashicorp/feature/User
isivaselvan May 7, 2026
26ff34e
Merge pull request #145 from hashicorp/feature/registry-provider-plat…
isivaselvan May 7, 2026
044ba21
feat(stack-config): Added models for the stack-config
isivaselvan May 8, 2026
1c8c5af
feat(stack-config): Added create, list and read method for the resource
isivaselvan May 8, 2026
9307768
feat(stack-config): Added examples and unit testcases
isivaselvan May 8, 2026
64df6d4
feat(stack): Added fetch latest stack from vcs method in the stack an…
isivaselvan May 8, 2026
e2032c7
feat(stack-config): updated models and example for stack config
isivaselvan May 8, 2026
fac1e9d
Merge pull request #147 from hashicorp/feature/stack-configuration
isivaselvan May 12, 2026
9900d94
feat(comment): Updated models for comments and created errors
isivaselvan May 12, 2026
f1f6a77
feat(comment): Added list, read and create methods for comment feature
isivaselvan May 12, 2026
962b178
feat(comment): Added unit tests and examples files
isivaselvan May 12, 2026
9558c83
Merge branch 'next-1.0.0' into main
isivaselvan May 13, 2026
d15ba17
Merge pull request #136 from jasodeep/main
isivaselvan May 13, 2026
29ee119
Merge pull request #155 from hashicorp/feature/comments
isivaselvan May 14, 2026
1b7880c
feat(state-versions): add upload functionality support
NimishaShrivastava-dev May 21, 2026
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Unreleased


# Released
# v1.0.0

## Features

### Explorer API
* Added Explorer resource support with query, CSV export, saved view CRUD, saved view result query, and saved view CSV export endpoints.


# v0.1.5

* `pytfe.__version__` added in src/pytfe/init.py via importlib.metadata.version("pytfe"). This will resolve to the version from pyproject.toml.
Expand Down
72 changes: 72 additions & 0 deletions examples/comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

from __future__ import annotations

import argparse
import os

from pytfe import TFEClient, TFEConfig
from pytfe.models import CommentCreateOptions


def _print_header(title: str):
print("\n" + "=" * 80)
print(title)
print("=" * 80)


def main():
parser = argparse.ArgumentParser(description="Comments demo for python-tfe SDK")
parser.add_argument(
"--address", default=os.getenv("TFE_ADDRESS", "https://app.terraform.io")
)
parser.add_argument("--token", default=os.getenv("TFE_TOKEN", ""))
parser.add_argument("--run-id", required=True, help="Run ID (e.g. run-xxxxx)")
parser.add_argument("--create", action="store_true", help="Create a new comment")
parser.add_argument("--body", help="Comment body text (required with --create)")
parser.add_argument("--read", action="store_true", help="Read a specific comment")
parser.add_argument("--id", help="Comment ID (e.g. com-xxxxx), required for --read")
args = parser.parse_args()

cfg = TFEConfig(address=args.address, token=args.token)
client = TFEClient(cfg)

# 1) Always list existing comments for the run
_print_header(f"Listing comments for run: {args.run_id}")
comment_count = 0
for comment in client.comments.list(run_id=args.run_id):
comment_count += 1
print(f"- ID: {comment.id}")
print(f" Body: {comment.body}")
print()

if comment_count == 0:
print("No comments found.")
else:
print(f"Total: {comment_count} comments")

# 2) Create a new comment
if args.create:
if not args.body:
print("--body is required for --create")
else:
_print_header(f"Creating a comment on run: {args.run_id}")
opts = CommentCreateOptions(body=args.body)
comment = client.comments.create(run_id=args.run_id, options=opts)
print(f"Created comment: {comment.id}")
print(f" Body: {comment.body}")

# 3) Read a specific comment
if args.read:
if not args.id:
print("--id is required for --read")
else:
_print_header(f"Reading comment: {args.id}")
comment = client.comments.read(comment_id=args.id)
print(f"ID: {comment.id}")
print(f"Body: {comment.body}")


if __name__ == "__main__":
main()
449 changes: 449 additions & 0 deletions examples/explorer.py

Large diffs are not rendered by default.

212 changes: 212 additions & 0 deletions examples/organization_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#!/usr/bin/env python3
"""
Organization Token Operations Example

Demonstrates usage of all 6 organization token operations:
1. create() - Create a new organization token, replacing any existing token
2. create_with_options() - Create with options like expiration date and token type
3. read() - Read the organization token
4. read_with_options() - Read with options like token type
5. delete() - Delete the organization token
6. delete_with_options() - Delete with options like token type

Usage:
- Modify organization names as needed for your environment
- Ensure you have proper TFE credentials and organization access
- Organization tokens are used for organization-level API access

Prerequisites:
- Set TFE_TOKEN and TFE_ADDRESS environment variables
- You need an existing organization or admin permissions to create one
- Appropriate permissions to manage organization tokens
"""

from datetime import datetime, timedelta

# Add the src directory to the path
##sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
from pytfe import TFEClient, TFEConfig
from pytfe.models import (
OrganizationTokenCreateOptions,
OrganizationTokenDeleteOptions,
OrganizationTokenReadOptions,
TokenType,
)


def redact_token(token_value: str | None) -> str:
"""Redact token value for safe display."""
if not token_value:
return "None"
if len(token_value) <= 8:
return f"{'*' * len(token_value)}"
# Show first 3 and last 3 characters
return f"{token_value[:3]}...{token_value[-3:]}".replace(
token_value[3:-3], "*" * (len(token_value) - 6)
)


def redact_id(id_value: str | None) -> str:
"""Redact ID for safe display."""
if not id_value:
return "None"
if len(id_value) <= 6:
return f"{'*' * len(id_value)}"
# Show first 3 and last 3 characters
return f"{id_value[:3]}...{id_value[-3:]}"


def main():
"""Execute organization token operation examples."""

print("=" * 80)
print("ORGANIZATION TOKEN OPERATIONS")
print("=" * 80)

# Initialize the TFE client
client = TFEClient(TFEConfig.from_env())
organization_name = "prab-sandbox02"
# =====================================================
# 1. CREATE ORGANIZATION TOKEN (BASIC)
# =====================================================
print("\n1. create() - Create a new organization token:")
print("-" * 40)
try:
print(f"Creating token for organization: {organization_name}")
token = client.organization_tokens.create(organization_name)

print("Token created successfully!")
print(f" Token ID: {redact_id(token.id)}")
print(f" Created At: {token.created_at}")
print(f" Description: {token.description}")
print(f" Token Value: {redact_token(token.token)}")
if token.expired_at:
print(f" Expires At: {token.expired_at}")
print()

except Exception as e:
print(f" Error: {e}")
print()

# =====================================================
# 2. CREATE WITH OPTIONS (WITH EXPIRATION)
# =====================================================
print("2. create_with_options() - Create token with expiration date:")
print("-" * 40)
try:
# Create a token that expires in 30 days
expiry_date = datetime.utcnow() + timedelta(days=30)
options = OrganizationTokenCreateOptions(expired_at=expiry_date)

print(f"Creating organization token with expiration date: {expiry_date}")
token = client.organization_tokens.create_with_options(
organization_name, options
)

print("Token created with options successfully!")
print(f" Token ID: {redact_id(token.id)}")
print(f" Created At: {token.created_at}")
if token.expired_at:
print(f" Expires At: {token.expired_at}")
print()

except Exception as e:
print(f" Error: {e}")
print()

# =====================================================
print("3. create_with_options() - Create audit-trails token:")
print("-" * 40)
try:
options = OrganizationTokenCreateOptions(token_type=TokenType.AUDIT_TRAILS)

print(f"Creating audit-trails token for organization: {organization_name}")
token = client.organization_tokens.create_with_options(
organization_name, options
)

print(" Audit-trails token created successfully!")
print(f" Token ID: {redact_id(token.id)}")
print(f" Token Value: {redact_token(token.token)}")
print()

except Exception as e:
print(f"Error: {e}")
print()

# =====================================================
print("4. read() - Read the organization token:")
print("-" * 40)
try:
print(f"Reading organization token for organization: {organization_name}")
token = client.organization_tokens.read(organization_name)

print("Token read successfully!")
print(f" Token ID: {redact_id(token.id)}")
print(f" Created At: {token.created_at}")
print(f" Description: {token.description}")
if token.last_used_at:
print(f" Last Used At: {token.last_used_at}")
if token.expired_at:
print(f" Expires At: {token.expired_at}")
print()

except Exception as e:
print(f" Error: {e}")
print()

# =====================================================
print("5. read_with_options() - Read audit-trails token:")
print("-" * 40)
try:
options = OrganizationTokenReadOptions(token_type=TokenType.AUDIT_TRAILS)

print(f"Reading audit-trails token for organization: {organization_name}")
token = client.organization_tokens.read_with_options(organization_name, options)

print(" Audit-trails token read successfully!")
print(f" Token ID: {redact_id(token.id)}")
print(f" Token Value: {redact_token(token.token)}")
print()

except Exception as e:
print(f" Error: {e}")
print()

# =====================================================
print("6. delete() - Delete the organization token:")
print("-" * 40)
try:
print(f"Deleting organization token for organization: {organization_name}")
client.organization_tokens.delete(organization_name)

print(" Token deleted successfully!")
print()

except Exception as e:
print(f" Error: {e}")
print()

# =====================================================
print("7. delete_with_options() - Delete audit-trails token:")
print("-" * 40)
try:
options = OrganizationTokenDeleteOptions(token_type=TokenType.AUDIT_TRAILS)

print(f"Deleting audit-trails token for organization: {organization_name}")
client.organization_tokens.delete_with_options(organization_name, options)

print(" Audit-trails token deleted successfully!")
print()

except Exception as e:
print(f"Error: {e}")
print()

print("=" * 80)
print("ORGANIZATION TOKEN OPERATIONS COMPLETED")
print("=" * 80)


if __name__ == "__main__":
main()
Loading
Loading