> Full SurrealDB documentation index: https://surrealdb.com/docs/llms.txt

# File

File and FileMetadata in the Python SDK: a reference to a file in a SurrealDB bucket as a bucket and a key, key normalisation, storing a File in a record, str() and is_literal_safe(), equality, and the FileMetadata that db.files.head() and db.files.list() return.

A `File` is a reference to a file that SurrealDB stores in a bucket: a bucket name and a key. It holds no contents, and has no methods to read or write them. A `File` maps to the SurrealDB `file` type in both directions, so a record can hold one in a field. This page documents `File` and `FileMetadata`. To read and write the contents of files, use the `db.files` helpers that [Files](/docs/reference/python/concepts/files.md) describes.

```python title="Import"
from surrealdb import File, FileMetadata
```

**Source:** [file.py](https://github.com/surrealdb/surrealdb.py/blob/main/src/surrealdb/data/types/file.py), [files.py](https://github.com/surrealdb/surrealdb.py/blob/main/src/surrealdb/connections/files.py)

---

## Constructor {#constructor}

```python title="Syntax"
File(bucket, key)
```

<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>bucket</code> _(required)_</td>
            <td><code>str</code></td>
            <td>The name of the bucket, as defined with <code>DEFINE BUCKET</code>.</td>
        </tr>
        <tr>
            <td><code>key</code> _(required)_</td>
            <td><code>str</code></td>
            <td>The path of the file in the bucket. The SDK adds a leading <code>/</code> when the key has none.</td>
        </tr>
    </tbody>
</table>

A bucket or key that is not a `str` raises `TypeError`. Because of the leading `/`, `File("images", "a.png")` and `File("images", "/a.png")` are the same file.

| Property | Type | Description |
|---|---|---|
| `bucket` | `str` | The bucket name. |
| `key` | `str` | The key, which always starts with `/`. |

```python
from surrealdb import File

avatar = File("images", "photos/avatar.png")
print(avatar.bucket, avatar.key)
print(avatar == File("images", "/photos/avatar.png"))
```

```text title="Output"
images /photos/avatar.png
True
```

Two `File` values are equal when their buckets and keys are equal, and a `File` is hashable.

---

## Files in records {#records}

A `File` can be a field value or a query variable, and a `file` value that the server returns reads back as a `File`. Storing the reference does not need the bucket or the file to exist. The `file` type needs SurrealDB 3.0 or later, and a SurrealDB 2.x server refuses a `File`.

```python
from surrealdb import File, RecordID, Surreal

with Surreal("ws://localhost:8000") as db:
    db.signin({"username": "root", "password": "secret"})
    db.use("surrealdb", "docs")

    db.create(RecordID("person", "tobie"), {
        "avatar": File("images", "photos/avatar.png"),
    })

    person = db.select(RecordID("person", "tobie")).execute()
    print(repr(person["avatar"]))
```

```python title="Output"
File(bucket='images', key='/photos/avatar.png')
```

---

## Text form {#str}

`str()` renders a `File` as a SurrealQL file literal, for logs and display. The literal syntax accepts only ASCII letters, digits, `_`, `-`, `.` and `/`, and has no escapes, so a key with a space or an accent has no valid literal. `is_literal_safe()` tells you whether `str()` is valid SurrealQL.

```python
print(str(File("images", "photos/avatar.png")))
print(File("images", "my photo.png").is_literal_safe())
```

```text title="Output"
f"images:/photos/avatar.png"
False
```

Do not build query text from `str(file)`. Pass the `File` as a query variable instead, which works for every key. The `db.files` helpers do this for you.

---

## `FileMetadata` {#filemetadata}

`FileMetadata` is a frozen dataclass that describes one stored file. `db.files.head(file)` returns one, or `None` when the file does not exist, and `db.files.list(bucket)` returns a list of them.

| Field | Type | Description |
|---|---|---|
| `file` | `File` | The file. |
| `size` | `int` | The size of the contents, in bytes. |
| `updated` | [`PreciseDatetime`](/docs/reference/python/api/values/datetime.md#precisedatetime) or `None` | When the file was last written. |

```python
from surrealdb import File, Surreal

with Surreal("ws://localhost:8000") as db:
    db.signin({"username": "root", "password": "secret"})
    db.use("surrealdb", "docs")

    db.query('DEFINE BUCKET images BACKEND "memory"').execute()

    avatar = File("images", "photos/avatar.png")
    db.files.put(avatar, b"PNG data")

    metadata = db.files.head(avatar)
    print(metadata.file.key, metadata.size)
```

```text title="Output"
/photos/avatar.png 8
```

Buckets are stable from SurrealDB 4.0. On SurrealDB 3.x they are experimental, and the server needs the setting that [Files](/docs/reference/python/concepts/files.md#requirements) describes.

---

## See also

- [Files](/docs/reference/python/concepts/files.md) for the `db.files` helpers
- [Python values](/docs/reference/python/api/values.md) for every value class
- [Files](/docs/reference/query-language/language-primitives/data-types/files.md) in SurrealQL
