# Amazon S3

## Install

```bash
pip install nexus-fs[s3]
```

This installs `boto3` as the S3 client.

## Credential setup

nexus-fs uses the standard AWS credential chain. Configure at least one:

### Option 1: Environment variables

```bash
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1  # optional
```

### Option 2: AWS credentials file

```bash
aws configure
```

This writes to `~/.aws/credentials`. nexus-fs reads it automatically.

### Option 3: IAM role (EC2/ECS/Lambda)

No configuration needed. boto3 picks up the instance metadata
credentials automatically.

### Verify credentials

```bash
nexus-fs doctor --mount s3://your-bucket
```

This validates that credentials are found and that the bucket is
accessible. See [nexus-fs doctor](../cli/doctor.md) for details.

## Mount

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket")
```

The bucket mounts at `/s3/my-bucket/`.

## Mount path

| URI | Mount point |
|-----|-------------|
| `s3://my-bucket` | `/s3/my-bucket/` |
| `s3://data-lake` | `/s3/data-lake/` |

Override with `at=`:

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket", at="/data")
```

## Common patterns

### Read and write

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket")

fs.write("/s3/my-bucket/report.csv", b"date,value\n2024-01-01,42\n")
content = fs.read("/s3/my-bucket/report.csv")
```

### List objects

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket")

# List top-level
files = fs.ls("/s3/my-bucket/")

# With metadata (size, modified time)
entries = fs.ls("/s3/my-bucket/", detail=True)
```

### Copy between backends

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket", "local://./cache")

# Download from S3 to local
content = fs.read("/s3/my-bucket/model.bin")
fs.write("/local/cache/model.bin", content)
```

### Multi-mount with local cache

```python
# skip-test
import nexus.fs

fs = nexus.fs.mount_sync("s3://my-bucket", "local://./local-cache")
# Read from S3, write to local — same API for both
```

## Async usage

```python
# skip-test
import asyncio
import nexus.fs

async def main():
    fs = await nexus.fs.mount("s3://my-bucket")
    content = await fs.read("/s3/my-bucket/data.json")
    print(len(content))

asyncio.run(main())
```
