Skip to content

Commit ee46f09

Browse files
committed
4.1 updates and pipelines route
1 parent 6cdf8f6 commit ee46f09

File tree

6 files changed

+595
-239
lines changed

6 files changed

+595
-239
lines changed

src/codeocean/capsule.py

Lines changed: 7 additions & 238 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
from typing import Optional, Iterator
66
from requests_toolbelt.sessions import BaseUrlSession
77

8-
from codeocean.components import Ownership, SortOrder, SearchFilter, Permissions
8+
from codeocean.components import (
9+
Ownership,
10+
SortOrder,
11+
SearchFilter,
12+
Permissions,
13+
AppPanel,
14+
)
915
from codeocean.computation import Computation
1016
from codeocean.data_asset import DataAssetAttachParams, DataAssetAttachResults
1117
from codeocean.enum import StrEnum
@@ -26,29 +32,6 @@ class CapsuleSortBy(StrEnum):
2632
Name = "name"
2733

2834

29-
class AppPanelDataAssetKind(StrEnum):
30-
"""The kind of data asset displayed in an app panel.
31-
32-
- 'Internal' → Data stored inside Code Ocean.
33-
- 'External' → Data stored external to Code Ocean.
34-
- 'Combined' → Data containing multiple external data assets.
35-
36-
In pipelines, a data asset can only be replaced with one of the same kind.
37-
"""
38-
39-
Internal = "internal"
40-
External = "external"
41-
Combined = "combined"
42-
43-
44-
class AppPanelParameterType(StrEnum):
45-
"""The type of parameter displayed in an app panel."""
46-
47-
Text = "text"
48-
List = "list"
49-
File = "file"
50-
51-
5235
@dataclass_json
5336
@dataclass(frozen=True)
5437
class OriginalCapsuleInfo:
@@ -272,199 +255,6 @@ class CapsuleSearchResults:
272255
)
273256

274257

275-
@dataclass_json
276-
@dataclass(frozen=True)
277-
class AppPanelCategories:
278-
"""Categories for a capsule's App Panel parameters."""
279-
280-
id: str = dataclass_field(
281-
metadata={"description": "Unique identifier for the category."},
282-
)
283-
name: str = dataclass_field(
284-
metadata={"description": "Human-readable name of the category."},
285-
)
286-
description: Optional[str] = dataclass_field(
287-
default=None,
288-
metadata={"description": "Optional detailed description of the category."},
289-
)
290-
help_text: Optional[str] = dataclass_field(
291-
default=None,
292-
metadata={"description": "Optional help text providing guidance or additional information about the category."},
293-
)
294-
295-
296-
@dataclass_json
297-
@dataclass(frozen=True)
298-
class AppPanelParameters:
299-
"""Parameters for a capsule's App Panel."""
300-
301-
name: str = dataclass_field(
302-
metadata={"description": "Parameter label/display name."}
303-
)
304-
type: AppPanelParameterType = dataclass_field(
305-
metadata={"description": "Type of the parameter (text, list, file)."}
306-
)
307-
category: Optional[str] = dataclass_field(
308-
default=None,
309-
metadata={"description": "ID of category the parameter belongs to."}
310-
)
311-
param_name: Optional[str] = dataclass_field(
312-
default=None,
313-
metadata={"description": "The parameter name/argument key"}
314-
)
315-
description: Optional[str] = dataclass_field(
316-
default=None,
317-
metadata={"description": "Description of the parameter."}
318-
)
319-
help_text: Optional[str] = dataclass_field(
320-
default=None,
321-
metadata={"description": "Help text for the parameter."}
322-
)
323-
value_type: Optional[str] = dataclass_field(
324-
default=None,
325-
metadata={"description": "Value type of the parameter."}
326-
)
327-
default_value: Optional[str] = dataclass_field(
328-
default=None,
329-
metadata={"description": "Default value of the parameter."}
330-
)
331-
required: Optional[bool] = dataclass_field(
332-
default=None,
333-
metadata={"description": "Indicates if the parameter is required."}
334-
)
335-
hidden: Optional[bool] = dataclass_field(
336-
default=None,
337-
metadata={"description": "Indicates if the parameter is hidden."}
338-
)
339-
minimum: Optional[float] = dataclass_field(
340-
default=None,
341-
metadata={"description": "Minimum value for the parameter."}
342-
)
343-
maximum: Optional[float] = dataclass_field(
344-
default=None,
345-
metadata={"description": "Maximum value for the parameter."}
346-
)
347-
pattern: Optional[str] = dataclass_field(
348-
default=None,
349-
metadata={"description": "Regular expression pattern for the parameter."}
350-
)
351-
value_options: Optional[list[str]] = dataclass_field(
352-
default=None,
353-
metadata={"description": "Allowed values for the parameter."}
354-
)
355-
356-
357-
@dataclass_json
358-
@dataclass(frozen=True)
359-
class AppPanelGeneral:
360-
"""General information about a capsule's App Panel."""
361-
362-
title: Optional[str] = dataclass_field(
363-
default=None,
364-
metadata={"description": "Title of the App Panel."}
365-
)
366-
instructions: Optional[str] = dataclass_field(
367-
default=None,
368-
metadata={"description": "Instructions for using the App Panel."}
369-
)
370-
help_text: Optional[str] = dataclass_field(
371-
default=None,
372-
metadata={"description": "Help text for the App Panel."}
373-
)
374-
375-
376-
@dataclass_json
377-
@dataclass(frozen=True)
378-
class AppPanelDataAsset:
379-
"""Data asset parameter for the App Panel."""
380-
381-
id: str = dataclass_field(
382-
metadata={"description": "Unique identifier for the data asset."}
383-
)
384-
mount: str = dataclass_field(
385-
metadata={"description": "Mount path of the data asset within the capsule. "
386-
"Use this mount path to replace the currently attached data asset with your own"}
387-
)
388-
name: str = dataclass_field(
389-
metadata={"description": "Display name of the data asset."}
390-
)
391-
kind: AppPanelDataAssetKind = dataclass_field(
392-
metadata={"description": "Kind of the data asset (internal, external, combined)."}
393-
)
394-
accessible: bool = dataclass_field(
395-
metadata={"description": "Indicates if the data asset is accessible to the user."}
396-
)
397-
description: Optional[str] = dataclass_field(
398-
default=None,
399-
metadata={"description": "Optional description of the data asset parameter."}
400-
)
401-
help_text: Optional[str] = dataclass_field(
402-
default=None,
403-
metadata={"description": "Optional help text for the data asset parameter."}
404-
)
405-
406-
407-
@dataclass_json
408-
@dataclass(frozen=True)
409-
class AppPanelResult:
410-
"""Selected result files to display once the computation is complete."""
411-
412-
file_name: str = dataclass_field(
413-
metadata={"description": "Name of the result file."}
414-
)
415-
416-
417-
@dataclass_json
418-
@dataclass(frozen=True)
419-
class AppPanelProcess:
420-
"""Pipeline process name and its corresponding app panel (for pipelines of capsules only)"""
421-
422-
name: str = dataclass_field(
423-
metadata={"description": "Name of the pipeline process."}
424-
)
425-
categories: Optional[AppPanelCategories] = dataclass_field(
426-
default=None,
427-
metadata={"description": "Categories for the pipeline process's app panel parameters."}
428-
)
429-
parameters: Optional[AppPanelParameters] = dataclass_field(
430-
default=None,
431-
metadata={"description": "Parameters for the pipeline process's app panel."}
432-
)
433-
434-
435-
@dataclass_json
436-
@dataclass(frozen=True)
437-
class AppPanel:
438-
"""App Panel configuration for a capsule or pipeline, including general info, data assets,
439-
categories, parameters, and results.
440-
"""
441-
442-
general: Optional[AppPanelGeneral] = dataclass_field(
443-
default=None,
444-
metadata={"description": "General information about the App Panel."}
445-
)
446-
data_assets: Optional[list[AppPanelDataAsset]] = dataclass_field(
447-
default=None,
448-
metadata={"description": "List of data assets used in the App Panel."}
449-
)
450-
categories: Optional[list[AppPanelCategories]] = dataclass_field(
451-
default=None,
452-
metadata={"description": "Categories for organizing App Panel parameters."}
453-
)
454-
parameters: Optional[list[AppPanelParameters]] = dataclass_field(
455-
default=None,
456-
metadata={"description": "Parameters for the App Panel."}
457-
)
458-
results: Optional[list[AppPanelResult]] = dataclass_field(
459-
default=None,
460-
metadata={"description": "Result files to display after computation."}
461-
)
462-
processes: Optional[list[AppPanelProcess]] = dataclass_field(
463-
default=None,
464-
metadata={"description": "Pipeline processes and their App Panels."}
465-
)
466-
467-
468258
@dataclass
469259
class Capsules:
470260
"""Client for interacting with Code Ocean capsule APIs."""
@@ -547,24 +337,3 @@ def search_capsules_iterator(self, search_params: CapsuleSearchParams) -> Iterat
547337
return
548338

549339
params["next_token"] = response.next_token
550-
551-
def search_pipelines(self, search_params: CapsuleSearchParams) -> CapsuleSearchResults:
552-
"""Search for pipelines with filtering, sorting, and pagination
553-
options."""
554-
res = self.client.post("pipelines/search", json=search_params.to_dict())
555-
556-
return CapsuleSearchResults.from_dict(res.json())
557-
558-
def search_pipelines_iterator(self, search_params: CapsuleSearchParams) -> Iterator[Capsule]:
559-
"""Iterate through all pipelines matching search criteria with automatic pagination."""
560-
params = search_params.to_dict()
561-
while True:
562-
response = self.search_pipelines(search_params=CapsuleSearchParams(**params))
563-
564-
for result in response.results:
565-
yield result
566-
567-
if not response.has_more:
568-
return
569-
570-
params["next_token"] = response.next_token

src/codeocean/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from codeocean.custom_metadata import CustomMetadataSchema
1313
from codeocean.data_asset import DataAssets
1414
from codeocean.error import Error
15+
from codeocean.pipeline import Pipelines
1516

1617

1718
@dataclass
@@ -55,6 +56,7 @@ def __post_init__(self):
5556
self.computations = Computations(client=self.session)
5657
self.custom_metadata = CustomMetadataSchema(client=self.session)
5758
self.data_assets = DataAssets(client=self.session)
59+
self.pipelines = Pipelines(client=self.session)
5860

5961
def _error_handler(self, response, *args, **kwargs):
6062
try:

0 commit comments

Comments
 (0)