Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ Command line tool that allows the user to execute data operations on the platfor
- Python
- [Click](https://click.palletsprojects.com/en/8.0.x/)

## Getting Started

### Prerequisites
- Python 3.7+
- [Poetry](https://python-poetry.org/docs/#installation)

#### Run with Python
1. Install dependencies (optional: run in edit mode).
```
poetry install
poetry run python app/pilotcli.py --help
```
2. Add environment variables if needed.

1. Create a `.env` file in the root directory of the project.
2. Sdd following two environmental varibles to the `.env` file.
- `api_url`: the url that the api server is hosted on. default is `https://api.pilot.indocresearch.com/pilot`
- `keycloak_realm_url`: thr url that the keycloak server is hosted on. default is `https://iam.pilot.indocresearch.com/realms/pilot`

#### Run from bundled application
1. Navigate to the appropriate directory for your system.
Expand All @@ -17,14 +35,6 @@ Command line tool that allows the user to execute data operations on the platfor
./app/bundled_app/mac/
./app/bundled_app/mac_arm/

#### Run with Python
1. Install dependencies (optional: run in edit mode).

poetry install
poetry run pilotcli

2. Add environment variables if needed.

## Usage

./app/bundled_app/linux/pilotcli --help
Expand Down
3 changes: 2 additions & 1 deletion app/configs/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Connections:
url_validation = ConfigClass.url_validation
url_keycloak = ConfigClass.url_keycloak
url_keycloak_token = f'{ConfigClass.url_keycloak}/token'
url_keycloak_realm = ConfigClass.keycloak_realm_url
url_bff = ConfigClass.url_bff
url_base = ConfigClass.base_url
url_base = ConfigClass.api_url
url_portal = ConfigClass.url_portal
39 changes: 16 additions & 23 deletions app/configs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,75 +28,68 @@ class Settings(BaseSettings):
harbor_client_secret: str = ''
url_harbor: str = ''

domain: str = 'pilot.indocresearch.com'

@computed_field
def base_url(self) -> str:
return f'https://api.{self.domain}/pilot'
api_url: str = 'https://api.pilot.indocresearch.com/pilot'
keycloak_realm_url: str = 'https://iam.pilot.indocresearch.com/realms/pilot'

@computed_field
def url_bff(self) -> str:
return f'{self.base_url}/cli'
return f'{self.api_url}/cli'

@computed_field
def url_portal(self) -> str:
return f'{self.base_url}/portal'

@computed_field
def url_keycloak_realm(self) -> str:
return f'https://iam.{self.domain}/realms/pilot'
return f'{self.api_url}/portal'

@computed_field
def url_keycloak(self) -> str:
return f'{self.url_keycloak_realm}/protocol/openid-connect'
return f'{self.keycloak_realm_url}/protocol/openid-connect'

@computed_field
def url_authn(self) -> str:
return f'{self.base_url}/portal/users/auth'
return f'{self.api_url}/portal/users/auth'

@computed_field
def url_refresh_token(self) -> str:
return f'{self.base_url}/portal/users/refresh'
return f'{self.api_url}/portal/users/refresh'

@computed_field
def url_file_tag(self) -> str:
return f'{self.base_url}/portal/v2/%s/tags'
return f'{self.api_url}/portal/v2/%s/tags'

@computed_field
def url_upload_greenroom(self) -> str:
return f'{self.base_url}/upload/gr'
return f'{self.api_url}/upload/gr'

@computed_field
def url_upload_core(self) -> str:
return f'{self.base_url}/upload/core'
return f'{self.api_url}/upload/core'

@computed_field
def url_status(self) -> str:
return f'{self.base_url}/portal/v1/files/actions/tasks'
return f'{self.api_url}/portal/v1/files/actions/tasks'

@computed_field
def url_download_greenroom(self) -> str:
return f'{self.base_url}/portal/download/gr/'
return f'{self.api_url}/portal/download/gr/'

@computed_field
def url_download_core(self) -> str:
return f'{self.base_url}/portal/download/core/'
return f'{self.api_url}/portal/download/core/'

@computed_field
def url_v2_download_pre(self) -> str:
return f'{self.url_bff}/v1/project/%s/files/download'

@computed_field
def url_dataset_v2download(self) -> str:
return f'{self.base_url}/portal/download/core/v2/dataset'
return f'{self.api_url}/portal/download/core/v2/dataset'

@computed_field
def url_dataset(self) -> str:
return f'{self.base_url}/portal/v1/dataset'
return f'{self.api_url}/portal/v1/dataset'

@computed_field
def url_validation(self) -> str:
return f'{self.base_url}/v1/files/validation'
return f'{self.api_url}/v1/files/validation'


@lru_cache(1)
Expand Down
2 changes: 1 addition & 1 deletion app/services/user_authentication/user_login_logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def exchange_api_key(api_key: str) -> Union[str, None]:
"""Exchange API Key with JWT token using Keycloak."""

url = f'{ConfigClass.url_keycloak_realm}/api-key/{api_key}'
url = f'{AppConfig.Connections.url_keycloak_realm}/api-key/{api_key}'
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "app"
version = "2.9.3"
version = "2.9.4"
description = "This service is designed to support pilot platform"
authors = ["Indoc Systems"]

Expand Down
5 changes: 4 additions & 1 deletion tests/app/commands/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jwt

from app.commands.user import login
from app.configs.app_config import AppConfig
from app.configs.user_config import UserConfig


Expand All @@ -14,7 +15,9 @@ def test_login_command_with_api_key_option_calls_keycloak_and_stores_response_in
username = fake.user_name()
api_key = fake.pystr(20)
access_token = jwt.encode({'preferred_username': username}, key='').decode()
requests_mock.get(f'{settings.url_keycloak_realm}/api-key/{api_key}', json={'access_token': access_token})
requests_mock.get(
f'{AppConfig.Connections.url_keycloak_realm}/api-key/{api_key}', json={'access_token': access_token}
)

result = cli_runner.invoke(login, ['--api-key', api_key])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_refresh_api_key_calls_keycloak_and_stores_access_token_in_config(self,
manager = SrvTokenManager()
access_token = jwt.encode({}, key='').decode()
requests_mock.get(
f'{settings.url_keycloak_realm}/api-key/{manager.config.api_key}',
f'{AppConfig.Connections.url_keycloak_realm}/api-key/{manager.config.api_key}',
json={'access_token': access_token},
)

Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def mock_settings(monkeypatch, mocker):
monkeypatch.setattr(AppConfig.Connections, 'url_download_core', 'http://url_dataset_download_core')
monkeypatch.setattr(AppConfig.Connections, 'url_upload_greenroom', 'http://upload_gr')
monkeypatch.setattr(AppConfig.Connections, 'url_upload_core', 'http://upload_core')
monkeypatch.setattr(AppConfig.Connections, 'url_keycloak_realm', 'http://url_keycloak_realm')
monkeypatch.setattr(UserConfig, 'username', 'test-user')
monkeypatch.setattr(UserConfig, 'password', 'test-password')
monkeypatch.setattr(UserConfig, 'api_key', 'test-api-key')
Expand Down