Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Code Workspaces 활용과 제약 FAQ

PySpark를 사용할 수 있나요?

Jupyter에서 PySpark를 사용할 수 있지만 작업공간 컨테이너의 CPU와 메모리로 실행하는 local 모드입니다. 분산 Spark 클러스터가 필요하면 Pipeline Builder 또는 Code Repositories를 사용합니다.

Libraries에서 pyspark와 openjdk를 설치하고 사용하는 PySpark에 맞는 OpenJDK 버전을 고정합니다.

PySpark 범위Code Workspaces의 OpenJDK 안내
4.0.0 미만8.x, 11.x 또는 17.x
4.0.0 이상17.x 또는 21.x

java.lang.UnsupportedOperationException: getSubject is supported only if a security manager is allowed 같은 오류는 해당 PySpark 버전에 지원되는 OpenJDK로 맞춥니다.

다음 예는 PySpark 4.0 이상, PyArrow와 2 CPU/16 GB 작업공간을 전제로 합니다. parquet_foundry_dataset 입력 별칭에는 col1이 있는 Parquet 데이터가, spark_output에는 출력 데이터셋이 등록되어 있어야 합니다.

새 커널에서 JVM을 시작하기 전에 driver 메모리를 지정합니다.

import os

os.environ["PYSPARK_SUBMIT_ARGS"] = "--driver-memory 10g pyspark-shell"

from foundry.transforms import Dataset
from pyspark.sql import SparkSession
import pyspark.sql.functions as F

files = Dataset.get("parquet_foundry_dataset").files().download()
if not files:
    raise ValueError("The input dataset has no Parquet files")

spark = (
    SparkSession.builder
    .appName("ParquetExample")
    .master("local[2]")
    .config("spark.sql.shuffle.partitions", "6")
    .getOrCreate()
)
spark_df = spark.read.parquet(*files.values())
df_processed = spark_df.filter(F.col("col1") == 1)
Dataset.get("spark_output").write_table(df_processed.toArrow())

local[2]는 두 실행 스레드이며 shuffle partition 6개는 이 예의 CPU 수 약 세 배로 잡은 값입니다. JVM driver에 전체 메모리의 약 50~65%, Python/Arrow와 native overhead에 약 20~35% 등의 여유를 고려하되 실제 합계는 작업공간 한도 안에 있어야 합니다. 예시의 10g는 Spark의 메모리 단위를 사용합니다.

spark.driver.memoryOverhead는 YARN/Kubernetes의 클러스터 모드 자원 배정에 관한 설정이며 local[2]에서 Python/Arrow 메모리를 별도로 예약하는 기능은 아닙니다. 호스팅 플랫폼과 Spark 실행 모드를 구분합니다.

toArrow는 PySpark 4.0.0부터 제공되며 결과를 driver 메모리에 모읍니다. 4.0 이전에는 마지막 쓰기를 Dataset.get("spark_output").write_table(df_processed.toPandas())로 바꿀 수 있습니다. 이 경로도 결과 전체를 메모리에 올리므로 결과 크기를 제한해야 합니다.

외부 API와 IDE는 무엇을 지원하나요?

VS Code, JupyterLab과 RStudio Workbench를 지원합니다. 외부 API는 소스를 우선 사용합니다. CBAC 활성 환경에서는 Control Panel에서 구성한 네트워크 정책 경로를 사용합니다.

대화형 작업공간의 외부 연결과 그 작업공간에서 게시한 transform의 지원 범위는 다릅니다. Jupyter transform과 R transform은 외부 서비스 API 호출을 지원하지 않습니다.

코드 뷰어에 어떤 코드가 보이나요?

코드 뷰어는 저장소에 커밋하고 동기화한 상태를 보여 줍니다. 로컬 개발 환경이나 각 IDE의 미게시 변경은 보이지 않습니다. 편집 작업공간 없이 사용할 수 있습니다.

중지된 VS Code 작업공간을 열 때는 기본으로 코드 뷰어를 먼저 표시하고 세션을 백그라운드에서 시작합니다. 준비되어도 자동으로 편집기로 전환하지 않으므로 VS Code 탭을 선택합니다. Settings > Preferences에서 해당 동작을 끌 수 있습니다.

지원하지 않는 Python 패키지가 있나요?

보안상의 이유로 folium과 pandasgui는 지원하지 않습니다. 필요한 업무가 있으면 Palantir 담당자와 지원 경로를 확인합니다.

저장소에서 notebook이 JSON으로 보이는 이유는 무엇인가요?

.ipynb는 셀 단위 코드와 메타데이터를 담는 IPython notebook JSON 형식입니다. 코드 뷰어에서 지원 notebook의 렌더링 보기와 소스 보기를 선택할 수 있습니다.

조직 패키지를 사용할 수 있나요?

Conda/PyPI/CRAN 채널을 Foundry가 proxy하도록 구성하여 프로젝트에 제공할 수 있습니다. 조직 채널 연결은 Palantir 담당자에게 문의합니다. 작업공간의 패키지 설치는 기반 저장소의 Libraries 탭이 아니라 작업공간 왼쪽 Packages/Libraries 패널을 사용합니다.

Code Repositories에서 수정해도 되나요?

작업공간에서 만든 코드도 기반 Code Repository에서 직접 수정할 수 있습니다. 커밋한 원격 변경은 작업공간에서 Sync 또는 Reset changes로 가져옵니다. Reset changes를 사용하기 전에는 미게시 로컬 변경을 보존합니다.

Code Repositories는 PR, 충돌 해결과 저장소 관리에 사용하고 코드는 각 작업공간에서 개발할 수 있습니다.

동료의 화면이 다른 이유는 무엇인가요?

JupyterLab과 RStudio는 사용자별 환경을 격리합니다. 다른 사용자와 코드 변경을 공유하려면 Sync Changes로 기반 저장소에 게시하고, 상대방이 Sync 또는 Reset changes로 가져와야 합니다. 동시 작업은 독립 브랜치를 권장합니다.

일부 파일은 기본 .gitignore로 제외하며 Jupyter .ipynb의 출력도 동기화할 때 제거합니다. 데이터를 코드 저장소에 넣는 방식으로 세션 상태를 공유하지 않습니다.

추가 LaTeX 패키지를 설치할 수 있나요?

기본 환경은 TinyTeX-1에 해당하는 일반 R Markdown 렌더링 의존성을 포함합니다. 추가 패키지는 신뢰할 수 있는 TDS archive를 사용합니다.

  1. 필요한 .tds.zip을 준비합니다. CTAN에서 제공하는 패키지 archive 등을 사용할 수 있습니다.
  2. Foundry의 새 또는 기존 데이터셋에 업로드하고 Upload to a dataset without a schema를 선택합니다. 여러 archive를 함께 둘 수 있습니다.
  3. Data > Read existing datasets로 입력을 등록합니다. 아래 별칭은 my_latex_packages입니다.
  4. .Rprofile에서 다운로드하고 TEXMFLOCAL에 TDS 구조를 풀도록 설정합니다.
library(foundry)

files <- datasets.list_files("my_latex_packages")
local_files <- datasets.download_files("my_latex_packages", files)
texmflocal <- system2("kpsewhich", c("--var-value", "TEXMFLOCAL"), stdout = TRUE)
lookup_status <- attr(texmflocal, "status")
if (length(texmflocal) != 1L || !nzchar(texmflocal) ||
    (!is.null(lookup_status) && lookup_status != 0L)) {
  stop("Unable to determine TEXMFLOCAL")
}
dir.create(texmflocal, recursive = TRUE, showWarnings = FALSE)
if (!dir.exists(texmflocal) || file.access(texmflocal, 2) != 0L) {
  stop("TEXMFLOCAL is not writable")
}
for (archive in unlist(local_files, use.names = FALSE)) {
  unzip(archive, exdir = texmflocal)
}
if (system2("mktexlsr", shQuote(texmflocal)) != 0L) {
  stop("Unable to update the TeX filename database")
}

TEXMFLOCAL의 파일 이름 데이터베이스를 갱신해야 새 파일을 찾을 수 있습니다. 실제 추가한 패키지를 R Markdown의 header-includes에 지정합니다. 아래 booktabs는 패키지 이름을 넣는 형식의 예입니다.

---
output: pdf_document
header-includes:
  - \usepackage{booktabs}
---

사용자 폰트를 쓸 수 있나요?

사용 및 배포 권한이 있는 TTF 파일을 준비하고 스키마 없는 데이터셋으로 업로드합니다. Data에서 my_fonts 같은 별칭으로 등록한 뒤 R 콘솔에서 내려받아 저장소의 fonts 디렉터리에 복사합니다.

library(foundry)

font_files <- datasets.list_files("my_fonts")
local_fonts <- datasets.download_files("my_fonts", font_files)
font_directory <- "/home/user/repo/fonts"
dir.create(font_directory, recursive = TRUE, showWarnings = FALSE)
copied <- file.copy(unlist(local_fonts, use.names = FALSE), font_directory)
if (!all(copied)) {
  stop("Some fonts were not copied; check paths and existing file names")
}

이름이 같은 기존 파일을 자동으로 덮어쓰지 않습니다. 버전 관리에 포함할 파일을 확인한 뒤 동기화합니다.

HTML은 사용자 CSS의 @font-face로 파일을 연결하고 font-family를 지정합니다. 다음은 fonts/ReportFont.ttf라는 실제 파일을 준비한 경우의 styles.css 예입니다.

@font-face {
  font-family: ReportFont;
  src: url("fonts/ReportFont.ttf") format("truetype");
}
body {
  font-family: ReportFont, sans-serif;
}

R Markdown HTML 출력에서 CSS를 선택합니다.

---
output:
  html_document:
    css: styles.css
    self_contained: true
---

TTF를 PDF에 사용하려면 XeLaTeX 또는 LuaLaTeX 같은 fontspec 지원 엔진을 사용합니다. 아래는 같은 파일로 별도 폰트 명령을 정의하는 R Markdown 예입니다.

---
output:
  pdf_document:
    latex_engine: xelatex
header-includes:
  - |
    \usepackage{fontspec}
    \newfontfamily\reportfont[Path=fonts/]{ReportFont.ttf}
---

문서에서 \reportfont를 적용할 부분을 지정합니다. 파일명과 글꼴의 문자 지원 범위는 실제 준비한 폰트에 맞춥니다.

코드 실행 중 자동 일시 중지를 막을 수 있나요?

Jupyter의 %%keep_alive cell magic을 사용하면 그 셀의 코드가 실행되는 동안 최대 24시간 유지합니다. 작업공간의 최대 세션 시간을 넘기는 기능은 아닙니다.

아래는 category와 수치 value 열을 가진 analysis_input을 Data에 등록한 경우의 실제 집계 셀입니다.

%%keep_alive
from foundry.transforms import Dataset

analysis = Dataset.get("analysis_input").read_table(format="pandas")
summary = analysis.groupby("category")["value"].sum()
print(summary)

브라우저 탭을 닫거나 오랫동안 유휴 상태로 두면 JupyterLab이 셀 출력을 표시하거나 보존하지 않을 수 있습니다. 출력을 변수에 모으려면 별도 실행에서 %%capture를 함께 사용합니다.

%%keep_alive
%%capture cell_output
from foundry.transforms import Dataset

analysis = Dataset.get("analysis_input").read_table(format="pandas")
summary = analysis.groupby("category")["value"].sum()
print(summary)

같은 세션의 다음 셀에서 stdout과 stderr를 파일에 저장할 수 있습니다. capture 변수 자체는 세션 메모리에 있으므로 세션이 끝나기 전에 저장해야 합니다.

from pathlib import Path

output_file = Path("/home/user/data/cell_output.txt")
output_file.parent.mkdir(parents=True, exist_ok=True)
with output_file.open("w", encoding="utf-8") as file:
    file.write(cell_output.stdout)
    file.write(cell_output.stderr)

/home/user/data는 일반 데이터 체크포인트에 포함되지만 Restricted outputs mode에서는 데이터 체크포인트가 꺼집니다. 사용자 간 공유하거나 장기간 사용할 출력은 허용된 Foundry 데이터셋 쓰기 경로를 사용합니다.

작업공간 파일을 내려받으려면 어떻게 하나요?

IDE의 기본 파일 다운로드는 플랫폼의 내보내기 통제를 적용하기 위해 비활성화되어 있습니다. Data > Write data to new dataset에서 출력과 별칭을 만들고 Non-tabular dataset을 선택한 뒤 실제 파일 또는 디렉터리 경로를 지정합니다.

생성 코드를 실행하여 파일을 데이터셋에 쓴 다음 데이터셋 링크로 Preview를 열고 플랫폼의 다운로드 기능을 사용합니다. 관리자는 내보내기 사유 제출이나 수량 제한을 적용할 수 있습니다.