From 41d62678bc7e86d7ca1cd03e1f34f4ad65c5c772 Mon Sep 17 00:00:00 2001 From: Tanya Singh Date: Tue, 5 May 2026 02:01:45 +0530 Subject: [PATCH 1/4] Add user API support and current-user endpoints - Add Users resource - Implement read(user_id) and read_current() - Add user model updates - Add unit tests for user endpoints - Add example usage in examples/user.py --- examples/user.py | 46 ++++++++++ src/pytfe/client.py | 3 +- src/pytfe/models/user.py | 46 +++++++--- src/pytfe/resources/user.py | 40 +++++++++ tests/units/test_user.py | 166 ++++++++++++++++++++++++++++++++++++ 5 files changed, 289 insertions(+), 12 deletions(-) create mode 100644 examples/user.py create mode 100644 src/pytfe/resources/user.py create mode 100644 tests/units/test_user.py diff --git a/examples/user.py b/examples/user.py new file mode 100644 index 00000000..40521677 --- /dev/null +++ b/examples/user.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +"""Example usage of the Users API. + +This example demonstrates how to read a user by ID using the Python TFE SDK. +""" + +import os +import sys + +# Add the src directory to the Python path so we can import the local package. +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +from pytfe import TFEClient, TFEConfig + + +def main() -> None: + """Read and print user details from Terraform Cloud.""" + user_id = os.getenv("TFE_USER_ID") + + try: + client = TFEClient(TFEConfig.from_env()) + + current_user = client.users.read_current() + print("=== Current Terraform Cloud User ===") + print(f"User ID: {current_user.id}") + print(f"Username: {current_user.username}") + print(f"Email: {current_user.email or 'N/A'}") + print(f"Auth Method: {current_user.auth_method or 'N/A'}") + + if not user_id: + print("\nTFE_USER_ID not set. Skipping client.users.read(user_id).") + return + + user = client.users.read(user_id) + + print("\n=== Terraform Cloud User By ID ===") + print(f"User ID: {user.id}") + print(f"Username: {user.username}") + print(f"Email: {user.email or 'N/A'}") + print(f"Auth Method: {user.auth_method or 'N/A'}") + except Exception as e: + print(f"Error running user example: {e}") + + +if __name__ == "__main__": + main() diff --git a/src/pytfe/client.py b/src/pytfe/client.py index 31961371..607cded5 100644 --- a/src/pytfe/client.py +++ b/src/pytfe/client.py @@ -36,6 +36,7 @@ from .resources.stack import Stacks from .resources.state_version_outputs import StateVersionOutputs from .resources.state_versions import StateVersions +from .resources.user import Users from .resources.team import Teams from .resources.team_project_access import TeamProjectAccesses from .resources.variable import Variables @@ -75,7 +76,7 @@ def __init__(self, config: TFEConfig | None = None): self.plans = Plans(self._transport) self.organizations = Organizations(self._transport) self.organization_memberships = OrganizationMemberships(self._transport) - + self.users = Users(self._transport) self.projects = Projects(self._transport) self.variables = Variables(self._transport) self.variable_sets = VariableSets(self._transport) diff --git a/src/pytfe/models/user.py b/src/pytfe/models/user.py index bfa43359..65a28e52 100644 --- a/src/pytfe/models/user.py +++ b/src/pytfe/models/user.py @@ -1,26 +1,50 @@ # Copyright IBM Corp. 2025, 2026 # SPDX-License-Identifier: MPL-2.0 +from pydantic import BaseModel, ConfigDict, Field -from __future__ import annotations +class TwoFactor(BaseModel): + model_config = ConfigDict(populate_by_name=True, validate_by_name=True) -from pydantic import BaseModel, ConfigDict, Field + enabled: bool = Field(default=False, alias="enabled") + verified: bool = Field(default=False, alias="verified") + + +class UserPermissions(BaseModel): + model_config = ConfigDict(populate_by_name=True, validate_by_name=True) + + can_create_organizations: bool = Field( + default=False, alias="can-create-organizations" + ) + can_change_email: bool = Field(default=False, alias="can-change-email") + can_change_username: bool = Field(default=False, alias="can-change-username") + can_manage_user_tokens: bool = Field(default=False, alias="can-manage-user-tokens") + can_view_2fa_settings: bool = Field(default=False, alias="can-view2fa-settings") + can_manage_hcp_account: bool = Field(default=False, alias="can-manage-hcp-account") class User(BaseModel): model_config = ConfigDict(populate_by_name=True, validate_by_name=True) id: str = Field(..., alias="id") - avatar_url: str = Field(default="", alias="avatar-url") - email: str = Field(default="", alias="email") + auth_method: str | None = Field(default=None, alias="auth-method") + avatar_url: str | None = Field(default=None, alias="avatar-url") + email: str | None = Field(default=None, alias="email") is_service_account: bool = Field(default=False, alias="is-service-account") - two_factor: dict = Field(default_factory=dict, alias="two-factor") - unconfirmed_email: str = Field(default="", alias="unconfirmed-email") + two_factor: TwoFactor | None = Field(default=None, alias="two-factor") + unconfirmed_email: str | None = Field(default=None, alias="unconfirmed-email") username: str = Field(default="", alias="username") v2_only: bool = Field(default=False, alias="v2-only") - is_site_admin: bool = Field(default=False, alias="is-site-admin") # Deprecated - is_admin: bool = Field(default=False, alias="is-admin") - is_sso_login: bool = Field(default=False, alias="is-sso-login") - permissions: dict = Field(default_factory=dict, alias="permissions") - + is_site_admin: bool | None = Field( + default=None, alias="is-site-admin" + ) # Deprecated + is_admin: bool | None = Field(default=None, alias="is-admin") + is_sso_login: bool | None = Field(default=None, alias="is-sso-login") + permissions: UserPermissions | None = Field(default=None, alias="permissions") # Relations # authentication_tokens: AuthenticationTokens = Field(..., alias="authentication-tokens") + +class UserUpdateCurrentOptions(BaseModel): + model_config = ConfigDict(populate_by_name=True, validate_by_name=True) + + username: str | None = Field(default=None, alias="username") + email: str | None = Field(default=None, alias="email") diff --git a/src/pytfe/resources/user.py b/src/pytfe/resources/user.py new file mode 100644 index 00000000..ab5a7e3b --- /dev/null +++ b/src/pytfe/resources/user.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from ..models.user import User, UserUpdateCurrentOptions +from ..utils import valid_string_id +from ._base import _Service + + +class Users(_Service): + def read(self, user_id: str) -> User: + if not valid_string_id(user_id): + raise ValueError("invalid user id") + + r = self.t.request("GET", f"/api/v2/users/{user_id}") + d = r.json()["data"] + attr = d.get("attributes", {}) or {} + user_data = dict(attr) + user_data["id"] = d.get("id") + return User(**user_data) + + def read_current(self) -> User: + r = self.t.request("GET", "/api/v2/account/details") + d = r.json()["data"] + attr = d.get("attributes", {}) or {} + user_data = dict(attr) + user_data["id"] = d.get("id") + return User(**user_data) + + def update_current(self, options: UserUpdateCurrentOptions) -> User: + body = { + "data": { + "type": "users", + "attributes": options.model_dump(exclude_none=True), + } + } + r = self.t.request("PATCH", "/api/v2/account/update", json_body=body) + d = r.json()["data"] + attr = d.get("attributes", {}) or {} + user_data = dict(attr) + user_data["id"] = d.get("id") + return User(**user_data) diff --git a/tests/units/test_user.py b/tests/units/test_user.py new file mode 100644 index 00000000..65cb0dfc --- /dev/null +++ b/tests/units/test_user.py @@ -0,0 +1,166 @@ +"""Unit tests for the Users resource.""" + +import copy +from unittest.mock import Mock + +import pytest +from pytfe.models.user import User, UserPermissions, UserUpdateCurrentOptions +from pytfe.resources.user import Users + + +class TestUsers: + """Test suite for user resource operations.""" + + @pytest.fixture + def mock_transport(self): + """Mock HTTP transport.""" + return Mock() + + @pytest.fixture + def users_service(self, mock_transport): + """Create users service with mocked transport.""" + return Users(mock_transport) + + @pytest.fixture + def sample_user_response(self): + """Sample JSON:API response for a user.""" + return { + "data": { + "id": "user-MA4GL63FmYRpSFxa", + "type": "users", + "attributes": { + "username": "admin", + "email": "admin@example.com", + "is-service-account": False, + "auth-method": "hcp_sso", + "avatar-url": "https://example.com/avatar.png", + "v2-only": True, + "permissions": { + "can-create-organizations": False, + "can-change-email": True, + "can-change-username": True, + }, + }, + } + } + + def test_read_user(self, users_service, mock_transport, sample_user_response): + """Test reading a specific user by ID.""" + mock_transport.request.return_value.json.return_value = sample_user_response + + user_id = "user-MA4GL63FmYRpSFxa" + user = users_service.read(user_id) + + mock_transport.request.assert_called_once_with( + "GET", f"/api/v2/users/{user_id}" + ) + assert isinstance(user, User) + assert user.id == user_id + assert user.username == "admin" + assert user.email == "admin@example.com" + assert user.is_service_account is False + assert user.auth_method == "hcp_sso" + assert user.avatar_url == "https://example.com/avatar.png" + assert user.v2_only is True + assert isinstance(user.permissions, UserPermissions) + assert user.permissions is not None + assert user.permissions.can_create_organizations is False + assert user.permissions.can_change_email is True + assert user.permissions.can_change_username is True + assert user.permissions.can_manage_user_tokens is False + assert user.permissions.can_view_2fa_settings is False + assert user.permissions.can_manage_hcp_account is False + + def test_read_user_invalid_id(self, users_service): + """Test reading a user with an invalid user ID.""" + with pytest.raises(ValueError, match="invalid user id"): + users_service.read("") + + def test_read_user_with_null_unconfirmed_email( + self, users_service, mock_transport, sample_user_response + ): + """Test reading a user when unconfirmed-email is null.""" + sample_user_response["data"]["attributes"]["unconfirmed-email"] = None + mock_transport.request.return_value.json.return_value = sample_user_response + + user = users_service.read("user-MA4GL63FmYRpSFxa") + + assert isinstance(user, User) + assert user.unconfirmed_email is None + + def test_read_user_two_factor_parsing( + self, users_service, mock_transport, sample_user_response + ): + """Test reading a user with two-factor data.""" + modified_response = copy.deepcopy(sample_user_response) + modified_response["data"]["attributes"]["two-factor"] = { + "enabled": True, + "verified": False, + } + mock_transport.request.return_value.json.return_value = modified_response + + user_id = "user-MA4GL63FmYRpSFxa" + user = users_service.read(user_id) + + assert user.two_factor is not None + assert user.two_factor.enabled is True + assert user.two_factor.verified is False + + def test_read_user_nullable_bools( + self, users_service, mock_transport, sample_user_response + ): + """Test reading a user when pointer-style boolean fields are null.""" + modified_response = copy.deepcopy(sample_user_response) + modified_response["data"]["attributes"]["is-site-admin"] = None + modified_response["data"]["attributes"]["is-admin"] = None + modified_response["data"]["attributes"]["is-sso-login"] = None + mock_transport.request.return_value.json.return_value = modified_response + + user_id = "user-MA4GL63FmYRpSFxa" + user = users_service.read(user_id) + + assert user.is_site_admin is None + assert user.is_admin is None + assert user.is_sso_login is None + + def test_read_current_user( + self, users_service, mock_transport, sample_user_response + ): + """Test reading the currently authenticated user.""" + mock_transport.request.return_value.json.return_value = sample_user_response + + user = users_service.read_current() + + mock_transport.request.assert_called_once_with("GET", "/api/v2/account/details") + assert isinstance(user, User) + assert user.id == "user-MA4GL63FmYRpSFxa" + assert user.username == "admin" + assert user.email == "admin@example.com" + + def test_update_current_user( + self, users_service, mock_transport, sample_user_response + ): + """Test updating the currently authenticated user.""" + mock_transport.request.return_value.json.return_value = sample_user_response + options = UserUpdateCurrentOptions( + username="new-admin", + email="new-admin@example.com", + ) + + user = users_service.update_current(options) + + mock_transport.request.assert_called_once_with( + "PATCH", + "/api/v2/account/update", + json_body={ + "data": { + "type": "users", + "attributes": { + "username": "new-admin", + "email": "new-admin@example.com", + }, + } + }, + ) + assert isinstance(user, User) + assert user.id == "user-MA4GL63FmYRpSFxa" From 21472698bd7541e58ef5959cd62b4c78fb7baf08 Mon Sep 17 00:00:00 2001 From: Tanya Singh Date: Tue, 5 May 2026 02:29:15 +0530 Subject: [PATCH 2/4] Fix lint issues for user endpoints --- src/pytfe/client.py | 2 +- src/pytfe/models/user.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pytfe/client.py b/src/pytfe/client.py index 607cded5..b62aa13a 100644 --- a/src/pytfe/client.py +++ b/src/pytfe/client.py @@ -36,9 +36,9 @@ from .resources.stack import Stacks from .resources.state_version_outputs import StateVersionOutputs from .resources.state_versions import StateVersions -from .resources.user import Users from .resources.team import Teams from .resources.team_project_access import TeamProjectAccesses +from .resources.user import Users from .resources.variable import Variables from .resources.variable_sets import VariableSets, VariableSetVariables from .resources.workspace_resources import WorkspaceResourcesService diff --git a/src/pytfe/models/user.py b/src/pytfe/models/user.py index 65a28e52..c48b0f13 100644 --- a/src/pytfe/models/user.py +++ b/src/pytfe/models/user.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MPL-2.0 from pydantic import BaseModel, ConfigDict, Field + class TwoFactor(BaseModel): model_config = ConfigDict(populate_by_name=True, validate_by_name=True) @@ -43,6 +44,7 @@ class User(BaseModel): # Relations # authentication_tokens: AuthenticationTokens = Field(..., alias="authentication-tokens") + class UserUpdateCurrentOptions(BaseModel): model_config = ConfigDict(populate_by_name=True, validate_by_name=True) From 9e3dad92e7548206dbc664d40a92313c637f3a25 Mon Sep 17 00:00:00 2001 From: Tanya Singh Date: Tue, 5 May 2026 02:40:40 +0530 Subject: [PATCH 3/4] Fix import order in test_user --- tests/units/test_user.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/units/test_user.py b/tests/units/test_user.py index 65cb0dfc..0441fbba 100644 --- a/tests/units/test_user.py +++ b/tests/units/test_user.py @@ -4,7 +4,11 @@ from unittest.mock import Mock import pytest -from pytfe.models.user import User, UserPermissions, UserUpdateCurrentOptions +from pytfe.models.user import ( + User, + UserPermissions, + UserUpdateCurrentOptions, +) from pytfe.resources.user import Users From b73e0bb7ecd1bd75896f7acb36daaecaeb4a3e5b Mon Sep 17 00:00:00 2001 From: Tanya Singh Date: Wed, 6 May 2026 13:40:34 +0530 Subject: [PATCH 4/4] Fix lint after rebase --- src/pytfe/client.py | 2 -- src/pytfe/models/__init__.py | 3 ++- tests/units/test_agent_pools.py | 1 - tests/units/test_agents.py | 1 - tests/units/test_configuration_version.py | 2 +- tests/units/test_notification_configuration.py | 1 - tests/units/test_organization_token.py | 1 - tests/units/test_plan.py | 1 - tests/units/test_policy.py | 1 - tests/units/test_policy_check.py | 1 - tests/units/test_policy_evaluation.py | 1 - tests/units/test_policy_set.py | 1 - tests/units/test_policy_set_parameter.py | 1 - tests/units/test_query_run.py | 1 - tests/units/test_registry_provider_version.py | 1 - tests/units/test_reserved_tag_key.py | 1 - tests/units/test_run.py | 1 - tests/units/test_run_events.py | 1 - tests/units/test_run_task.py | 1 - tests/units/test_run_trigger.py | 1 - tests/units/test_ssh_keys.py | 1 - tests/units/test_stack.py | 1 - tests/units/test_state_version.py | 1 - tests/units/test_team.py | 1 - tests/units/test_team_project_access.py | 1 - tests/units/test_variable_sets.py | 1 - tests/units/test_workspace_resources.py | 1 - 27 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/pytfe/client.py b/src/pytfe/client.py index f85101c4..639111eb 100644 --- a/src/pytfe/client.py +++ b/src/pytfe/client.py @@ -36,8 +36,6 @@ from .resources.ssh_keys import SSHKeys from .resources.state_version_outputs import StateVersionOutputs from .resources.state_versions import StateVersions -from .resources.team import Teams -from .resources.team_project_access import TeamProjectAccesses from .resources.user import Users from .resources.variable import Variables from .resources.variable_sets import VariableSets, VariableSetVariables diff --git a/src/pytfe/models/__init__.py b/src/pytfe/models/__init__.py index 4c3b6f32..8b91748f 100644 --- a/src/pytfe/models/__init__.py +++ b/src/pytfe/models/__init__.py @@ -31,8 +31,9 @@ Tag, TagBinding, TagList, -) # if you put ExecutionMode enum here +) +# if you put ExecutionMode enum here # ── Configuration Versions ──────────────────────────────────────────────────── # (Old: .configuration_version_types) → import directly from real module from .configuration_version import ( diff --git a/tests/units/test_agent_pools.py b/tests/units/test_agent_pools.py index f797f612..4d933b9e 100644 --- a/tests/units/test_agent_pools.py +++ b/tests/units/test_agent_pools.py @@ -18,7 +18,6 @@ from unittest.mock import Mock import pytest - from pytfe.errors import AuthError, NotFound, ValidationError from pytfe.models.agent import ( AgentPool, diff --git a/tests/units/test_agents.py b/tests/units/test_agents.py index 69e40ae2..34922fe7 100644 --- a/tests/units/test_agents.py +++ b/tests/units/test_agents.py @@ -16,7 +16,6 @@ from unittest.mock import Mock import pytest - from pytfe.errors import AuthError, NotFound from pytfe.models.agent import ( Agent, diff --git a/tests/units/test_configuration_version.py b/tests/units/test_configuration_version.py index d8d442bc..8db26185 100644 --- a/tests/units/test_configuration_version.py +++ b/tests/units/test_configuration_version.py @@ -23,7 +23,6 @@ from unittest.mock import Mock import pytest - from pytfe.models.configuration_version import ( ConfigurationSource, ConfigurationStatus, @@ -32,6 +31,7 @@ ConfigurationVersionReadOptions, ConfigVerIncludeOpt, ) + from src.pytfe.errors import NotFound, TFEError from src.pytfe.resources.configuration_version import ConfigurationVersions diff --git a/tests/units/test_notification_configuration.py b/tests/units/test_notification_configuration.py index a9204bf2..80b14e12 100644 --- a/tests/units/test_notification_configuration.py +++ b/tests/units/test_notification_configuration.py @@ -10,7 +10,6 @@ from unittest.mock import Mock import pytest - from pytfe.errors import InvalidOrgError, ValidationError from pytfe.models.notification_configuration import ( DeliveryResponse, diff --git a/tests/units/test_organization_token.py b/tests/units/test_organization_token.py index 826f2239..fb25ba85 100644 --- a/tests/units/test_organization_token.py +++ b/tests/units/test_organization_token.py @@ -4,7 +4,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ERR_INVALID_ORG from pytfe.models.organization_token import ( diff --git a/tests/units/test_plan.py b/tests/units/test_plan.py index 36c3f7ee..b4429eb1 100644 --- a/tests/units/test_plan.py +++ b/tests/units/test_plan.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe.errors import InvalidPlanIDError from pytfe.resources.plan import Plans diff --git a/tests/units/test_policy.py b/tests/units/test_policy.py index e94a38b0..82f63629 100644 --- a/tests/units/test_policy.py +++ b/tests/units/test_policy.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidOrgError, diff --git a/tests/units/test_policy_check.py b/tests/units/test_policy_check.py index 07642cb5..935d03e0 100644 --- a/tests/units/test_policy_check.py +++ b/tests/units/test_policy_check.py @@ -3,7 +3,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import InvalidPolicyCheckIDError, InvalidRunIDError from pytfe.models.policy_check import ( diff --git a/tests/units/test_policy_evaluation.py b/tests/units/test_policy_evaluation.py index ea41ee08..eb597f70 100644 --- a/tests/units/test_policy_evaluation.py +++ b/tests/units/test_policy_evaluation.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe._http import HTTPTransport from pytfe.errors import InvalidTaskStageIDError from pytfe.models.policy_evaluation import ( diff --git a/tests/units/test_policy_set.py b/tests/units/test_policy_set.py index 91229c4c..9a9f5a92 100644 --- a/tests/units/test_policy_set.py +++ b/tests/units/test_policy_set.py @@ -3,7 +3,6 @@ from unittest.mock import Mock import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidNameError, diff --git a/tests/units/test_policy_set_parameter.py b/tests/units/test_policy_set_parameter.py index c8023c25..40eca0c6 100644 --- a/tests/units/test_policy_set_parameter.py +++ b/tests/units/test_policy_set_parameter.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidCategoryError, diff --git a/tests/units/test_query_run.py b/tests/units/test_query_run.py index e31bf4ef..b983c666 100644 --- a/tests/units/test_query_run.py +++ b/tests/units/test_query_run.py @@ -20,7 +20,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe.errors import InvalidQueryRunIDError, InvalidWorkspaceIDError from pytfe.models import ( QueryRun, diff --git a/tests/units/test_registry_provider_version.py b/tests/units/test_registry_provider_version.py index e291e602..a102dbfa 100644 --- a/tests/units/test_registry_provider_version.py +++ b/tests/units/test_registry_provider_version.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidKeyIDError, diff --git a/tests/units/test_reserved_tag_key.py b/tests/units/test_reserved_tag_key.py index 9c62bedf..7ec1b10b 100644 --- a/tests/units/test_reserved_tag_key.py +++ b/tests/units/test_reserved_tag_key.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidOrgError, diff --git a/tests/units/test_run.py b/tests/units/test_run.py index 7a72d2cb..b24b8594 100644 --- a/tests/units/test_run.py +++ b/tests/units/test_run.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidRunIDError, diff --git a/tests/units/test_run_events.py b/tests/units/test_run_events.py index af82e786..3d642cee 100644 --- a/tests/units/test_run_events.py +++ b/tests/units/test_run_events.py @@ -3,7 +3,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import InvalidRunEventIDError, InvalidRunIDError from pytfe.models.run_event import ( diff --git a/tests/units/test_run_task.py b/tests/units/test_run_task.py index cb197e3a..d6b89fdb 100644 --- a/tests/units/test_run_task.py +++ b/tests/units/test_run_task.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidOrgError, diff --git a/tests/units/test_run_trigger.py b/tests/units/test_run_trigger.py index 6fbcac02..83b42ba5 100644 --- a/tests/units/test_run_trigger.py +++ b/tests/units/test_run_trigger.py @@ -7,7 +7,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidRunTriggerIDError, diff --git a/tests/units/test_ssh_keys.py b/tests/units/test_ssh_keys.py index adbf3f7c..1ed06f02 100644 --- a/tests/units/test_ssh_keys.py +++ b/tests/units/test_ssh_keys.py @@ -6,7 +6,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ( InvalidOrgError, diff --git a/tests/units/test_stack.py b/tests/units/test_stack.py index 03c9d28f..7007f55b 100644 --- a/tests/units/test_stack.py +++ b/tests/units/test_stack.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe._http import HTTPTransport from pytfe.models.agent import AgentPool from pytfe.models.project import Project diff --git a/tests/units/test_state_version.py b/tests/units/test_state_version.py index 11f67c8f..fe6a1344 100644 --- a/tests/units/test_state_version.py +++ b/tests/units/test_state_version.py @@ -3,7 +3,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import NotFound from pytfe.models.state_version import ( diff --git a/tests/units/test_team.py b/tests/units/test_team.py index cd38ab0b..a1906ffb 100644 --- a/tests/units/test_team.py +++ b/tests/units/test_team.py @@ -3,7 +3,6 @@ from unittest.mock import Mock, patch import pytest - from pytfe._http import HTTPTransport from pytfe.errors import ERR_INVALID_ORG, InvalidTeamIDError from pytfe.models import ( diff --git a/tests/units/test_team_project_access.py b/tests/units/test_team_project_access.py index 75b6a4a6..8f540555 100644 --- a/tests/units/test_team_project_access.py +++ b/tests/units/test_team_project_access.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe._http import HTTPTransport from pytfe.errors import InvalidTeamProjectAccessIDError from pytfe.models.project import Project diff --git a/tests/units/test_variable_sets.py b/tests/units/test_variable_sets.py index efaa6adb..5b2d7cac 100644 --- a/tests/units/test_variable_sets.py +++ b/tests/units/test_variable_sets.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe.models.variable_set import ( CategoryType, Parent, diff --git a/tests/units/test_workspace_resources.py b/tests/units/test_workspace_resources.py index 28909b7b..d58b1ff5 100644 --- a/tests/units/test_workspace_resources.py +++ b/tests/units/test_workspace_resources.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest - from pytfe.models.workspace_resource import ( WorkspaceResource, WorkspaceResourceListOptions,