Skip to content

Commit

Permalink
Patch: Updates API request to send API key via HTTP only. Deprecates …
Browse files Browse the repository at this point in the history
…API key via parameters. (#170)

* update requests

* update requests

* update pytests
  • Loading branch information
dapineyro authored Nov 7, 2024
1 parent a958887 commit 5b875ad
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 53 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## lifebit-ai/cloudos-cli: changelog

## v2.11.2 (2024-11-6)

### Fix

- Updates API requests to only use API key via HTTP header. Done in preparation for the upcoming deprecation of API key via parameters in CloudOS API.

## v2.11.1 (2024-10-22)

### Fix
Expand Down
2 changes: 1 addition & 1 deletion cloudos/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.11.1'
__version__ = '2.11.2'
37 changes: 26 additions & 11 deletions cloudos/clos.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,13 @@ def get_job_list(self, workspace_id, last_n_jobs=30, page=1, verify=True):
r : list
A list of dicts, each corresponding to a jobs from the user and the workspace.
"""
data = {"apikey": self.apikey}
headers = {
"Content-type": "application/json",
"apikey": self.apikey
}
r = retry_requests_get("{}/api/v1/jobs?teamId={}&page={}".format(self.cloudos_url,
workspace_id, page),
params=data, verify=verify)
headers=headers, verify=verify)
if r.status_code >= 400:
raise BadRequestException(r)
content = json.loads(r.content)
Expand Down Expand Up @@ -329,8 +332,7 @@ def get_curated_workflow_list(self, workspace_id, get_all=True, page=1, verify=T
r : list
A list of dicts, each corresponding to a workflow.
"""
data = {"apikey": self.apikey,
"search": "",
data = {"search": "",
"page": page,
"filters": [
[
Expand All @@ -355,9 +357,13 @@ def get_curated_workflow_list(self, workspace_id, get_all=True, page=1, verify=T
]
]
}
headers = {
"Content-type": "application/json",
"apikey": self.apikey
}
r = retry_requests_post("{}/api/v1/workflows/getByType?teamId={}".format(self.cloudos_url,
workspace_id),
json=data, verify=verify)
json=data, headers=headers, verify=verify)
if r.status_code >= 400:
raise BadRequestException(r)
content = json.loads(r.content)
Expand Down Expand Up @@ -391,10 +397,13 @@ def get_workflow_list(self, workspace_id, verify=True):
r : list
A list of dicts, each corresponding to a workflow.
"""
data = {"apikey": self.apikey}
headers = {
"Content-type": "application/json",
"apikey": self.apikey
}
r = retry_requests_get("{}/api/v1/workflows?teamId={}".format(self.cloudos_url,
workspace_id),
params=data, verify=verify)
headers=headers, verify=verify)
if r.status_code >= 400:
raise BadRequestException(r)
return json.loads(r.content)
Expand Down Expand Up @@ -520,9 +529,12 @@ def get_project_list(self, workspace_id, verify=True):
r : requests.models.Response
The server response
"""
data = {"apikey": self.apikey}
headers = {
"Content-type": "application/json",
"apikey": self.apikey
}
r = retry_requests_get("{}/api/v1/projects?teamId={}".format(self.cloudos_url, workspace_id),
params=data, verify=verify)
headers=headers, verify=verify)
if r.status_code >= 400:
raise BadRequestException(r)
return r
Expand Down Expand Up @@ -615,7 +627,6 @@ def workflow_import(self, workspace_id, workflow_url, workflow_name,
repository_name = workflow_url.split('/')[-1]

data = {
"apikey": self.apikey,
"workflowType": "nextflow",
"repository": {
"platform": platform,
Expand All @@ -638,9 +649,13 @@ def workflow_import(self, workspace_id, workflow_url, workflow_name,
"docsLink": workflow_docs_link,
"team": workspace_id
}
headers = {
"Content-type": "application/json",
"apikey": self.apikey
}
r = retry_requests_post("{}/api/v1/workflows?teamId={}".format(self.cloudos_url,
workspace_id),
json=data, verify=verify)
json=data, headers=headers, verify=verify)
if r.status_code == 401:
raise ValueError('It seems your API key is not authorised. Please check if ' +
'your workspace has support for importing workflows using cloudos-cli')
Expand Down
7 changes: 5 additions & 2 deletions cloudos/jobs/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,14 @@ def fetch_cloudos_id(self,
if resource not in allowed_resources:
raise ValueError('Your specified resource is not supported. ' +
f'Use one of the following: {allowed_resources}')
data = {"apikey": apikey}
headers = {
"Content-type": "application/json",
"apikey": apikey
}
r = retry_requests_get("{}/api/v1/{}?teamId={}".format(cloudos_url,
resource,
workspace_id),
params=data, verify=verify)
headers=headers, verify=verify)
if r.status_code >= 400:
raise BadRequestException(r)
content = json.loads(r.content)
Expand Down
7 changes: 4 additions & 3 deletions tests/test_clos/test_detect_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ def test_detect_workflow():
API request is mocked and replicated with json files
"""
json_data = load_json_file(INPUT)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
14 changes: 8 additions & 6 deletions tests/test_clos/test_get_job_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ def test_get_job_list_correct_response():
API request is mocked and replicated with json files
"""
create_json = load_json_file(INPUT)
params = {"teamId": WORKSPACE_ID, "page": 1, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID, "page": 1}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&page=1&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}&page=1"
# mock GET method with the .json
responses.add(
responses.GET,
Expand All @@ -53,12 +54,13 @@ def test_get_job_list_incorrect_response():
error_message = {"statusCode": 400, "code": "BadRequest",
"message": "Bad Request.", "time": "2022-11-23_17:31:07"}
error_json = json.dumps(error_message)
params = {"teamId": WORKSPACE_ID, "page": 1, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID, "page": 1}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&page=1&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}&page=1"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
14 changes: 8 additions & 6 deletions tests/test_clos/test_get_project_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ def test_get_project_list_correct_response():
"""
Test 'get_project_list' to work as intended
"""
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand All @@ -50,12 +51,13 @@ def test_get_project_list_incorrect_response():
error_message = {"statusCode": 400, "code": "BadRequest",
"message": "Bad Request.", "time": "2022-11-23_17:31:07"}
error_json = json.dumps(error_message)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
14 changes: 8 additions & 6 deletions tests/test_clos/test_get_workflow_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ def test_get_workflow_list_correct_response():
API request is mocked and replicated with json files
"""
create_json = load_json_file(INPUT)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down Expand Up @@ -54,12 +55,13 @@ def test_get_workflow_list_incorrect_response():
error_message = {"statusCode": 400, "code": "BadRequest",
"message": "Bad Request.", "time": "2022-11-23_17:31:07"}
error_json = json.dumps(error_message)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
7 changes: 4 additions & 3 deletions tests/test_clos/test_is_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ def test_is_module():
API request is mocked and replicated with json files
"""
json_data = load_json_file(INPUT)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
7 changes: 4 additions & 3 deletions tests/test_errors/test_bad_request_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ def test_bad_request_exception():
API request is mocked and replicated with json files
"""
create_json = load_json_file(INPUT)
params = {"teamId": WORKSPACE_ID, "page": 1, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID, "page": 1}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&page=1&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}&page=1"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
7 changes: 4 additions & 3 deletions tests/test_jobs/test_project_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ def test_project_id():
"""
create_json_project = load_json_file(INPUT_PROJECT)
create_json_workflow = load_json_file(INPUT_WORKFLOW)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down
10 changes: 4 additions & 6 deletions tests/test_jobs/test_send_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ def test_send_job():
create_json_workflow = load_json_file(INPUT_WORKFLOW)
create_json = load_json_file(INPUT)
params_job = {"teamId": WORKSPACE_ID}
params_pro_wf = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
header = {
"Content-type": "application/json",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}"
search_str_pro_wf = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
# mock GET method with the .json
responses.add(
responses.POST,
Expand All @@ -49,17 +47,17 @@ def test_send_job():
status=200)
responses.add(
responses.GET,
url=f"{CLOUDOS_URL}/api/v1/projects?{search_str_pro_wf}",
url=f"{CLOUDOS_URL}/api/v1/projects?{search_str}",
body=create_json_project,
headers=header,
match=[matchers.query_param_matcher(params_pro_wf)],
match=[matchers.query_param_matcher(params_job)],
status=200)
responses.add(
responses.GET,
url=f"{CLOUDOS_URL}/api/v1/workflows?{search_str_pro_wf}",
url=f"{CLOUDOS_URL}/api/v1/workflows?{search_str}",
body=create_json_workflow,
headers=header,
match=[matchers.query_param_matcher(params_pro_wf)],
match=[matchers.query_param_matcher(params_job)],
status=200)
# start cloudOS service
job = Job(apikey=APIKEY,
Expand Down
7 changes: 4 additions & 3 deletions tests/test_jobs/test_workflow_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ def test_workflow_id():
"""
create_json_project = load_json_file(INPUT_PROJECT)
create_json_workflow = load_json_file(INPUT_WORKFLOW)
params = {"teamId": WORKSPACE_ID, "apikey": APIKEY}
params = {"teamId": WORKSPACE_ID}
header = {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8"
"Content-Type": "application/json;charset=UTF-8",
"apikey": APIKEY
}
search_str = f"teamId={WORKSPACE_ID}&apikey={APIKEY}"
search_str = f"teamId={WORKSPACE_ID}"
# mock GET method with the .json
responses.add(
responses.GET,
Expand Down

0 comments on commit 5b875ad

Please sign in to comment.