Skip to content
Open
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
129 changes: 98 additions & 31 deletions openhexa/cli/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,47 @@ def get_pipeline_from_code(pipeline_code: str) -> dict[str, typing.Any]:
return data["pipelineByCode"]


def create_pipeline(pipeline_name: str, functional_type: str = None, tags: list[str] = None):
"""Create a pipeline using the API."""
def _build_pipeline_version_input(
pipeline,
pipeline_directory_path: str | Path,
name: str = None,
description: str = None,
external_link: str = None,
) -> dict:
"""Build the GraphQL input to create a new pipeline version."""
zip_file = generate_zip_file(pipeline_directory_path.absolute())

if settings.debug:
# Write zip_file to disk for debugging
with open("pipeline.zip", "wb") as debug_file:
debug_file.write(zip_file.read())
zip_file.seek(0)

return {
"name": name,
"description": description,
"externalLink": external_link,
"zipfile": base64.b64encode(zip_file.read()).decode("ascii"),
"parameters": [p.to_dict() for p in pipeline.parameters],
"timeout": pipeline.timeout,
}


def create_pipeline(
pipeline_name: str,
pipeline_directory_path: str | Path = None,
version_name: str = None,
version_description: str = None,
version_external_link: str = None,
functional_type: str = None,
tags: list[str] = None,
):
"""Create a pipeline, optionally with its first version in a single atomic call.

When ``pipeline_directory_path`` is provided, the directory is zipped and sent as
the first version (atomic on the backend). The returned dict then carries both the
``pipeline`` and the ``pipelineVersion`` keys; otherwise only ``pipeline`` is set.
"""
if settings.current_workspace is None:
raise NoActiveWorkspaceError

Expand All @@ -311,27 +350,64 @@ def create_pipeline(pipeline_name: str, functional_type: str = None, tags: list[
if tags:
input_data["tags"] = tags

if pipeline_directory_path is not None:
pipeline = get_pipeline(pipeline_directory_path.absolute())
input_data["version"] = _build_pipeline_version_input(
pipeline,
pipeline_directory_path,
name=version_name,
description=version_description,
external_link=version_external_link,
)

data = graphql(
"""
mutation createPipeline($input: CreatePipelineInput!) {
createPipeline(input: $input) {
success
errors
pipeline {
id
code
name
mutation createPipeline($input: CreatePipelineInput!) {
createPipeline(input: $input) {
success
errors
pipeline {
id
code
permissions {
createTemplateVersion {
isAllowed
}
}
template {
id
code
name
}
}
pipelineVersion {
id
versionName
pipeline {
id
code
permissions {
createTemplateVersion {
isAllowed
}
}
template {
id
code
name
}
}
}
}
}
}
}
""",
""",
{"input": input_data},
)

if not data["createPipeline"]["success"]:
raise Exception(data["createPipeline"]["errors"])

return data["createPipeline"]["pipeline"]
return data["createPipeline"]


def download_pipeline_sourcecode(pipeline_code, output_path: Path = None, force_overwrite=False):
Expand Down Expand Up @@ -628,27 +704,18 @@ def upload_pipeline(
if settings.current_workspace is None:
raise NoActiveWorkspaceError

directory = pipeline_directory_path.absolute()
pipeline = get_pipeline(directory)
zip_file = generate_zip_file(directory)

if settings.debug:
# Write zip_file to disk for debugging
with open("pipeline.zip", "wb") as debug_file:
debug_file.write(zip_file.read())
zip_file.seek(0)

base64_content = base64.b64encode(zip_file.read()).decode("ascii")
pipeline = get_pipeline(pipeline_directory_path.absolute())

input_data = {
"workspaceSlug": settings.current_workspace,
"code": target_pipeline_code,
"name": name,
"description": description,
"externalLink": link,
"zipfile": base64_content,
"parameters": [p.to_dict() for p in pipeline.parameters],
"timeout": pipeline.timeout,
**_build_pipeline_version_input(
pipeline,
pipeline_directory_path,
name=name,
description=description,
external_link=link,
),
}

if functional_type or pipeline.functional_type:
Expand Down
34 changes: 22 additions & 12 deletions openhexa/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,20 +461,30 @@ def pipelines_push(
click.confirm(confirmation_message, default=True, abort=True)

normalized_tags = [normalize_tag(t) for t in tag] if tag else []
selected_pipeline = selected_pipeline or create_pipeline(
pipeline.name, functional_type=functional_type, tags=normalized_tags
)
uploaded_pipeline_version = None
try:
uploaded_pipeline_version = upload_pipeline(
selected_pipeline["code"],
path,
name,
description=description,
link=link,
functional_type=functional_type,
tags=normalized_tags,
)
if selected_pipeline:
uploaded_pipeline_version = upload_pipeline(
selected_pipeline["code"],
path,
name,
description=description,
link=link,
functional_type=functional_type,
tags=normalized_tags,
)
else:
create_result = create_pipeline(
pipeline.name,
path,
version_name=name,
version_description=description,
version_external_link=link,
functional_type=functional_type,
tags=normalized_tags,
)
uploaded_pipeline_version = create_result["pipelineVersion"]
selected_pipeline = create_result["pipeline"]
version_url = click.style(
f"{settings.public_api_url}/workspaces/{workspace}/pipelines/{selected_pipeline['code']}",
fg="bright_blue",
Expand Down
16 changes: 16 additions & 0 deletions openhexa/graphql/graphql_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
CreateAccessmodProjectError,
CreateAccessmodProjectMemberError,
CreateAccessmodZonalStatisticsError,
CreateAssistantConversationError,
CreateBucketFolderError,
CreateConnectionError,
CreateDatasetError,
Expand Down Expand Up @@ -156,6 +157,7 @@
DHIS2MetadataType,
DisableTwoFactorError,
EnableTwoFactorError,
FileEncoding,
FileSampleStatus,
FileType,
GenerateChallengeError,
Expand All @@ -171,6 +173,7 @@
LaunchAccessmodAnalysisError,
LaunchNotebookServerError,
LinkDatasetError,
LinkedObjectType,
LoginError,
MembershipRole,
MessagePriority,
Expand Down Expand Up @@ -233,6 +236,7 @@
UpdateWorkspaceMemberError,
UpgradePipelineVersionFromTemplateError,
VerifyDeviceError,
WebappOperationScope,
WebappType,
WorkspaceInvitationStatus,
WorkspaceMembershipRole,
Expand Down Expand Up @@ -275,6 +279,7 @@
CreateAccessmodProjectInput,
CreateAccessmodProjectMemberInput,
CreateAccessmodZonalStatisticsInput,
CreateAssistantConversationInput,
CreateBucketFolderInput,
CreateConnectionInput,
CreateDatasetInput,
Expand All @@ -286,9 +291,11 @@
CreatePipelineInput,
CreatePipelineRecipientInput,
CreatePipelineTemplateVersionInput,
CreatePipelineVersionInput,
CreateTeamInput,
CreateWebappInput,
CreateWorkspaceInput,
DatasetVersionFileContentInput,
DeclineWorkspaceInvitationInput,
DeleteAccessmodAnalysisInput,
DeleteAccessmodFilesetInput,
Expand Down Expand Up @@ -392,6 +399,7 @@
UpgradePipelineVersionFromTemplateInput,
UploadPipelineInput,
VerifyDeviceInput,
WebappFileInput,
WebappSourceInput,
WorkspaceInvitationInput,
WorkspacePermissionInput,
Expand Down Expand Up @@ -541,6 +549,8 @@
"CreateAccessmodProjectMemberInput",
"CreateAccessmodZonalStatisticsError",
"CreateAccessmodZonalStatisticsInput",
"CreateAssistantConversationError",
"CreateAssistantConversationInput",
"CreateBucketFolderError",
"CreateBucketFolderInput",
"CreateConnection",
Expand Down Expand Up @@ -580,6 +590,7 @@
"CreatePipelineTemplateVersionCreatePipelineTemplateVersionPipelineTemplate",
"CreatePipelineTemplateVersionError",
"CreatePipelineTemplateVersionInput",
"CreatePipelineVersionInput",
"CreateTeamError",
"CreateTeamInput",
"CreateTemplateVersionPermissionReason",
Expand Down Expand Up @@ -609,6 +620,7 @@
"DatasetDatasetVersionsItems",
"DatasetDatasetVersionsItemsCreatedBy",
"DatasetDatasetWorkspace",
"DatasetVersionFileContentInput",
"Datasets",
"DatasetsDatasets",
"DatasetsDatasetsItems",
Expand Down Expand Up @@ -683,6 +695,7 @@
"DisableTwoFactorInput",
"EnableTwoFactorError",
"EnableTwoFactorInput",
"FileEncoding",
"FileSampleStatus",
"FileType",
"GenerateChallengeError",
Expand Down Expand Up @@ -732,6 +745,7 @@
"LaunchNotebookServerInput",
"LinkDatasetError",
"LinkDatasetInput",
"LinkedObjectType",
"LogPipelineMessageInput",
"LoginError",
"LoginInput",
Expand Down Expand Up @@ -912,6 +926,8 @@
"UploadPipelineUploadPipeline",
"VerifyDeviceError",
"VerifyDeviceInput",
"WebappFileInput",
"WebappOperationScope",
"WebappSourceInput",
"WebappType",
"Workspace",
Expand Down
Loading
Loading