Skip to content

Commit

Permalink
Merge pull request #68 from ITC-CRIB/pkg/refactor
Browse files Browse the repository at this point in the history
Pkg/refactor
  • Loading branch information
manuGil authored Apr 29, 2024
2 parents 9acb555 + e7d2477 commit 27d36a9
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 151 deletions.
11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ build-backend = "hatchling.build"
[project]
name = "fairly"
version = "1.0.0"
authors = [
{ name="Serkan Girgin", email="[email protected]" },
{ name="Manuel Garcia Alvarez", email="[email protected]" },
{ name="Jose Urra Llanusa", email="[email protected]" }, ]
description = "A package to create, publish, and download research datasets"
readme = "README.rst"
license = { file="LICENSE" }
requires-python = ">=3.8"
authors = [
{ name="Serkan Girgin", email="[email protected]" },
{ name="Manuel Garcia Alvarez", email="[email protected]" },
{ name="Jose Urra Llanusa", email="[email protected]" },
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand Down Expand Up @@ -43,4 +44,4 @@ dev = [
"Funding" = "https://nwo.nl/en/researchprogrammes/open-science/open-science-fund"

[project.scripts]
fairly = "cli:app"
fairly = "fairly.cli:app"
12 changes: 4 additions & 8 deletions src/cli/__init__.py → src/fairly/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import sys
import pprint as pp

from ruamel.yaml import YAML
import typer
import fairly

import cli.dataset
import cli.config


from fairly.cli import dataset
from fairly.cli import config

app = typer.Typer()
app.add_typer(cli.dataset.app, name="dataset")
app.add_typer(cli.config.app, name="config")
app.add_typer(dataset.app, name="dataset")
app.add_typer(config.app, name="config")

@app.command()
def list_repos():
Expand Down
File renamed without changes.
274 changes: 137 additions & 137 deletions src/cli/dataset.py → src/fairly/cli/dataset.py
Original file line number Diff line number Diff line change
@@ -1,138 +1,138 @@
import typer

from rich.progress import Progress, SpinnerColumn, TextColumn

import fairly


app = typer.Typer(pretty_exceptions_show_locals=False)

@app.command()
def create(
path: str = typer.Argument(help="Path where the dataset will be created"),
template: str = typer.Option("default", help="Metadata template to be used for the dataset"),
) -> None:
'''Create a local dataset under path with default template\n
fairly dataset create <path>\n
Create a local dataset under path with the specified template\n
<template> = 'zeondo, 4tu, default'\n
fairly dataset create <path> --template <template>
'''
fairly.init_dataset(path, template=template)


@app.command()
def clone(
id: str = typer.Argument(help="Dataset identifier (URL, DOI, or unique ID)"),
path: str = typer.Argument("", help="Path where the dataset will be stored"),
repo: str = typer.Option("", help="Repository option argument"),
token: str = typer.Option("", help="Access token option argument"),
notify: bool = typer.Option(False, help="Enable process notification"),
extract: bool = typer.Option(False, help="Extract archive files"),
) -> None:
'''
Clones a dataset by using its URL address, DOI or unique ID.
Examples: \n
>>> fairly dataset clone <url|doi|uid> \n \n
>>> fairly dataset clone https://zenodo.org/records/7759648 \n
>>> fairly dataset clone 10.5281/zenodo.7759648 \n
>>> fairly dataset clone <repository> <id> \n
>>> fairly dataset clone --repo zenodo 7759648 \n
'''

if repo:
if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)
dataset = client.get_dataset(id)

else:
dataset = fairly.dataset(id)

if not path:
path = dataset.doi if dataset.doi else "dataset"

for sep in ["/", "\\"]:
path = path.replace(sep, "_")

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task("Cloning dataset", total=None)

dataset.store(path, notify=fairly.notify if notify else None, extract=extract)
print(f"Dataset {id} is successfully cloned to {path}")


return None

@app.command()
def upload(
path: str = typer.Argument(help="Path where the dataset is located"),
repo: str = typer.Argument(help="Repository to upload the dataset"),
token: str = typer.Option(None, help="Access token option argument"),
notify: bool = typer.Option(False, help="Enable process notification"),
):
'''
Uploads a local dataset to a data repository.
'''
dataset = fairly.dataset(path)

# TODO: Support repository selection from the metadata template of the dataset

if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task(description=f"Uploading dataset {path}", total=None)
remote_dataset = dataset.upload(client, notify=notify)

print(f"Dataset {path} is successfully uploaded at {remote_dataset.url or remote_dataset.plain_id}")


@app.command()
def delete(
id: str = typer.Argument(help="Dataset identifier (URL address, DOI, or unique ID)"),
repo: str = typer.Option("", help="Repository option argument"),
token: str = typer.Option("", help="Access token option argument"),
):
'''
Deletes a dataset by using its URL address, DOI or unique ID.
'''
if repo:
if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)
dataset = client.get_dataset(id)

else:
dataset = fairly.dataset(id)
client = dataset.client

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task(description=f"Deleting dataset {id}", total=None)
client.delete_dataset(dataset.id)

print(f"Dataset {id} is successfully deleted.")


if __name__ == "__main__":
import typer

from rich.progress import Progress, SpinnerColumn, TextColumn

import fairly


app = typer.Typer(pretty_exceptions_show_locals=False)

@app.command()
def create(
path: str = typer.Argument(help="Path where the dataset will be created"),
template: str = typer.Option("default", help="Metadata template to be used for the dataset"),
) -> None:
'''Create a local dataset under path with default template\n
fairly dataset create <path>\n
Create a local dataset under path with the specified template\n
<template> = 'zeondo, 4tu, default'\n
fairly dataset create <path> --template <template>
'''
fairly.init_dataset(path, template=template)


@app.command()
def clone(
id: str = typer.Argument(help="Dataset identifier (URL, DOI, or unique ID)"),
path: str = typer.Argument("", help="Path where the dataset will be stored"),
repo: str = typer.Option("", help="Repository option argument"),
token: str = typer.Option("", help="Access token option argument"),
notify: bool = typer.Option(False, help="Enable process notification"),
extract: bool = typer.Option(False, help="Extract archive files"),
) -> None:
'''
Clones a dataset by using its URL address, DOI or unique ID.
Examples: \n
>>> fairly dataset clone <url|doi|uid> \n \n
>>> fairly dataset clone https://zenodo.org/records/7759648 \n
>>> fairly dataset clone 10.5281/zenodo.7759648 \n
>>> fairly dataset clone <repository> <id> \n
>>> fairly dataset clone --repo zenodo 7759648 \n
'''

if repo:
if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)
dataset = client.get_dataset(id)

else:
dataset = fairly.dataset(id)

if not path:
path = dataset.doi if dataset.doi else "dataset"

for sep in ["/", "\\"]:
path = path.replace(sep, "_")

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task("Cloning dataset", total=None)

dataset.store(path, notify=fairly.notify if notify else None, extract=extract)
print(f"Dataset {id} is successfully cloned to {path}")


return None

@app.command()
def upload(
path: str = typer.Argument(help="Path where the dataset is located"),
repo: str = typer.Argument(help="Repository to upload the dataset"),
token: str = typer.Option(None, help="Access token option argument"),
notify: bool = typer.Option(False, help="Enable process notification"),
):
'''
Uploads a local dataset to a data repository.
'''
dataset = fairly.dataset(path)

# TODO: Support repository selection from the metadata template of the dataset

if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task(description=f"Uploading dataset {path}", total=None)
remote_dataset = dataset.upload(client, notify=notify)

print(f"Dataset {path} is successfully uploaded at {remote_dataset.url or remote_dataset.plain_id}")


@app.command()
def delete(
id: str = typer.Argument(help="Dataset identifier (URL address, DOI, or unique ID)"),
repo: str = typer.Option("", help="Repository option argument"),
token: str = typer.Option("", help="Access token option argument"),
):
'''
Deletes a dataset by using its URL address, DOI or unique ID.
'''
if repo:
if token:
client = fairly.client(repo, token=token)
else:
client = fairly.client(repo)
dataset = client.get_dataset(id)

else:
dataset = fairly.dataset(id)
client = dataset.client

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient = True,
) as progress:
progress.add_task(description=f"Deleting dataset {id}", total=None)
client.delete_dataset(dataset.id)

print(f"Dataset {id} is successfully deleted.")


if __name__ == "__main__":
app()
7 changes: 6 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import pytest
import os
from tests.conftest import *

import fairly

import re

from cli import app
from fairly.cli import app

from typer.testing import CliRunner

runner = CliRunner()

def test_cli_help():
'''Test if CLI is reachable from the system terminal.'''
exit_status = os.system("fairly --help")
assert exit_status == 0

def test_show_config():
result = runner.invoke(app, ["config", "show"])
Expand Down

0 comments on commit 27d36a9

Please sign in to comment.