Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.2.0 #25

Merged
merged 4 commits into from
Oct 2, 2023
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
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ coverage:
tests:
paths:
- "tests/"
target: 100%
target: 70%
source:
paths:
- "jupytext/"
Expand Down
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format.

## [0.2.0] - 2023-10-02
### Added
- Project search functionality

## [0.1.1] - 2023-07-29
### Fixed
- Incorrect base url
Expand Down
2 changes: 1 addition & 1 deletion pephubclient/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pephubclient.pephubclient import PEPHubClient

__app_name__ = "pephubclient"
__version__ = "0.1.2"
__version__ = "0.2.0"
__author__ = "Oleksandr Khoroshevskyi, Rafal Stepien"


Expand Down
1 change: 1 addition & 0 deletions pephubclient/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
PEPHUB_BASE_URL = "https://pephub.databio.org/"
# PEPHUB_BASE_URL = "http://0.0.0.0:8000/"
PEPHUB_PEP_API_BASE_URL = f"{PEPHUB_BASE_URL}api/v1/projects/"
PEPHUB_PEP_SEARCH_URL = f"{PEPHUB_BASE_URL}api/v1/namespaces/{{namespace}}/projects"
PEPHUB_PUSH_URL = f"{PEPHUB_BASE_URL}api/v1/namespaces/{{namespace}}/projects/json"


Expand Down
23 changes: 22 additions & 1 deletion pephubclient/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Optional
import datetime
from typing import Optional, List

import pydantic
from pydantic import BaseModel, Extra, Field
Expand Down Expand Up @@ -32,3 +33,23 @@ class ProjectUploadData(BaseModel):
@pydantic.validator("tag")
def tag_should_not_be_none(cls, v):
return v or "default"


class ProjectAnnotationModel(BaseModel):
namespace: str
name: str
tag: str
is_private: bool
number_of_samples: int
description: str
last_update_date: datetime.datetime
submission_date: datetime.datetime
digest: str
pep_schema: str


class SearchReturnModel(BaseModel):
count: int
limit: int
offset: int
items: List[ProjectAnnotationModel]
83 changes: 80 additions & 3 deletions pephubclient/pephubclient.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import os
from typing import NoReturn, Optional
from typing import NoReturn, Optional, Literal

import pandas as pd
import peppy
Expand All @@ -21,6 +21,7 @@
PEPHUB_PUSH_URL,
RegistryPath,
ResponseStatusCodes,
PEPHUB_PEP_SEARCH_URL,
)
from pephubclient.exceptions import (
IncorrectQueryStringError,
Expand All @@ -29,7 +30,12 @@
)
from pephubclient.files_manager import FilesManager
from pephubclient.helpers import MessageHandler, RequestManager
from pephubclient.models import ProjectDict, ProjectUploadData
from pephubclient.models import (
ProjectDict,
ProjectUploadData,
SearchReturnModel,
ProjectAnnotationModel,
)
from pephubclient.pephub_oauth.pephub_oauth import PEPHubAuth

urllib3.disable_warnings()
Expand Down Expand Up @@ -182,9 +188,65 @@
"User does not have permission to write to this namespace!"
)
else:
raise ResponseError("Unexpected Response Error.")
raise ResponseError(
f"Unexpected Response Error. {pephub_response.status_code}"
)
return None

def find_project(
self,
namespace: str,
query_string: str = "",
limit: int = 100,
offset: int = 0,
filter_by: Literal["submission_date", "last_update_date"] = None,
start_date: str = None,
end_date: str = None,
) -> SearchReturnModel:
"""
Find project in specific namespace and return list of PEP annotation

:param namespace: Namespace where to search for projects
:param query_string: Search query
:param limit: Return limit
:param offset: Return offset
:param filter_by: Use filter date. Option: [submission_date, last_update_date]
:param start_date: filter beginning date
:param end_date: filter end date (if none today's date is used)
:return:
"""
jwt_data = FilesManager.load_jwt_data_from_file(self.PATH_TO_FILE_WITH_JWT)

query_param = {
"q": query_string,
"limit": limit,
"offset": offset,
}
if filter_by in ["submission_date", "last_update_date"]:
query_param["filter_by"] = filter_by
query_param["filter_start_date"] = start_date
if end_date:
query_param["filter_end_date"] = end_date

Check warning on line 229 in pephubclient/pephubclient.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/pephubclient.py#L226-L229

Added lines #L226 - L229 were not covered by tests

url = self._build_project_search_url(
namespace=namespace,
query_param=query_param,
)

pephub_response = self.send_request(
method="GET",
url=url,
headers=self._get_header(jwt_data),
json=None,
cookies=None,
)
if pephub_response.status_code == ResponseStatusCodes.OK:
decoded_response = self._handle_pephub_response(pephub_response)
project_list = []
for project_found in json.loads(decoded_response)["items"]:
project_list.append(ProjectAnnotationModel(**project_found))
return SearchReturnModel(**json.loads(decoded_response))

@staticmethod
def _save_raw_pep(
reg_path: str,
Expand Down Expand Up @@ -334,6 +396,21 @@

return PEPHUB_PEP_API_BASE_URL + endpoint

def _build_project_search_url(
self, namespace: str, query_param: dict = None
) -> str:
"""
Build request for searching projects form pephub

:param query_param: dict of parameters used in query string
:return: url string
"""

variables_string = PEPHubClient._parse_query_param(query_param)
endpoint = variables_string

return PEPHUB_PEP_SEARCH_URL.format(namespace=namespace) + endpoint

@staticmethod
def _build_push_request_url(namespace: str) -> str:
"""
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pephubclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,14 @@ def test_push_with_pephub_error_response(
namespace="s_name",
name="name",
)

def test_search_prj(self, mocker):
return_value = b'{"count":1,"limit":100,"offset":0,"items":[{"namespace":"namespace1","name":"basic","tag":"default","is_private":false,"number_of_samples":2,"description":"None","last_update_date":"2023-08-27 19:07:31.552861+00:00","submission_date":"2023-08-27 19:07:31.552858+00:00","digest":"08cbcdbf4974fc84bee824c562b324b5","pep_schema":"random_schema_name"}],"session_info":null,"can_edit":false}'
requests_mock = mocker.patch(
"requests.request",
return_value=Mock(content=return_value, status_code=200),
)

return_value = PEPHubClient().find_project(namespace="namespace1")
assert return_value.count == 1
assert len(return_value.items) == 1
Loading