Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
3 changes: 3 additions & 0 deletions .changes/unreleased/added-20251120-025450.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: added
body: Add --format option to export command to pick .ipynb or .py when exporting notebooks
Comment thread
ayeshurun marked this conversation as resolved.
time: 2025-11-20T02:54:50.543931335Z
3 changes: 2 additions & 1 deletion docs/commands/fs/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ Export an item.
**Usage:**

```
fab export <path> -o <output_path> [-a] [-f]
fab export <path> -o <output_path> [-a] [--format <format>] [-f]
```

**Parameters:**

- `<path>`: Path to the item to export.
- `-o, --output <output_path>`: Output directory path.
- `-a, --all`: Export all items. Optional.
- `--format <format>`: Format of the export. Supported for items allowing multiple export formats, currently only Notebooks (`.ipynb`, `.py`). Optional.
- `-f, --force`: Force export without confirmation. Optional.

**Example:**
Expand Down
18 changes: 17 additions & 1 deletion src/fabric_cli/commands/fs/export/fab_fs_export_item.py
Comment thread
aviatco marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import os
from argparse import Namespace
from copy import deepcopy
from typing import Optional, Union

from fabric_cli.client import fab_api_item as item_api
Expand All @@ -12,6 +13,7 @@
from fabric_cli.core.fab_types import ItemType, definition_format_mapping
from fabric_cli.core.hiearchy.fab_folder import Folder
from fabric_cli.core.hiearchy.fab_hiearchy import Item, Workspace
from fabric_cli.errors import ErrorMessages
from fabric_cli.utils import fab_cmd_export_utils as utils_export
from fabric_cli.utils import fab_item_util, fab_mem_store, fab_storage, fab_ui

Expand Down Expand Up @@ -89,6 +91,7 @@ def export_single_item(
item_uri: Optional[bool] = False,
) -> dict:
item_def = {}
args = deepcopy(args)
Comment thread
ayeshurun marked this conversation as resolved.

if args.force or fab_ui.prompt_confirm(
"Item definition is exported without its sensitivity label. Are you sure?"
Expand All @@ -99,7 +102,20 @@ def export_single_item(

args.from_path = item.path.strip("/")
args.ws_id, args.id, args.item_type = workspace_id, item_id, str(item_type)
args.format = definition_format_mapping.get(item_type, "")

valid_export_formats = definition_format_mapping.get(item_type, {"default": ""})
export_format = (
args.format if getattr(args, "format", None) is not None else "default"
)
if export_format not in valid_export_formats:
raise FabricCLIError(
ErrorMessages.Export.invalid_export_format(
list(valid_export_formats.keys())
),
fab_constant.ERROR_INVALID_INPUT,
)
else:
args.format = valid_export_formats[export_format]

item_def = item_api.get_item_withdefinition(args, item_uri)

Comment thread
ayeshurun marked this conversation as resolved.
Expand Down
3 changes: 2 additions & 1 deletion src/fabric_cli/commands/fs/set/fab_fs_set_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def exec(item: Item, args: Namespace) -> None:
args.item_uri = format_mapping.get(item.item_type, "items")

if query_value.startswith(fab_constant.ITEM_QUERY_DEFINITION):
args.format = definition_format_mapping.get(item.item_type, "")
formats = definition_format_mapping.get(item.item_type, {"default": ""})
args.format = formats["default"]
def_response = item_api.get_item_definition(args)
definition = json.loads(def_response.text)

Expand Down
8 changes: 6 additions & 2 deletions src/fabric_cli/core/fab_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ class MirroredDatabaseFolders(Enum):
# Item Payload definition

definition_format_mapping = {
ItemType.SPARK_JOB_DEFINITION: "?format=SparkJobDefinitionV1",
ItemType.NOTEBOOK: "?format=ipynb",
ItemType.SPARK_JOB_DEFINITION: {"default": "?format=SparkJobDefinitionV1"},
ItemType.NOTEBOOK: {
"default": "?format=ipynb",
".py": "?format=fabricGitSource",
".ipynb": "?format=ipynb",
},
}
2 changes: 2 additions & 0 deletions src/fabric_cli/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .config import ConfigErrors
from .context import ContextErrors
from .cp import CpErrors
from .export import ExportErrors
from .hierarchy import HierarchyErrors
from .labels import LabelsErrors
from .mkdir import MkdirErrors
Expand All @@ -22,6 +23,7 @@ class ErrorMessages:
Config = ConfigErrors
Context = ContextErrors
Cp = CpErrors
Export = ExportErrors
Hierarchy = HierarchyErrors
Labels = LabelsErrors
Mkdir = MkdirErrors
Expand Down
10 changes: 10 additions & 0 deletions src/fabric_cli/errors/export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.


class ExportErrors:
@staticmethod
def invalid_export_format(valid_formats: list[str]) -> str:
return (
f"Invalid format. Only the following formats are supported: {valid_formats}"
Comment thread
ayeshurun marked this conversation as resolved.
Outdated
)
5 changes: 5 additions & 0 deletions src/fabric_cli/parsers/fab_fs_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ def register_export_parser(subparsers: _SubParsersAction) -> None:
action="store_true",
help="Export all. Optional",
)
export_parser.add_argument(
"--format",
metavar="",
help="Export format. Optional",
)
export_parser.add_argument(
"-f",
"--force",
Expand Down
Loading