> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 파일 오퍼레이션

> CWSandbox 클라이언트를 사용하여 CoreWeave 샌드박스 인스턴스 내에서 파일을 조회하고, 쓰고, 관리합니다

이 예시에서는 `CWSANDBOX_API_KEY`에 설정된 CoreWeave API 액세스 토큰을 사용합니다. Forge API 키 인증은 [시작하기](/ko/products/sandboxes/get-started)를, CKS 요구 사항은 [배치 모드](/ko/products/sandboxes/placement)를 참조하세요.

이 가이드에서는 CWSandbox 클라이언트를 사용하여 CoreWeave 샌드박스 인스턴스 내부에서 파일을 조회하고, 쓰고, 관리하는 방법을 설명합니다. 샌드박스 안팎으로 데이터를 이동하는 워크플로를 구축하는 개발자를 대상으로 하며, 병렬 업로드 및 다운로드, 오류 처리, 대용량 파일 패턴 등을 다룹니다.

<h2 id="basic-operations">
  기본 오퍼레이션
</h2>

이 섹션의 예시에서는 가장 일반적인 파일 오퍼레이션인 샌드박스 내 경로에 데이터를 쓰고 다시 조회하는 방법을 다룹니다. 파일 오퍼레이션은 `OperationRef` 객체를 반환합니다. 완료될 때까지 대기하려면 `.result()`를 사용하세요.

<h3 id="write-files">
  파일 쓰기
</h3>

```python theme={"system"}
from cwsandbox import Sandbox

with Sandbox.run() as sandbox:
    # 파일에 바이트 쓰기
    sandbox.write_file("/app/data.txt", b"Hello, World!").result()

    # JSON 쓰기
    import json
    config = {"key": "value", "count": 42}
    sandbox.write_file(
        "/app/config.json",
        json.dumps(config).encode()
    ).result()
```

<h3 id="read-files">
  파일 조회
</h3>

```python theme={"system"}
# 파일 내용을 바이트로 조회
content = sandbox.read_file("/app/data.txt").result()
print(content.decode())  # "Hello, World!"

# JSON 조회
config_bytes = sandbox.read_file("/app/config.json").result()
config = json.loads(config_bytes.decode())
```

<h2 id="parallel-operations">
  병렬 오퍼레이션
</h2>

파일 오퍼레이션은 즉시 반환되어 자연스러운 병렬 처리를 가능하게 합니다. 여러 독립 파일에 대해 업로드 또는 다운로드를 병렬로 실행하면 전체 전송 시간을 줄일 수 있습니다.

<h3 id="parallel-uploads">
  병렬 업로드
</h3>

```python theme={"system"}
from cwsandbox import results

# 모든 업로드를 동시에 시작합니다
write_refs = [
    sandbox.write_file("/app/config.json", config_bytes),
    sandbox.write_file("/app/data.csv", data_bytes),
    sandbox.write_file("/app/model.pkl", model_bytes),
]

# 모든 업로드가 완료될 때까지 기다립니다
results(write_refs)
```

<h3 id="parallel-downloads">
  병렬 다운로드
</h3>

```python theme={"system"}
# 모든 다운로드를 동시에 시작합니다
read_refs = [
    sandbox.read_file("/app/output.json"),
    sandbox.read_file("/app/metrics.json"),
    sandbox.read_file("/app/logs.txt"),
]

# 모든 결과 조회
output, metrics, logs = results(read_refs)
```

<h2 id="upload-process-download-pattern">
  업로드-처리-다운로드 패턴
</h2>

일반적인 워크플로: 입력 파일을 업로드하고, 처리를 실행한 후, 결과를 다운로드합니다.

```python theme={"system"}
from cwsandbox import Sandbox, results

with Sandbox.run() as sandbox:
    # 1. 병렬 업로드
    results([
        sandbox.write_file("/app/config.json", config_bytes),
        sandbox.write_file("/app/input.csv", input_bytes),
    ])

    # 2. 순차 처리
    sandbox.exec(["pip", "install", "-r", "requirements.txt"]).result()
    sandbox.exec(["python", "/app/process.py"]).result()

    # 3. 병렬 다운로드
    output, metrics = results([
        sandbox.read_file("/app/output.json"),
        sandbox.read_file("/app/metrics.json"),
    ])
```

<h2 id="error-handling">
  오류 처리
</h2>

파일 오퍼레이션은 경로가 존재하지 않거나 쓰기 권한이 없는 경우 실패할 수 있습니다. 이러한 경우를 처리하고 영향을 받는 경로를 검사하려면 `SandboxFileError`를 catch하세요.

<h3 id="file-not-found">
  파일을 찾을 수 없음
</h3>

```python theme={"system"}
from cwsandbox import SandboxFileError

try:
    content = sandbox.read_file("/nonexistent/file.txt").result()
except SandboxFileError as e:
    print(f"File error: {e.filepath}")
```

<h3 id="write-errors">
  쓰기 오류
</h3>

```python theme={"system"}
try:
    sandbox.write_file("/readonly/path.txt", b"data").result()
except SandboxFileError as e:
    print(f"Cannot write to: {e.filepath}")
```

<h2 id="binary-files">
  바이너리 파일
</h2>

파일 오퍼레이션은 이미지와 직렬화된 Python 객체를 포함한 모든 바이너리 콘텐츠를 처리합니다:

```python theme={"system"}
# 이미지
with open("image.png", "rb") as f:
    sandbox.write_file("/app/image.png", f.read()).result()

# Pickle 파일 (신뢰할 수 있는 소스에서만 데이터를 언피클하세요)
import pickle
model_bytes = pickle.dumps(my_model)
sandbox.write_file("/app/model.pkl", model_bytes).result()

# 다운로드 및 언피클
model_bytes = sandbox.read_file("/app/trained_model.pkl").result()
trained_model = pickle.loads(model_bytes)
```

<Warning>
  신뢰할 수 있는 소스에서만 데이터를 언피클하세요. 피클 파일을 로드하면 임의의 코드가 실행될 수 있습니다.
</Warning>

<h2 id="text-encoding">
  텍스트 인코딩
</h2>

파일은 바이트로 전송되므로 비ASCII 문자가 손상되지 않도록 텍스트를 명시적으로 인코딩하고 디코딩해야 합니다.

```python theme={"system"}
# 텍스트 쓰기
text = "Hello, Unicode! "
sandbox.write_file("/app/text.txt", text.encode("utf-8")).result()

# 텍스트 조회
content = sandbox.read_file("/app/text.txt").result()
text = content.decode("utf-8")
```

<h2 id="large-file-considerations">
  대용량 파일 고려 사항
</h2>

`read_file` 및 `write_file` API는 소형 또는 중간 크기의 파일에 가장 적합합니다. 대용량 파일을 다룰 때는 다음 사항을 고려하세요.

* 파일이 API를 통해 전송되므로 대역폭을 감안하세요.
* 대용량 데이터 세트는 가능하면 스트리밍을 사용하세요.
* API를 통해 데이터를 전송하는 대신 객체 저장소에 직접 액세스하세요.

`object_storage_access` 매개변수는 임시 CoreWeave AI Object Storage 사용자 인증 정보를 생성하여 샌드박스의 컨테이너에 제공합니다. 이를 통해 워크로드가 버킷을 직접 읽고 쓸 수 있으므로 대용량 객체가 `read_file`이나 `write_file`을 거치지 않습니다. 이 기능을 사용하려면 먼저 조직에서 샌드박스 컨트롤 플레인에 워크로드 아이덴티티 제휴 설정을 등록해야 합니다. 자세한 내용은 [객체 저장소 액세스](/ko/products/sandboxes/operations/object-storage-access)를 참조하세요.

다음 예시에서는 CoreWeave 인증을 사용하여 버킷 하나에 대한 읽기/쓰기 액세스 권한을 가진 샌드박스를 시작한 다음, 사용자 인증 정보가 주입되었는지 확인합니다. `CWSANDBOX_API_KEY`를 설정이 완료된 조직의 CoreWeave API 액세스 토큰으로 지정하고, `[BUCKET-NAME]`을 사용할 버킷 이름으로 바꾸세요.

```python theme={"system"}
from cwsandbox import AuthStrategy, ObjectStorageAccess, ObjectStoragePermission, Sandbox

with Sandbox.run(
    auth=AuthStrategy.COREWEAVE_API_KEY,
    container_image="python:3.11",
    object_storage_access=ObjectStorageAccess(
        buckets=["[BUCKET-NAME]"],
        permission=ObjectStoragePermission.READ_WRITE,
    ),
) as sandbox:
    result = sandbox.exec(["printenv", "AWS_ENDPOINT_URL_S3"]).result()
    print(result.stdout)
```

샌드박스는 AWS SDK가 컨테이너 사용자 인증 정보를 가져올 때 조회하는 환경 변수를 설정합니다. 따라서 샌드박스 내부의 모든 S3 호환 클라이언트는 키를 명시적으로 지정하지 않아도 작동합니다. 해당 변수와 Boto3 예시는 [샌드박스 내부에서 사용자 인증 정보 사용](/ko/products/sandboxes/operations/object-storage-access#step-5-use-the-credentials-inside-the-sandbox)을 참조하세요.

사용자 인증 정보의 범위를 특정 키 접두사로 제한하려면 `object_prefix`를 사용하세요. 데이터를 읽기만 하는 워크로드에는 `ObjectStoragePermission.READ`를 사용하세요.

샌드박스 내에서만 사용하는 대용량 임시 데이터라면 볼륨을 연결하는 것이 좋습니다. 자세한 내용은 [볼륨](/ko/products/sandboxes/volumes)을 참조하세요.
