Skip to content

Commit 08c9d10

Browse files
Merge branch 'main' of github.com:forcedotcom/datacloud-customcode-python-sdk into sarasavilli/func_pyfile_lib_support
2 parents a6be350 + 9134460 commit 08c9d10

14 files changed

Lines changed: 83 additions & 330 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pip install salesforce-data-customcode
4040
datacustomcode init my_package
4141
```
4242

43+
To create a package of type function, pass the parameter `--code-type=function` with the init command.
44+
4345
This will yield all necessary files to get started:
4446
```
4547
.
@@ -244,6 +246,8 @@ Initialize a new development environment with a code package template.
244246

245247
Argument:
246248
- `DIRECTORY`: Directory to create project in (default: ".")
249+
Options:
250+
- `--code-type TEXT`: This can be either `function` or `script`. The default value is `script` if the argument is missing.
247251

248252

249253
#### `datacustomcode scan`
@@ -293,6 +297,7 @@ Options:
293297
- `--description TEXT`: Description of the transformation job (default: "")
294298
- `--network TEXT`: docker network (default: "default")
295299
- `--cpu-size TEXT`: CPU size for the deployment (default: `CPU_2XL`). Available options: CPU_L(Large), CPU_XL(Extra Large), CPU_2XL(2X Large), CPU_4XL(4X Large)
300+
- `--function-invoke-opt TEXT`: Currently we support only `UnstructuredChunking` for functions.
296301

297302

298303
## Docker usage

src/datacustomcode/cmd.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ def _cmd_output(
8585
**kwargs: Any,
8686
) -> tuple[int, bytes, Union[bytes, None]]:
8787
_setdefault_kwargs(kwargs)
88+
kwargs.setdefault("shell", True)
89+
# On Windows, Popen with shell=True and a sequence uses list2cmdline() which
90+
# quotes the entire string, causing cmd.exe to fail. Joining to a plain string
91+
# works correctly on both Unix (/bin/sh -c "...") and Windows (cmd.exe /c ...).
92+
cmd_arg: Union[tuple[str, ...], str] = " ".join(cmd) if kwargs.get("shell") else cmd
8893
try:
89-
kwargs.setdefault("shell", True)
90-
proc = subprocess.Popen(cmd, **kwargs)
94+
proc = subprocess.Popen(cmd_arg, **kwargs)
9195
except OSError as e:
9296
returncode, stdout_b, stderr_b = _oserror_to_output(e)
9397
else:

src/datacustomcode/deploy.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def create_deployment(
272272
raise
273273

274274

275-
PLATFORM_ENV_VAR = "DOCKER_DEFAULT_PLATFORM=linux/amd64"
275+
PLATFORM_ENV = {"DOCKER_DEFAULT_PLATFORM": "linux/amd64"}
276276
DOCKER_IMAGE_NAME = "datacloud-custom-code-dependency-builder"
277277
DEPENDENCIES_ARCHIVE_NAME = "native_dependencies"
278278
DEPENDENCIES_ARCHIVE_FULL_NAME = f"{DEPENDENCIES_ARCHIVE_NAME}.tar.gz"
@@ -289,18 +289,25 @@ def prepare_dependency_archive(
289289
cmd = f"docker images -q {DOCKER_IMAGE_NAME}"
290290
image_exists = cmd_output(cmd)
291291

292+
docker_env = {**os.environ, **PLATFORM_ENV}
293+
292294
if not image_exists:
293295
logger.info(f"Building docker image with docker network: {docker_network}...")
294296
cmd = docker_build_cmd(docker_network)
295-
cmd_output(cmd)
297+
cmd_output(cmd, env=docker_env)
296298

297-
with tempfile.TemporaryDirectory() as temp_dir:
298-
logger.info(f"Building dependencies with docker network: {docker_network}")
299+
# ignore_cleanup_errors=True: on Windows, Docker creates files inside the
300+
# mounted volume whose permissions prevent the host from deleting them.
301+
# The archive has already been copied out, so silently skipping leftover
302+
# files is safe and avoids a fatal error on context-manager exit.
303+
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as temp_dir:
304+
logger.info(
305+
f"Building dependencies archive with docker network: {docker_network}"
306+
)
299307
shutil.copy("requirements.txt", temp_dir)
300308
shutil.copy("build_native_dependencies.sh", temp_dir)
301309
cmd = docker_run_cmd(docker_network, temp_dir)
302-
cmd_output(cmd)
303-
310+
cmd_output(cmd, env=docker_env)
304311
if package_type == "function":
305312
source_py_files = os.path.join(temp_dir, "py-files")
306313
if os.path.exists(source_py_files):
@@ -326,23 +333,19 @@ def prepare_dependency_archive(
326333

327334

328335
def docker_build_cmd(network: str) -> str:
329-
cmd = (
330-
f"{PLATFORM_ENV_VAR} docker build -t {DOCKER_IMAGE_NAME} "
331-
f"--file Dockerfile.dependencies . "
332-
)
336+
cmd = f"docker build -t {DOCKER_IMAGE_NAME} --file Dockerfile.dependencies . "
333337

334338
if network != "default":
335339
cmd = cmd + f"--network {network}"
336340
logger.debug(f"Docker build command: {cmd}")
337341
return cmd
338342

339343

340-
def docker_run_cmd(network: str, temp_dir) -> str:
341-
cmd = (
342-
f"{PLATFORM_ENV_VAR} docker run --rm "
343-
f"-v {temp_dir}:/workspace "
344-
f"{DOCKER_IMAGE_NAME} "
345-
)
344+
def docker_run_cmd(network: str, temp_dir: str) -> str:
345+
# Normalise path separators: Docker expects forward slashes even on Windows,
346+
# and quoting handles paths that contain spaces.
347+
docker_path = temp_dir.replace("\\", "/")
348+
cmd = f'docker run --rm -v "{docker_path}:/workspace" {DOCKER_IMAGE_NAME} '
346349

347350
if network != "default":
348351
cmd = cmd + f"--network {network} "

src/datacustomcode/run.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
)
2626

2727
from datacustomcode.config import config
28-
from datacustomcode.scan import get_package_type
28+
from datacustomcode.scan import find_base_directory, get_package_type
2929

3030

3131
def _set_config_option(config_obj, key: str, value: str) -> None:
@@ -68,7 +68,9 @@ def run_entrypoint(
6868
f"config.json not found at {config_json_path}. config.json is required."
6969
)
7070

71-
package_type = get_package_type(entrypoint_dir)
71+
# SDK config (.datacustomcode_proj/sdk_config.json) is under project root
72+
base_directory = find_base_directory(entrypoint)
73+
package_type = get_package_type(base_directory)
7274

7375
try:
7476
with open(config_json_path, "r") as f:

src/datacustomcode/templates/function/Dockerfile

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/datacustomcode/templates/function/Dockerfile.dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM public.ecr.aws/emr-on-eks/spark/emr-7.3.0:latest
1+
FROM python:3.11-slim
22

33
USER root
44

src/datacustomcode/templates/function/account.ipynb

Lines changed: 0 additions & 86 deletions
This file was deleted.

src/datacustomcode/templates/function/examples/employee_hierarchy/employee_data.csv

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/datacustomcode/templates/function/examples/employee_hierarchy/entrypoint.py

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)