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.4.0 #37

Merged
merged 23 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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 .github/workflows/pytest-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.10"]
python-version: ["3.11"]
os: [windows-latest]

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.11"]
python-version: ["3.8", "3.12"]
os: [ubuntu-20.04]

steps:
Expand Down
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include requirements/*
include README.md
include pephubclient/pephub_oauth/*
include pephubclient/pephub_oauth/*
include pephubclient/modules/*
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ run-coverage:
coverage run -m pytest

html-report:
coverage html
coverage html --omit="*/test*"

open-coverage:
cd htmlcov && google-chrome index.html
Expand Down
18 changes: 18 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,26 @@

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.4.0] - 2024-02-12
### Added
- a parameter that points to where peps should be saved ([#32](https://github.com/pepkit/pephubclient/issues/32))
- pep zipping option to `save_pep` function ([#34](https://github.com/pepkit/pephubclient/issues/34))
- API for samples ([#29](https://github.com/pepkit/pephubclient/issues/29))
- API for projects ([#28](https://github.com/pepkit/pephubclient/issues/28))

### Updated
- Transferred `save_pep` function to helpers

## [0.3.0] - 2024-01-17
### Added
- customization of the base PEPhub URL ([#22](https://github.com/pepkit/pephubclient/issues/22))

### Updated
- Updated PEPhub API URL
- Increased the required pydantic version to >2.5.0

## [0.2.2] - 2024-01-17
### Added
- customization of the base pephub URL. [#22](https://github.com/pepkit/pephubclient/issues/22)

### Updated
Expand Down
22 changes: 20 additions & 2 deletions pephubclient/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
from pephubclient.pephubclient import PEPHubClient
from pephubclient.helpers import is_registry_path, save_pep
import logging
import coloredlogs

__app_name__ = "pephubclient"
__version__ = "0.2.2"
__version__ = "0.4.0"
__author__ = "Oleksandr Khoroshevskyi, Rafal Stepien"


__all__ = ["PEPHubClient", __app_name__, __author__, __version__]
__all__ = [
"PEPHubClient",
__app_name__,
__author__,
__version__,
"is_registry_path",
"save_pep",
]


_LOGGER = logging.getLogger(__app_name__)
coloredlogs.install(
logger=_LOGGER,
datefmt="%H:%M:%S",
fmt="[%(levelname)s] [%(asctime)s] %(message)s",
)
4 changes: 4 additions & 0 deletions pephubclient/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def logout():
def pull(
project_registry_path: str,
force: bool = typer.Option(False, help="Overwrite project if it exists."),
zip: bool = typer.Option(False, help="Save project as zip file."),
output: str = typer.Option(None, help="Output directory."),
):
"""
Download and save project locally.
Expand All @@ -37,6 +39,8 @@ def pull(
_client.pull,
project_registry_path=project_registry_path,
force=force,
output=output,
zip=zip,
)


Expand Down
17 changes: 15 additions & 2 deletions pephubclient/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
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"

PEPHUB_SAMPLE_URL = f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/samples/{{sample_name}}"
PEPHUB_VIEW_URL = (
f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/views/{{view_name}}"
)
PEPHUB_VIEW_SAMPLE_URL = f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/views/{{view_name}}/{{sample_name}}"


class RegistryPath(BaseModel):
protocol: Optional[str]
protocol: Optional[str] = None
namespace: str
item: str
subitem: Optional[str]
subitem: Optional[str] = None
tag: Optional[str] = "default"

@field_validator("tag")
Expand All @@ -33,3 +39,10 @@
NOT_EXIST = 404
CONFLICT = 409
INTERNAL_ERROR = 500


USER_DATA_FILE_NAME = "jwt.txt"
HOME_PATH = os.getenv("HOME")
if not HOME_PATH:
HOME_PATH = os.path.expanduser("~")

Check warning on line 47 in pephubclient/constants.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/constants.py#L47

Added line #L47 was not covered by tests
PATH_TO_FILE_WITH_JWT = os.path.join(HOME_PATH, ".pephubclient/") + USER_DATA_FILE_NAME
53 changes: 33 additions & 20 deletions pephubclient/files_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import pandas
import yaml
import zipfile

from pephubclient.constants import RegistryPath
from pephubclient.exceptions import PEPExistsError


Expand All @@ -29,17 +29,23 @@
return f.read()

@staticmethod
def create_project_folder(registry_path: RegistryPath) -> str:
def create_project_folder(
parent_path: str,
folder_name: str,
) -> str:
"""
Create new project folder

:param registry_path: project registry path
:param parent_path: parent path to create folder in
:param folder_name: folder name
:return: folder_path
"""
folder_name = FilesManager._create_filename_to_save_downloaded_project(
registry_path
)
folder_path = os.path.join(os.getcwd(), folder_name)
if parent_path:
if not Path(parent_path).exists():
raise OSError(

Check warning on line 45 in pephubclient/files_manager.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/files_manager.py#L43-L45

Added lines #L43 - L45 were not covered by tests
f"Parent path does not exist. Provided path: {parent_path}"
)
folder_path = os.path.join(parent_path or os.getcwd(), folder_name)

Check warning on line 48 in pephubclient/files_manager.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/files_manager.py#L48

Added line #L48 was not covered by tests
Path(folder_path).mkdir(parents=True, exist_ok=True)
return folder_path

Expand All @@ -62,21 +68,28 @@
def delete_file_if_exists(filename: str) -> None:
with suppress(FileNotFoundError):
os.remove(filename)

@staticmethod
def _create_filename_to_save_downloaded_project(registry_path: RegistryPath) -> str:
"""
Takes query string and creates output filename to save the project to.

:param registry_path: Query string that was used to find the project.
:return: Filename uniquely identifying the project.
"""
filename = "_".join(filter(bool, [registry_path.namespace, registry_path.item]))
if registry_path.tag:
filename += f":{registry_path.tag}"
return filename
print(
f"\033[38;5;11m{f'File was deleted successfully -> {filename}'}\033[0m"
)

@staticmethod
def check_writable(path: str, force: bool = True):
if not force and os.path.isfile(path):
raise PEPExistsError(f"File already exists and won't be updated: {path}")

@staticmethod
def save_zip_file(files_dict: dict, file_path: str, force: bool = False) -> None:
"""
Save zip file with provided files as dict.

:param files_dict: dict with files to save. e.g. {"file1.txt": "file1 content"}
:param file_path: filename to save zip file to
:param force: overwrite file if exists
:return: None
"""
FilesManager.check_writable(path=file_path, force=force)
with zipfile.ZipFile(

Check warning on line 91 in pephubclient/files_manager.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/files_manager.py#L90-L91

Added lines #L90 - L91 were not covered by tests
file_path, mode="w", compression=zipfile.ZIP_DEFLATED
) as zf:
for name, res in files_dict.items():
zf.writestr(name, str.encode(res))

Check warning on line 95 in pephubclient/files_manager.py

View check run for this annotation

Codecov / codecov/patch

pephubclient/files_manager.py#L94-L95

Added lines #L94 - L95 were not covered by tests
Loading
Loading