Skip to content

Commit

Permalink
chore: add test files and list projects
Browse files Browse the repository at this point in the history
Update .gitignore to include the files main_test.py and test_config.json.
  • Loading branch information
guptadev21 committed Oct 24, 2024
1 parent b929c7e commit 997cb9e
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ wheels/
.ruff_cache
.idea
.github/workflows/release.yml
.vscode
.vscode
main_test.py
test_config.json
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description = "Python SDK for rapyuta.io v2 APIs"
dependencies = [
"httpx>=0.27.2",
"mock>=5.1.0",
"pytest-mock>=3.14.0",
"pytest>=8.3.3",
"tenacity>=9.0.0",
]
Expand Down
2 changes: 1 addition & 1 deletion rapyuta_io_sdk_v2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ruff: noqa
from rapyuta_io_sdk_v2.config import Configuration

__version__ = "0.0.1"
__version__ = "0.0.1"
54 changes: 47 additions & 7 deletions rapyuta_io_sdk_v2/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import httpx

from rapyuta_io_sdk_v2.client import Client
from rapyuta_io_sdk_v2.config import Configuration
from rapyuta_io_sdk_v2.utils import handle_server_errors


Expand All @@ -32,15 +33,54 @@ async def _get_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
) as async_client:
yield async_client

@staticmethod
async def get_token(self, email: str, password: str) -> str:
url = "{}/user/login/".format(self.v2api_host)
async def get_token(
self, email: str = None, password: str = None, env: str = "ga"
) -> str:
"""Get the authentication token for the user.
Args:
email (str)
password (str)
Returns:
str: authentication token
"""
if email is None and password is None and self.config is None:
raise ValueError("email and password are required")

if self.config is None:
self.config = Configuration(email=email, password=password, environment=env)

data = {
"email": email or self.config.email,
"password": password or self.config._password,
}

rip_host = self.config.hosts.get("rip_host")
url = "{}/user/login".format(rip_host)
headers = {"Content-Type": "application/json"}
data = {"email": email, "password": password}
response = httpx.post(url=url, headers=headers, json=data, timeout=10)
handle_server_errors(response)
return response.json().get("token")

async with httpx.AsyncClient() as asyncClient:
response = await asyncClient.post(
url=url, headers=headers, json=data, timeout=10
)
handle_server_errors(response)
return response.json()["data"].get("token")

@staticmethod
async def expire_token(token: str) -> None:
pass

async def refresh_token(self, token: str) -> str:
rip_host = self.config.hosts.get("rip_host")
url = "{}/refreshtoken".format(rip_host)
headers = {"Content-Type": "application/json"}

async with httpx.AsyncClient() as asyncClient:
response = await asyncClient.post(
url=url, headers=headers, json={"token": token}, timeout=10
)
handle_server_errors(response)

data = response.json()["data"]
return data["Token"]
61 changes: 53 additions & 8 deletions rapyuta_io_sdk_v2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ def _get_headers(self, with_project: bool = True) -> dict:
headers = {
"Authorization": "Bearer " + self.config.auth_token,
"Content-Type": "application/json",
"project": self.config.project_guid,
"organizationguid": self.config.organization_guid,
}
if with_project:
headers["project"] = self.config.project_guid
return headers

def get_authenticated_user(self) -> Optional[Dict]:
Expand All @@ -51,8 +52,9 @@ def get_authenticated_user(self) -> Optional[Dict]:
except Exception:
raise

@staticmethod
def get_token(email: str, password: str, env: str = None) -> str:
def get_token(
self, email: str = None, password: str = None, env: str = "ga"
) -> str:
"""Get the authentication token for the user.
Args:
Expand All @@ -62,22 +64,65 @@ def get_token(email: str, password: str, env: str = None) -> str:
Returns:
str: authentication token
"""
config = Configuration(email=email, password=password)
config.set_environment(env)
rip_host = config.hosts.get("rip_host")
if email is None and password is None and self.config is None:
raise ValueError("email and password are required")

if self.config is None:
self.config = Configuration(email=email, password=password, environment=env)

data = {
"email": email or self.config.email,
"password": password or self.config._password,
}

rip_host = self.config.hosts.get("rip_host")
url = "{}/user/login".format(rip_host)
headers = {"Content-Type": "application/json"}
data = {"email": email, "password": password}
response = httpx.post(url=url, headers=headers, json=data, timeout=10)
handle_server_errors(response)
return response.json()["data"].get("token")
self.config.auth_token = response.json()["data"].get("token")
return self.config.auth_token

@staticmethod
def expire_token(token: str) -> None:
pass

def refresh_token(self, token: str) -> str:
"""Refresh the authentication token.
Args:
token (str): The token to refresh.
Returns:
str: The refreshed token.
"""
rip_host = self.config.hosts.get("rip_host")
url = "{}/refreshtoken".format(rip_host)
headers = {"Content-Type": "application/json"}

response = httpx.post(
url=url, headers=headers, json={"token": token}, timeout=10
)
handle_server_errors(response)

data = response.json()["data"]
self.config.auth_token = data["Token"]
return self.config.auth_token

def set_project(self, project_guid: str):
self.config.project_guid = project_guid

def set_organization(self, organization_guid: str):
self.config.organization_guid = organization_guid

def list_projects(self, organization_guid: str):
if organization_guid is None:
raise ValueError("organization_guid is required")
v2api_host = self.config.hosts.get("v2api_host")
self.config.organization_guid = organization_guid
headers = self._get_headers(with_project=False)
response = httpx.get(
url="{}/v2/projects/".format(v2api_host), headers=headers, timeout=10
)
handle_server_errors(response)
return response.json()
11 changes: 5 additions & 6 deletions rapyuta_io_sdk_v2/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
PROD_ENVIRONMENT_SUBDOMAIN,
STAGING_ENVIRONMENT_SUBDOMAIN,
)
from rapyuta_io_sdk_v2.exceptions import (
ValidationError,
)
from rapyuta_io_sdk_v2.exceptions import ValidationError


@dataclass
Expand All @@ -48,13 +46,12 @@ def __init__(
self.auth_token = auth_token
self.project_guid = project_guid
self.organization_guid = organization_guid
if environment is not None:
self.environment = environment
self.environment = environment
self.hosts = {}
self.set_environment(environment)

@staticmethod
def from_file(self, file_path: str) -> "Configuration":
def from_file(file_path: str) -> "Configuration":
with open(file_path, "r") as file:
data = json.load(file)
return Configuration(
Expand All @@ -81,6 +78,8 @@ def set_environment(self, name: str = None) -> None:
ValidationError: If the environment is invalid.
"""
subdomain = PROD_ENVIRONMENT_SUBDOMAIN
if self.environment is not None:
name = self.environment
if name is not None:
is_valid_env = name in NAMED_ENVIRONMENTS or name.startswith("pr")
if not is_valid_env:
Expand Down
2 changes: 1 addition & 1 deletion rapyuta_io_sdk_v2/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

STAGING_ENVIRONMENT_SUBDOMAIN = "apps.okd4v2.okd4beta.rapyuta.io"
PROD_ENVIRONMENT_SUBDOMAIN = "apps.okd4v2.prod.rapyuta.io"
NAMED_ENVIRONMENTS = ["v11", "v12", "v13", "v14", "v15", "qa", "dev", "mock_test"]
NAMED_ENVIRONMENTS = ["v11", "v12", "v13", "v14", "v15", "qa", "dev"]
31 changes: 21 additions & 10 deletions tests/get_token.py → tests/test_get_token.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import pytest
import httpx

# Assuming the function exists within a class, let's call it Client
from rapyuta_io_sdk_v2.client import Client


Expand All @@ -13,20 +9,23 @@ def test_get_token_success(mocker):
# Mocking the httpx.post response
mock_post = mocker.patch("httpx.post")


# Setup a mocked response with a token
mock_response = mocker.Mock()
mock_response.json.return_value = {"success": True,"data": {"token": "mocked_token"}}
mock_response.json.return_value = {
"success": True,
"data": {"token": "mocked_token"},
}
mock_response.status_code = 200
mock_post.return_value = mock_response

# Call the function under test
token = Client.get_token(email=email, password=password, env="mock_test")
test_client = Client()
token = test_client.get_token(email, password, "pr_mock_test")
# config_instance.hosts = {"rip_host": "http://mocked-rip-host.com"}

# Assertions
mock_post.assert_called_once_with(
url="https://mock_testrip.apps.okd4v2.okd4beta.rapyuta.io/user/login",
url="https://pr_mock_testrip.apps.okd4v2.okd4beta.rapyuta.io/user/login",
headers={"Content-Type": "application/json"},
json={"email": email, "password": password},
timeout=10,
Expand All @@ -46,12 +45,24 @@ def test_get_token_server_error(mocker):
config_instance.hosts = {"rip_host": "http://mocked-rip-host.com"}

# Mocking the handle_server_errors function
mock_handle_server_errors = mocker.patch("rapyuta_io_sdk_v2.utils.handle_server_errors")
# mock_handle_server_errors = mocker.patch(
# "rapyuta_io_sdk_v2.utils.handle_server_errors"
# )

# Mocking the httpx.post response
mock_post = mocker.patch("httpx.post")
mock_post.return_value.status_code = 400
mock_post.json.return_value = {"error": "mocked_error"}

# Setup a mocked response with an error status code
mock_response = mocker.Mock()
mock_response.status_code = 400
mock_post.return_value = mock_response
mock_response.json.return_value = {"error": "mocked_error"}
mock_post.return_value = mock_response

mock_post.assert_called_once_with(
url="https://mock_testrip.apps.okd4v2.okd4beta.rapyuta.io/user/login",
headers={"Content-Type": "application/json"},
json={"email": email, "password": password},
timeout=10,
)
14 changes: 14 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 997cb9e

Please sign in to comment.