Skip to content

Commit a528dd8

Browse files
committed
adding get_url operator
1 parent cd63989 commit a528dd8

3 files changed

Lines changed: 113 additions & 0 deletions

File tree

plugins/io/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,25 @@ dataset_or_view.draw_labels(
158158
where the operator's form allows you to configure the output directory on disk,
159159
the label field(s) to render, and any other optional arguments for
160160
`draw_labels()`.
161+
162+
### get_url (Enterprise-only)
163+
164+
[FiftyOne Enterprise](https://docs.voxel51.com/enterprise/index.html) users can
165+
use this operator to retrieve signed URLs to read/write/delete assets in cloud
166+
storage.
167+
168+
This operator is essentially a wrapper around the
169+
`fiftyone.core.storage.get_url()` method:
170+
171+
```py
172+
import fiftyone.core.storage as fos
173+
174+
path = "s3://..."
175+
method = "GET" # GET|PUT|DELETE
176+
hours = 24
177+
178+
url = fos.get_url(path, method=method, hours=hours)
179+
```
180+
181+
where the operator's form allows you to select the path, HTTP verb, and desired
182+
expiration time of the URL.

plugins/io/__init__.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,6 +2659,94 @@ def _draw_labels_inputs(ctx, inputs):
26592659
return True
26602660

26612661

2662+
class GetURL(foo.Operator):
2663+
@property
2664+
def config(self):
2665+
return foo.OperatorConfig(
2666+
name="get_url",
2667+
label="Get URL",
2668+
light_icon="/assets/icon-light.svg",
2669+
dark_icon="/assets/icon-dark.svg",
2670+
allow_delegated_execution=False,
2671+
allow_immediate_execution=True,
2672+
default_choice_to_delegated=False,
2673+
dynamic=True,
2674+
)
2675+
2676+
def resolve_input(self, ctx):
2677+
inputs = types.Object()
2678+
2679+
_get_url_inputs(ctx, inputs)
2680+
2681+
return types.Property(inputs, view=types.View(label="Get URL"))
2682+
2683+
def execute(self, ctx):
2684+
filepath = _parse_path(ctx, "filepath")
2685+
hours = ctx.params.get("hours", 24)
2686+
method = ctx.params.get("method", "GET")
2687+
2688+
# pylint: disable=no-member
2689+
url = fos.get_url(filepath, hours=hours, method=method)
2690+
2691+
return {"url": url}
2692+
2693+
def resolve_output(self, ctx):
2694+
outputs = types.Object()
2695+
2696+
# @todo if method=GET, render a download button
2697+
outputs.str("url", label="URL", view=types.MarkdownView())
2698+
2699+
return types.Property(
2700+
outputs, view=types.View(label="Get URL samples")
2701+
)
2702+
2703+
2704+
def _get_url_inputs(ctx, inputs):
2705+
file_explorer = types.FileExplorerView(button_label="Choose a file...")
2706+
prop = inputs.file(
2707+
"filepath",
2708+
required=True,
2709+
label="File",
2710+
description="Choose a file for which to generate a signed URL",
2711+
view=file_explorer,
2712+
)
2713+
filepath = _parse_path(ctx, "filepath")
2714+
2715+
inputs.int(
2716+
"hours",
2717+
default=24,
2718+
label="Hours",
2719+
description="The number of hours that the URL should be valid",
2720+
)
2721+
hours = ctx.params.get("hours", 24)
2722+
2723+
method_choices = types.Choices()
2724+
method_choices.add_choice("GET", label="GET")
2725+
method_choices.add_choice("PUT", label="PUT")
2726+
method_choices.add_choice("DELETE", label="DELETE")
2727+
2728+
inputs.enum(
2729+
"method",
2730+
method_choices.values(),
2731+
required=True,
2732+
default="GET",
2733+
label="Method",
2734+
description="The HTTP verb (GET, PUT, DELETE) to authorize",
2735+
view=method_choices,
2736+
)
2737+
method = ctx.params.get("method", "GET")
2738+
2739+
try:
2740+
# pylint: disable=no-member
2741+
url = fos.get_url(filepath, hours=hours, method=method)
2742+
view = types.Notice(label=f"[{url}]({url})")
2743+
except Exception as e:
2744+
view = types.Error(label=str(e))
2745+
2746+
prop = inputs.view("result", view)
2747+
prop.invalid = True
2748+
2749+
26622750
def _parse_path(ctx, key):
26632751
value = ctx.params.get(key, None)
26642752
return value.get("absolute_path", None) if value else None
@@ -2697,3 +2785,5 @@ def register(p):
26972785
p.register(MergeLabels)
26982786
p.register(ExportSamples)
26992787
p.register(DrawLabels)
2788+
if hasattr(foc, "TEAMS_VERSION"):
2789+
p.register(GetURL)

plugins/io/fiftyone.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ operators:
1111
- merge_labels
1212
- export_samples
1313
- draw_labels
14+
- get_url

0 commit comments

Comments
 (0)