Skip to content

Conversation

@iam404
Copy link
Member

@iam404 iam404 commented Sep 8, 2025

Description

This PR lays the core foundation for a typed, ergonomic Python SDK for Terraform Enterprise.
It establishes a consistent HTTP transport with retries, JSON:API helpers, config loading, typed domain models, and resource services plus packaging and an example. This is the baseline we’ll grow into full TFE coverage.

Note: Organizations, Projects, Workspaces resources added here are not final draft.

Key Changes

  1. Moved to hatchling, package name tfe.
  2. Exposes TFEConfig, TFEClient, and errors as the primary import points.
  3. HTTPTransport (Sync). Async Version is not tested. Retry policy & Error mapping.
  4. src/tfe/client.py --> TFEClient:
    Wires HTTPTransport from TFEConfig.
  5. src/tfe/resources/_base.py --> base classes with pagination helpers. This need to be tested for all APIs.
  6. src/tfe/types.py — Pydantic models and enums.
  7. Python 3.9 support.

@iam404 iam404 requested a review from a team as a code owner September 8, 2025 08:31
@@ -0,0 +1,9 @@
from tfe._http import HTTPTransport

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand you have deleted the old tests because the new codebase has new class names, locations, and API surfaces, so the old tests would fail. Ensure you have a ticket for this at a later time.

src/tfe/_http.py Outdated

async def _asleep(self, attempt: int, retry_after: float | None):
if retry_after is not None: await anyio.sleep(retry_after); return
delay = min(self.backoff_cap, self.backoff_base * (2 ** attempt))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backoff_jitter is accepted in init but not applied here. Consider adding random jitter to the delay.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore async methods, Async are not thoroughly tested.

@isivaselvan isivaselvan requested a review from Copilot September 8, 2025 11:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a comprehensive rewrite of the python-tfe library to establish a modern, typed SDK foundation for Terraform Enterprise/Cloud. The changes include migrating to Pydantic-based models, implementing robust HTTP transport with retry logic, and restructuring the project for better maintainability and extensibility.

  • Replaced simple dataclass configuration with Pydantic-based TFEConfig and comprehensive error handling
  • Introduced HTTPTransport with retry policies and proper JSON:API support
  • Created typed domain models and resource services for Organizations, Projects, and Workspaces

Reviewed Changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pyproject.toml Updated build system to hatchling, changed package name to "tfe", added new dependencies
src/tfe/init.py New module exports for TFEConfig, TFEClient, and errors
src/tfe/config.py New Pydantic-based configuration with environment variable support
src/tfe/client.py New TFEClient implementation using HTTPTransport
src/tfe/_http.py HTTP transport layer with retry logic and error mapping
src/tfe/errors.py Comprehensive error hierarchy for different API conditions
src/tfe/types.py Pydantic models for core domain objects
src/tfe/resources/*.py Resource service implementations for Organizations, Projects, Workspaces
examples/ws_list.py Example usage of the new SDK
tests/units/*.py Updated test files for new structure
Comments suppressed due to low confidence (1)

pyproject.toml:1

  • The classifier for Python 3.9 is missing but the project requires Python >=3.9. Add 'Programming Language :: Python :: 3.9', to the classifiers list.
[build-system]

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +19 to +21
return ExecutionMode._value2member_map_.get(v) # type: ignore[return-value]


Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessing private attribute _value2member_map_ is not recommended. Use the public try/except ValueError pattern with ExecutionMode(v) instead.

Suggested change
return ExecutionMode._value2member_map_.get(v) # type: ignore[return-value]
try:
return ExecutionMode(v)
except ValueError:
return None

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +57
self._sync = httpx.Client(
http2=http2, timeout=timeout, verify=ca_bundle or verify_tls
) # proxies=proxies
self._async = httpx.AsyncClient(
http2=http2, timeout=timeout, verify=ca_bundle or verify_tls
) # proxies=proxies
Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented out proxies=proxies suggests incomplete implementation. Either implement proxy support or remove the commented code and the proxies parameter if not needed.

Suggested change
self._sync = httpx.Client(
http2=http2, timeout=timeout, verify=ca_bundle or verify_tls
) # proxies=proxies
self._async = httpx.AsyncClient(
http2=http2, timeout=timeout, verify=ca_bundle or verify_tls
) # proxies=proxies
client_kwargs = {
"http2": http2,
"timeout": timeout,
"verify": ca_bundle or verify_tls,
}
if proxies is not None:
client_kwargs["proxies"] = proxies
self._sync = httpx.Client(**client_kwargs)
self._async = httpx.AsyncClient(**client_kwargs)

Copilot uses AI. Check for mistakes.


"""
Warning: Do Not Use this Async Service as its not stable with HashiCorp API.
Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar error: 'its' should be 'it's' (it is). Should read: 'Warning: Do Not Use this Async Service as it's not stable with HashiCorp API.'

Suggested change
Warning: Do Not Use this Async Service as its not stable with HashiCorp API.
Warning: Do Not Use this Async Service as it's not stable with HashiCorp API.

Copilot uses AI. Check for mistakes.
Copy link

@mukulmohan177 mukulmohan177 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good. The core abstractions (TFEClient, config, transport, and resource layers) are thoughtfully designed and this can be extended in the future meeting our scalability requirements.

@iam404 iam404 merged commit 0bce1e1 into main Sep 8, 2025
11 checks passed
@KshitijaChoudhari
Copy link
Collaborator

Summary Table

Area Issue/Concern Action Required
  1. Enum Handling | Unsafe enum construction | No action required, enum will be added as a class later
  2. Pydantic Models | Mutable default list | Best Practice: Use Field(default_factory=list) , but given version wshould not cause any issues |
  3. HTTP Proxies | Parameter not implemented | Implement -> more research needed, team will take a look |
  4. Async Services | Not supported/stable | Currently async not supported, should be fine |
  5. Tests | Insufficient coverage | Add more tests in later PRs |
  6. Documentation | Missing docstrings & usage | Add more docs when more Code is submitted |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants