Skip to content

Commit b22fd96

Browse files
authored
feat: Add directory argument to allow restricting file browser on specific folder (HEXA-1356)
2 parents ae3396e + 7abe617 commit b22fd96

10 files changed

Lines changed: 103 additions & 15 deletions

openhexa/graphql/graphql_client/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
PermissionMode,
168168
PinDatasetError,
169169
PipelineError,
170+
PipelineFunctionalType,
170171
PipelineNotificationLevel,
171172
PipelineRecipientError,
172173
PipelineRunOrderBy,
@@ -645,6 +646,7 @@
645646
"PinDatasetInput",
646647
"Pipeline",
647648
"PipelineError",
649+
"PipelineFunctionalType",
648650
"PipelineNotificationLevel",
649651
"PipelinePipelineByCode",
650652
"PipelinePipelineByCodeCurrentVersion",

openhexa/graphql/graphql_client/create_pipeline_from_template_version.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
class CreatePipelineFromTemplateVersion(BaseModel):
13-
create_pipeline_from_template_version: (
14-
"CreatePipelineFromTemplateVersionCreatePipelineFromTemplateVersion"
15-
) = Field(alias="createPipelineFromTemplateVersion")
13+
create_pipeline_from_template_version: "CreatePipelineFromTemplateVersionCreatePipelineFromTemplateVersion" = Field(
14+
alias="createPipelineFromTemplateVersion"
15+
)
1616

1717

1818
class CreatePipelineFromTemplateVersionCreatePipelineFromTemplateVersion(BaseModel):

openhexa/graphql/graphql_client/create_pipeline_template_version.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
class CreatePipelineTemplateVersion(BaseModel):
13-
create_pipeline_template_version: (
14-
"CreatePipelineTemplateVersionCreatePipelineTemplateVersion"
15-
) = Field(alias="createPipelineTemplateVersion")
13+
create_pipeline_template_version: "CreatePipelineTemplateVersionCreatePipelineTemplateVersion" = Field(
14+
alias="createPipelineTemplateVersion"
15+
)
1616

1717

1818
class CreatePipelineTemplateVersionCreatePipelineTemplateVersion(BaseModel):

openhexa/graphql/graphql_client/enums.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,21 @@ class PipelineError(str, Enum):
546546
PERMISSION_DENIED = "PERMISSION_DENIED"
547547
PIPELINE_ALREADY_COMPLETED = "PIPELINE_ALREADY_COMPLETED"
548548
PIPELINE_ALREADY_STOPPED = "PIPELINE_ALREADY_STOPPED"
549+
PIPELINE_CODE_PARSING_ERROR = "PIPELINE_CODE_PARSING_ERROR"
549550
PIPELINE_DOES_NOT_SUPPORT_PARAMETERS = "PIPELINE_DOES_NOT_SUPPORT_PARAMETERS"
550551
PIPELINE_NOT_FOUND = "PIPELINE_NOT_FOUND"
551552
PIPELINE_VERSION_NOT_FOUND = "PIPELINE_VERSION_NOT_FOUND"
552553
TABLE_NOT_FOUND = "TABLE_NOT_FOUND"
553554
WORKSPACE_NOT_FOUND = "WORKSPACE_NOT_FOUND"
554555

555556

557+
class PipelineFunctionalType(str, Enum):
558+
computation = "computation"
559+
extraction = "extraction"
560+
loading = "loading"
561+
transformation = "transformation"
562+
563+
556564
class PipelineNotificationLevel(str, Enum):
557565
ALL = "ALL"
558566
ERROR = "ERROR"

openhexa/graphql/graphql_client/input_types.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
OrganizationMembershipRole,
1515
ParameterWidget,
1616
PermissionMode,
17+
PipelineFunctionalType,
1718
PipelineNotificationLevel,
1819
WorkspaceMembershipRole,
1920
)
@@ -141,6 +142,9 @@ class CreatePipelineFromTemplateVersionInput(BaseModel):
141142

142143
class CreatePipelineInput(BaseModel):
143144
code: Optional[str] = None
145+
functional_type: Optional[PipelineFunctionalType] = Field(
146+
alias="functionalType", default=None
147+
)
144148
name: str
145149
notebook_path: Optional[str] = Field(alias="notebookPath", default=None)
146150
workspace_slug: str = Field(alias="workspaceSlug")
@@ -379,6 +383,7 @@ class ParameterInput(BaseModel):
379383
code: str
380384
connection: Optional[str] = None
381385
default: Optional[Any] = None
386+
directory: Optional[str] = None
382387
help: Optional[str] = None
383388
multiple: Optional[bool] = None
384389
name: Optional[str] = None
@@ -598,9 +603,13 @@ class UpdatePipelineInput(BaseModel):
598603
)
599604
config: Optional[Any] = None
600605
description: Optional[str] = None
606+
functional_type: Optional[PipelineFunctionalType] = Field(
607+
alias="functionalType", default=None
608+
)
601609
id: Any
602610
name: Optional[str] = None
603611
schedule: Optional[str] = None
612+
tags: Optional[List[str]] = None
604613
webhook_enabled: Optional[bool] = Field(alias="webhookEnabled", default=None)
605614

606615

@@ -675,9 +684,13 @@ class UploadPipelineInput(BaseModel):
675684
config: Optional[Any] = None
676685
description: Optional[str] = None
677686
external_link: Optional[Any] = Field(alias="externalLink", default=None)
687+
functional_type: Optional[PipelineFunctionalType] = Field(
688+
alias="functionalType", default=None
689+
)
678690
name: Optional[str] = None
679-
parameters: List["ParameterInput"]
691+
parameters: Optional[List["ParameterInput"]] = None
680692
pipeline_code: Optional[str] = Field(alias="pipelineCode", default=None)
693+
tags: Optional[List[str]] = None
681694
timeout: Optional[int] = None
682695
workspace_slug: str = Field(alias="workspaceSlug")
683696
zipfile: str

openhexa/graphql/graphql_client/upgrade_pipeline_version_from_template.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
class UpgradePipelineVersionFromTemplate(BaseModel):
13-
upgrade_pipeline_version_from_template: (
14-
"UpgradePipelineVersionFromTemplateUpgradePipelineVersionFromTemplate"
15-
) = Field(alias="upgradePipelineVersionFromTemplate")
13+
upgrade_pipeline_version_from_template: "UpgradePipelineVersionFromTemplateUpgradePipelineVersionFromTemplate" = Field(
14+
alias="upgradePipelineVersionFromTemplate"
15+
)
1616

1717

1818
class UpgradePipelineVersionFromTemplateUpgradePipelineVersionFromTemplate(BaseModel):

openhexa/graphql/schema.generated.graphql

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ type CreatePipelineFromTemplateVersionResult {
794794
"""Represents the input for creating a pipeline."""
795795
input CreatePipelineInput {
796796
code: String @deprecated(reason: "The code will be autogenerated")
797+
functionalType: PipelineFunctionalType
797798
name: String!
798799
notebookPath: String
799800
workspaceSlug: String!
@@ -2634,7 +2635,7 @@ type Organization {
26342635
invitations(includeAccepted: Boolean, page: Int, perPage: Int): OrganizationInvitationPage!
26352636

26362637
"""The members of the organization."""
2637-
members(page: Int, perPage: Int, term: String): OrganizationMembershipPage!
2638+
members(page: Int, perPage: Int, role: OrganizationMembershipRole, term: String): OrganizationMembershipPage!
26382639

26392640
"""The name of the organization."""
26402641
name: String!
@@ -2748,6 +2749,7 @@ input ParameterInput {
27482749
code: String!
27492750
connection: String
27502751
default: Generic
2752+
directory: String
27512753
help: String
27522754
multiple: Boolean
27532755
name: String
@@ -2829,6 +2831,7 @@ type Pipeline {
28292831
createdAt: DateTime!
28302832
currentVersion: PipelineVersion
28312833
description: String
2834+
functionalType: PipelineFunctionalType
28322835
hasNewTemplateVersions: Boolean!
28332836
id: UUID!
28342837
name: String
@@ -2839,6 +2842,7 @@ type Pipeline {
28392842
runs(orderBy: PipelineRunOrderBy, page: Int, perPage: Int): PipelineRunPage!
28402843
schedule: String
28412844
sourceTemplate: PipelineTemplate
2845+
tags: [Tag!]!
28422846
template: PipelineTemplate
28432847
type: PipelineType!
28442848
updatedAt: DateTime
@@ -2857,13 +2861,32 @@ enum PipelineError {
28572861
PERMISSION_DENIED
28582862
PIPELINE_ALREADY_COMPLETED
28592863
PIPELINE_ALREADY_STOPPED
2864+
PIPELINE_CODE_PARSING_ERROR
28602865
PIPELINE_DOES_NOT_SUPPORT_PARAMETERS
28612866
PIPELINE_NOT_FOUND
28622867
PIPELINE_VERSION_NOT_FOUND
28632868
TABLE_NOT_FOUND
28642869
WORKSPACE_NOT_FOUND
28652870
}
28662871

2872+
"""
2873+
Represents the functional purpose of a pipeline in data workflows.
2874+
2875+
Categorizes WHAT a pipeline does in terms of business purpose:
2876+
- extraction: Data ingestion from external sources
2877+
- transformation: Data processing operations
2878+
- loading: Data output to destinations
2879+
- computation: Analytics and computational workflows
2880+
2881+
Used for pipeline categorization, filtering, and workflow organization.
2882+
"""
2883+
enum PipelineFunctionalType {
2884+
computation
2885+
extraction
2886+
loading
2887+
transformation
2888+
}
2889+
28672890
"""Represents the notification level for a pipeline recipient."""
28682891
enum PipelineNotificationLevel {
28692892
ALL
@@ -3067,7 +3090,13 @@ type PipelineTokenResult {
30673090
token: String
30683091
}
30693092

3070-
"""Represents the type of a pipeline."""
3093+
"""
3094+
Represents the technical implementation format of a pipeline.
3095+
3096+
This determines HOW a pipeline is packaged and executed:
3097+
- zipFile: Code archive with Python modules (.zip format)
3098+
- notebook: Jupyter notebook-based pipeline (.ipynb format)
3099+
"""
30713100
enum PipelineType {
30723101
notebook
30733102
zipFile
@@ -3310,12 +3339,12 @@ type Query {
33103339
pipelineVersion(id: UUID!): PipelineVersion
33113340

33123341
"""Retrieves a page of pipelines ordered by relevant name."""
3313-
pipelines(name: String, page: Int, perPage: Int, search: String, workspaceSlug: String): PipelinesPage!
3342+
pipelines(functionalType: PipelineFunctionalType, name: String, page: Int, perPage: Int, search: String, tags: [String!], workspaceSlug: String): PipelinesPage!
33143343
searchDatabaseTables(organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): DatabaseTableResultPage!
33153344
searchDatasets(organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): DatasetResultPage!
33163345
searchFiles(organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): FileResultPage!
33173346
searchPipelineTemplates(organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): PipelineTemplateResultPage!
3318-
searchPipelines(organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): PipelineResultPage!
3347+
searchPipelines(functionalType: PipelineFunctionalType, organizationId: UUID, page: Int = 1, perPage: Int = 15, query: String!, workspaceSlugs: [String]): PipelineResultPage!
33193348
team(id: UUID!): Team
33203349
teams(page: Int, perPage: Int, term: String): TeamPage!
33213350

@@ -4028,9 +4057,11 @@ input UpdatePipelineInput {
40284057
autoUpdateFromTemplate: Boolean
40294058
config: JSON
40304059
description: String
4060+
functionalType: PipelineFunctionalType
40314061
id: UUID!
40324062
name: String
40334063
schedule: String
4064+
tags: [String!]
40344065
webhookEnabled: Boolean
40354066
}
40364067

@@ -4311,16 +4342,19 @@ input UploadPipelineInput {
43114342
config: JSON
43124343
description: String
43134344
externalLink: URL
4345+
functionalType: PipelineFunctionalType
43144346
name: String
4315-
parameters: [ParameterInput!]!
4347+
parameters: [ParameterInput!]
43164348
pipelineCode: String
4349+
tags: [String!]
43174350
timeout: Int
43184351
workspaceSlug: String!
43194352
zipfile: String!
43204353
}
43214354

43224355
"""Represents the result of uploading a pipeline."""
43234356
type UploadPipelineResult {
4357+
details: String
43244358
errors: [PipelineError!]!
43254359
pipelineVersion: PipelineVersion
43264360
success: Boolean!

openhexa/sdk/pipelines/parameter.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,16 @@ def expected_type(self) -> type:
358358
"""Returns the python type expected for values."""
359359
return File
360360

361+
@property
362+
def accepts_multiple(self) -> bool:
363+
"""Only allow single file selection."""
364+
return False
365+
366+
@property
367+
def accepts_choices(self) -> bool:
368+
"""Don't allow choices for file."""
369+
return False
370+
361371
def validate_default(self, value: typing.Any | None):
362372
"""Validate the default value configured for this type."""
363373
if value is None:
@@ -444,6 +454,7 @@ def __init__(
444454
connection: str | None = None,
445455
required: bool = True,
446456
multiple: bool = False,
457+
directory: str | None = None,
447458
):
448459
validate_pipeline_parameter_code(code)
449460
self.code = code
@@ -480,6 +491,7 @@ def __init__(
480491

481492
self.widget = widget
482493
self.connection = connection
494+
self.directory = directory
483495

484496
self._validate_default(default, multiple)
485497
self.default = default
@@ -504,6 +516,7 @@ def to_dict(self) -> dict[str, typing.Any]:
504516
"connection": self.connection,
505517
"required": self.required,
506518
"multiple": self.multiple,
519+
"directory": self.directory,
507520
}
508521

509522
def _validate_single(self, value: typing.Any):
@@ -622,6 +635,7 @@ def parameter(
622635
default: typing.Any | None = None,
623636
required: bool = True,
624637
multiple: bool = False,
638+
directory: str | None = None,
625639
):
626640
"""Decorate a pipeline function by attaching a parameter to it..
627641
@@ -651,6 +665,8 @@ def parameter(
651665
multiple : bool, default=True
652666
Whether this parameter should be provided multiple values (if True, the value must be provided as a list of
653667
values of the chosen type)
668+
directory : str, optional
669+
An optional parameter to force file selection to specific directory (only used for parater type File). If the directory does not exist, it will be ignored.
654670
655671
Returns
656672
-------
@@ -673,6 +689,7 @@ def decorator(fun):
673689
widget=widget,
674690
connection=connection,
675691
multiple=multiple,
692+
directory=directory,
676693
),
677694
)
678695

openhexa/sdk/pipelines/runtime.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ def get_pipeline(pipeline_path: Path) -> Pipeline:
294294
Argument("connection", [ast.Constant]),
295295
Argument("required", [ast.Constant], default_value=True),
296296
Argument("multiple", [ast.Constant], default_value=False),
297+
Argument("directory", [ast.Constant]),
297298
),
298299
)
299300

0 commit comments

Comments
 (0)