Skip to content
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
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,27 +73,29 @@ from obiba_opal import OpalClient, HTTPError, Formatter, ImportCSVCommand, TaskS

# if 2-factor auth is enabled, user will be asked for the secret code
# Personal access token authentication is also supported (and recommended)
client = OpalClient.buildWithAuthentication(server='https://opal-demo.obiba.org', user='administrator', password='password')
client = OpalClient.buildWithAuthentication(
server="https://opal-demo.obiba.org", user="administrator", password="password"
)

try:
# upload a local CSV data file into Opal file system
fs = FileService(client)
fs.upload_file('./data.csv', '/tmp')
fs.upload_file("./data.csv", "/tmp")

# import this CSV file into a project
task = ImportCSVCommand(client).import_data('/tmp/data.csv', 'CNSIM')
status = TaskService(client).wait_task(task['id'])
task = ImportCSVCommand(client).import_data("/tmp/data.csv", "CNSIM")
status = TaskService(client).wait_task(task["id"])

# clean data file from Opal
fs.delete_file('/tmp/data.csv')
fs.delete_file("/tmp/data.csv")

if status == 'SUCCEEDED':
if status == "SUCCEEDED":
dico = DictionaryService(client)
table = dico.get_table('CNSIM', 'data')
table = dico.get_table("CNSIM", "data")
# do something ...
dico.delete_tables('CNSIM', ['data'])
dico.delete_tables("CNSIM", ["data"])
else:
print('Import failed!')
print("Import failed!")
# do something ...
except HTTPError as e:
Formatter.print_json(e.error, True)
Expand Down
12 changes: 11 additions & 1 deletion obiba_opal/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,21 @@ def project_command(
None, "--name", "-n", help="Project name. Not specifying the project name, will get the list of the projects."
),
database: str | None = typer.Option(
None, "--database", "-db", help="Project database name. If not provided only views can be added."
None,
"--database",
"-db",
help="Project database name. If not provided and internal is False, only views can be added.",
),
title: str | None = typer.Option(None, "--title", "-t", help="Project title."),
description: str | None = typer.Option(None, "--description", "-dc", help="Project description."),
tags: list[str] | None = typer.Option(None, "--tags", "-tg", help="Tags to apply to the project."),
export_folder: str | None = typer.Option(None, "--export-folder", "-ex", help="Project preferred export folder."),
internal: bool = typer.Option(
False,
"--internal",
"-i",
help="Create the project using an internal database. Ignored if database is provided.",
),
add: bool = typer.Option(False, "--add", "-a", help="Add a project (requires at least a project name)."),
delete: bool = typer.Option(False, "--delete", "-de", help="Delete a project (requires at least a project name)."),
force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation on project deletion"),
Expand All @@ -162,6 +171,7 @@ def project_command(
description=description,
tags=tags,
export_folder=export_folder,
internal=internal,
add=add,
delete=delete,
force=force,
Expand Down
14 changes: 10 additions & 4 deletions obiba_opal/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,15 @@ def download_file(self, path: str, fd: int | os.PathLike, download_password: str
bundle_request = self.client.new_request().fail_on_error()
if self.verbose:
bundle_request.verbose()
response = bundle_request.post().resource("/shell/commands/_file-bundle").accept_json().content_type_json().content(json.dumps(options)).send()
response = (
bundle_request
.post()
.resource("/shell/commands/_file-bundle")
.accept_json()
.content_type_json()
.content(json.dumps(options))
.send()
)
task = response.from_json()
task_service = TaskService(self.client)
try:
Expand Down Expand Up @@ -210,9 +218,7 @@ def get_ws(self):
return f"/files{self.path}"

def make_bundle_options(self, download_password):
options = {
"paths": [self.path]
}
options = {"paths": [self.path]}
if download_password:
options["password"] = download_password
return options
21 changes: 17 additions & 4 deletions obiba_opal/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def add_arguments(cls, parser):
"--database",
"-db",
required=False,
help="Project database name. If not provided only views can be added.",
help="Project database name. If not provided and internal is False, only views can be added.",
)
parser.add_argument("--title", "-t", required=False, help="Project title.")
parser.add_argument("--description", "-dc", required=False, help="Project description.")
Expand All @@ -49,7 +49,12 @@ def add_arguments(cls, parser):
required=False,
help="Project preferred export folder.",
)

parser.add_argument(
"--internal",
"-i",
action="store_true",
help="Create the project using an internal database. Ignored if database is provided.",
)
parser.add_argument(
"--add",
"-a",
Expand Down Expand Up @@ -94,6 +99,7 @@ def do_command(cls, args):
args.description,
args.tags,
args.export_folder,
args.internal,
)
elif args.delete:
if not args.name:
Expand Down Expand Up @@ -154,17 +160,22 @@ def add_project(
description: str = None,
tags: list = None,
export_folder: str = None,
internal: bool = False,
):
"""
Add a project.

:param name: The project name
:param database: The project database name. If not provided only views can be added. See
get_databases() for the list of databases available for storage.
:param database: The project database name. If not provided and internal is False,
only views can be added. See get_databases() for the list of databases available
for storage.
:param title: The project title
:param description: The project description
:param tags: The list of project tags
:param export_folder: The project's preferred export folder
:param internal: If True, the project will be created using an internal database. Ignored
if database is provided. If False, the project will be created without a database. Default
is False.
"""
if not name:
raise ValueError("The project name is required.")
Expand All @@ -173,6 +184,8 @@ def add_project(
project = {"name": name}
if database:
project["database"] = database
elif internal:
project["internalDatabase"] = True
if title:
project["title"] = title
else:
Expand Down
2 changes: 1 addition & 1 deletion obiba_opal/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ def cancel_task(self, id: str | int):
request.put().resource(f"/shell/command/{id}/status").send()

def wait_task(self, id: str | int, silently: bool = False):
""" Wait for the task to complete or being canceled, and return its status. """
"""Wait for the task to complete or be canceled, and return its status."""
task = self.get_task(id)
while task["status"] not in ["SUCCEEDED", "CANCELED", "FAILED", "CANCEL_PENDING"]:
if not silently:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "obiba-opal"
version = "6.1.0"
version = "6.2.0"
description = "OBiBa/Opal python client."
authors = [
{name = "Yannick Marcon", email = "yannick.marcon@obiba.org"}
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading