# Files, blobs and Zarr arrays (/notebooks/files-and-arrays)

Store files and Zarr arrays in the lakehouse from a notebook, under your own catalog grants.

Not everything is a table. From a notebook you can keep files of any kind — CSVs, PDFs, Parquet,
images — and Zarr arrays in the lakehouse, next to your Iceberg tables and governed by the same
catalog grants.

## How it works

Files and arrays live in a **generic table**: a catalog entry in a namespace, like an Iceberg table,
that holds files instead of rows. Two helpers in `databaas-utils` open one for you:

| Helper | Returns |
| ------ | ------- |
| `get_store(namespace=...)` | A store for reading and writing files under a generic table |
| `get_zarr_group(table, namespace=...)` | A [Zarr](https://zarr.readthedocs.io/) group for reading and writing arrays |

Both create the namespace and the generic table if they do not exist yet. The catalog signs every
request on your behalf and checks your grants each time, so you never hold storage keys, and you can
only read or write where you have been granted access. See [data
permissions](/catalog/data-permissions).

<Callout type="warn">
  Like an Iceberg table, a generic table is shared lakehouse data, not a private folder. Keep
  experiments in a namespace of your own.
</Callout>

## Store and read files

```python title="Put, list, get and delete files"
from pathlib import Path
from databaas_utils.notebook import get_store

store = get_store(namespace="sandbox")

uri = store.put("reports", "2026/summary.csv", Path("summary.csv"))   # -> "s3://…/summary.csv"
store.put("reports", "2026/notes.txt", Path("notes.txt"))

for obj in store.list("reports", prefix="2026"):
    print(obj)

store.get("reports", "2026/notes.txt", Path("notes-downloaded.txt"))

store.delete("reports", "2026/notes.txt")
```

Keys are relative to the generic table, so `"2026/summary.csv"` is a file inside `sandbox.reports`.
Only `put` creates the generic table on first use; `get`, `list` and `delete` never do, so a
misspelled table name fails instead of silently creating an empty one. `store.open(table, key)`
returns a readable file object without staging it to disk first, and `store.uri(table, key)` returns
the `s3://` URI an object has or would have.

Pass the URI a `put` returns when you need to hand the file to something else, such as
[dlt](/pipelines/dlt-and-dbt) — not the bytes themselves.

## Store and read Zarr arrays

```python title="Write a Zarr array"
import numpy as np
from databaas_utils.notebook import get_zarr_group

root = get_zarr_group("hello_zarr", namespace="sandbox")   # created if missing
root["temperature"] = np.zeros((10, 10), dtype="f4")
```

```python title="Read it back"
root = get_zarr_group("hello_zarr", namespace="sandbox", read_only=True)
list(root.array_keys())
root["temperature"][:2, :2]
```

`read_only` and `create` choose how the group opens:

| `read_only` | `create` | Mode | Behaviour |
| ----------- | -------- | ---- | --------- |
| `True` | ignored | `r` | Read only; the store must already exist |
| `False` | `True` | `a` | Read and write; created if missing (default) |
| `False` | `False` | `r+` | Read and write; the store must already exist |

Every chunk you read or write is a separate signed request, so larger chunks and fewer reads are
faster than many small ones.

## Your token refreshes itself

`get_store()` and `get_zarr_group()` each resolve your identity on their own — there is no catalog
object to build or pass between them first. Like the Iceberg catalog, the token underneath refreshes
itself on every request, so a `store` or a Zarr `root` stays usable for as long as your notebook runs.
See [your catalog does not go stale](/notebooks/querying-data#your-catalog-does-not-go-stale).

## Find them in the Data Catalog

A generic table appears in the [Data Catalog](/catalog/browsing) in its namespace, with a format badge
and its own icon. It has no preview or schema, only its format, location and
permissions — see [table details](/catalog/table-details#tables-that-are-not-iceberg). Grant access
to it the same way as to a table.