Skip to content

Commit 5389da7

Browse files
Merge pull request #37 from pepkit/dev
Release 0.4.0
2 parents 98c4a4d + c71a4af commit 5389da7

20 files changed

+1359
-196
lines changed

.github/workflows/pytest-windows.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ${{ matrix.os }}
1212
strategy:
1313
matrix:
14-
python-version: ["3.10"]
14+
python-version: ["3.11"]
1515
os: [windows-latest]
1616

1717
steps:

.github/workflows/pytest.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ${{ matrix.os }}
1212
strategy:
1313
matrix:
14-
python-version: ["3.8", "3.11"]
14+
python-version: ["3.8", "3.12"]
1515
os: [ubuntu-20.04]
1616

1717
steps:

MANIFEST.in

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include requirements/*
22
include README.md
3-
include pephubclient/pephub_oauth/*
3+
include pephubclient/pephub_oauth/*
4+
include pephubclient/modules/*

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ run-coverage:
55
coverage run -m pytest
66

77
html-report:
8-
coverage html
8+
coverage html --omit="*/test*"
99

1010
open-coverage:
1111
cd htmlcov && google-chrome index.html

docs/changelog.md

+18
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,26 @@
22

33
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.
44

5+
## [0.4.0] - 2024-02-12
6+
### Added
7+
- a parameter that points to where peps should be saved ([#32](https://github.com/pepkit/pephubclient/issues/32))
8+
- pep zipping option to `save_pep` function ([#34](https://github.com/pepkit/pephubclient/issues/34))
9+
- API for samples ([#29](https://github.com/pepkit/pephubclient/issues/29))
10+
- API for projects ([#28](https://github.com/pepkit/pephubclient/issues/28))
11+
12+
### Updated
13+
- Transferred `save_pep` function to helpers
14+
515
## [0.3.0] - 2024-01-17
616
### Added
17+
- customization of the base PEPhub URL ([#22](https://github.com/pepkit/pephubclient/issues/22))
18+
19+
### Updated
20+
- Updated PEPhub API URL
21+
- Increased the required pydantic version to >2.5.0
22+
23+
## [0.2.2] - 2024-01-17
24+
### Added
725
- customization of the base pephub URL. [#22](https://github.com/pepkit/pephubclient/issues/22)
826

927
### Updated

pephubclient/__init__.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
from pephubclient.pephubclient import PEPHubClient
2+
from pephubclient.helpers import is_registry_path, save_pep
3+
import logging
4+
import coloredlogs
25

36
__app_name__ = "pephubclient"
4-
__version__ = "0.2.2"
7+
__version__ = "0.4.0"
58
__author__ = "Oleksandr Khoroshevskyi, Rafal Stepien"
69

710

8-
__all__ = ["PEPHubClient", __app_name__, __author__, __version__]
11+
__all__ = [
12+
"PEPHubClient",
13+
__app_name__,
14+
__author__,
15+
__version__,
16+
"is_registry_path",
17+
"save_pep",
18+
]
19+
20+
21+
_LOGGER = logging.getLogger(__app_name__)
22+
coloredlogs.install(
23+
logger=_LOGGER,
24+
datefmt="%H:%M:%S",
25+
fmt="[%(levelname)s] [%(asctime)s] %(message)s",
26+
)

pephubclient/cli.py

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ def logout():
2929
def pull(
3030
project_registry_path: str,
3131
force: bool = typer.Option(False, help="Overwrite project if it exists."),
32+
zip: bool = typer.Option(False, help="Save project as zip file."),
33+
output: str = typer.Option(None, help="Output directory."),
3234
):
3335
"""
3436
Download and save project locally.
@@ -37,6 +39,8 @@ def pull(
3739
_client.pull,
3840
project_registry_path=project_registry_path,
3941
force=force,
42+
output=output,
43+
zip=zip,
4044
)
4145

4246

pephubclient/constants.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@
1212
PEPHUB_PEP_SEARCH_URL = f"{PEPHUB_BASE_URL}api/v1/namespaces/{{namespace}}/projects"
1313
PEPHUB_PUSH_URL = f"{PEPHUB_BASE_URL}api/v1/namespaces/{{namespace}}/projects/json"
1414

15+
PEPHUB_SAMPLE_URL = f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/samples/{{sample_name}}"
16+
PEPHUB_VIEW_URL = (
17+
f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/views/{{view_name}}"
18+
)
19+
PEPHUB_VIEW_SAMPLE_URL = f"{PEPHUB_BASE_URL}api/v1/projects/{{namespace}}/{{project}}/views/{{view_name}}/{{sample_name}}"
20+
1521

1622
class RegistryPath(BaseModel):
17-
protocol: Optional[str]
23+
protocol: Optional[str] = None
1824
namespace: str
1925
item: str
20-
subitem: Optional[str]
26+
subitem: Optional[str] = None
2127
tag: Optional[str] = "default"
2228

2329
@field_validator("tag")
@@ -33,3 +39,10 @@ class ResponseStatusCodes(int, Enum):
3339
NOT_EXIST = 404
3440
CONFLICT = 409
3541
INTERNAL_ERROR = 500
42+
43+
44+
USER_DATA_FILE_NAME = "jwt.txt"
45+
HOME_PATH = os.getenv("HOME")
46+
if not HOME_PATH:
47+
HOME_PATH = os.path.expanduser("~")
48+
PATH_TO_FILE_WITH_JWT = os.path.join(HOME_PATH, ".pephubclient/") + USER_DATA_FILE_NAME

pephubclient/files_manager.py

+33-20
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import pandas
66
import yaml
7+
import zipfile
78

8-
from pephubclient.constants import RegistryPath
99
from pephubclient.exceptions import PEPExistsError
1010

1111

@@ -29,17 +29,23 @@ def load_jwt_data_from_file(path: str) -> str:
2929
return f.read()
3030

3131
@staticmethod
32-
def create_project_folder(registry_path: RegistryPath) -> str:
32+
def create_project_folder(
33+
parent_path: str,
34+
folder_name: str,
35+
) -> str:
3336
"""
3437
Create new project folder
3538
36-
:param registry_path: project registry path
39+
:param parent_path: parent path to create folder in
40+
:param folder_name: folder name
3741
:return: folder_path
3842
"""
39-
folder_name = FilesManager._create_filename_to_save_downloaded_project(
40-
registry_path
41-
)
42-
folder_path = os.path.join(os.getcwd(), folder_name)
43+
if parent_path:
44+
if not Path(parent_path).exists():
45+
raise OSError(
46+
f"Parent path does not exist. Provided path: {parent_path}"
47+
)
48+
folder_path = os.path.join(parent_path or os.getcwd(), folder_name)
4349
Path(folder_path).mkdir(parents=True, exist_ok=True)
4450
return folder_path
4551

@@ -62,21 +68,28 @@ def file_exists(full_path: str) -> bool:
6268
def delete_file_if_exists(filename: str) -> None:
6369
with suppress(FileNotFoundError):
6470
os.remove(filename)
65-
66-
@staticmethod
67-
def _create_filename_to_save_downloaded_project(registry_path: RegistryPath) -> str:
68-
"""
69-
Takes query string and creates output filename to save the project to.
70-
71-
:param registry_path: Query string that was used to find the project.
72-
:return: Filename uniquely identifying the project.
73-
"""
74-
filename = "_".join(filter(bool, [registry_path.namespace, registry_path.item]))
75-
if registry_path.tag:
76-
filename += f":{registry_path.tag}"
77-
return filename
71+
print(
72+
f"\033[38;5;11m{f'File was deleted successfully -> {filename}'}\033[0m"
73+
)
7874

7975
@staticmethod
8076
def check_writable(path: str, force: bool = True):
8177
if not force and os.path.isfile(path):
8278
raise PEPExistsError(f"File already exists and won't be updated: {path}")
79+
80+
@staticmethod
81+
def save_zip_file(files_dict: dict, file_path: str, force: bool = False) -> None:
82+
"""
83+
Save zip file with provided files as dict.
84+
85+
:param files_dict: dict with files to save. e.g. {"file1.txt": "file1 content"}
86+
:param file_path: filename to save zip file to
87+
:param force: overwrite file if exists
88+
:return: None
89+
"""
90+
FilesManager.check_writable(path=file_path, force=force)
91+
with zipfile.ZipFile(
92+
file_path, mode="w", compression=zipfile.ZIP_DEFLATED
93+
) as zf:
94+
for name, res in files_dict.items():
95+
zf.writestr(name, str.encode(res))

0 commit comments

Comments
 (0)