Files
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

265 lines
9.1 KiB
Plaintext

---
title: Nextcloud
icon: cloud
---
The Nextcloud resource mounts a [WebDAV](http://www.webdav.org/specs/rfc4918.html)
server (Nextcloud, ownCloud, Hetzner Storage Share, or any generic WebDAV
endpoint) at some prefix such as `/nc/`. Reads are async and streaming, with
range requests for partial reads.
For credential setup, see [Nextcloud Setup](/home/setup/nextcloud).
## Install
```bash
uv add "mirage-ai[nextcloud]"
```
## Config
```python
import os
from mirage import MountMode, Workspace
from mirage.resource.nextcloud import NextcloudConfig, NextcloudResource
config = NextcloudConfig(
url=os.environ["NEXTCLOUD_URL"],
username=os.environ["NEXTCLOUD_USERNAME"],
password=os.environ["NEXTCLOUD_PASSWORD"],
# Optional:
# verify_ssl=True,
# timeout=30,
)
resource = NextcloudResource(config)
ws = Workspace({"/nc/": resource}, mode=MountMode.WRITE)
```
`NextcloudResource(config)` takes a `NextcloudConfig` object with the
WebDAV URL plus optional Basic Auth credentials. Both `READ` and `WRITE`
modes are supported. Use an **app password** (Settings → Security in
Nextcloud) rather than your account password.
## Filesystem Layout
WebDAV resources map directly to virtual paths under the mount prefix.
For example, if your Nextcloud root contains:
```text
Documents/notes.md
Documents/contract.pdf
Photos/2024/cat.jpg
```
Then mounting at `/nc/` exposes:
```text
/nc/
Documents/
notes.md
contract.pdf
Photos/
2024/
cat.jpg
```
Path mapping: virtual `/nc/Documents/notes.md` issues HTTP requests
against `<NEXTCLOUD_URL>/Documents/notes.md`.
## Cache
The Nextcloud resource uses `IndexCacheStore`. Directory listings come
from a single `PROPFIND Depth: 1` and populate file size, type, and
ETag entries that `stat` reads via a fast path, so a `readdir` followed
by per-entry `stat` calls (which is what `ls`, FUSE `getattr`, and most
shell commands trigger) costs one HTTP request instead of N.
## Fingerprinting and Snapshots
`SUPPORTS_SNAPSHOT = True`. Per-file fingerprints come from the WebDAV
`getetag` property, so snapshot drift detection works automatically:
when a remote file changes, its ETag changes, and Mirage notices on the
next access.
## Example
```python
import asyncio
import os
from dotenv import load_dotenv
from mirage import MountMode, Workspace
from mirage.resource.nextcloud import NextcloudConfig, NextcloudResource
load_dotenv(".env.development")
config = NextcloudConfig(
url=os.environ["NEXTCLOUD_URL"],
username=os.environ["NEXTCLOUD_USERNAME"],
password=os.environ["NEXTCLOUD_PASSWORD"],
)
resource = NextcloudResource(config)
async def main() -> None:
ws = Workspace({"/nc/": resource}, mode=MountMode.WRITE)
r = await ws.execute("ls /nc/")
print(await r.stdout_str())
r = await ws.execute("tree /nc/")
print(await r.stdout_str())
r = await ws.execute("find /nc/ -name '*.md'")
print(await r.stdout_str())
r = await ws.execute("cat /nc/Documents/notes.md")
print(await r.stdout_str())
r = await ws.execute("grep TODO /nc/Documents/notes.md")
print(await r.stdout_str())
r = await ws.execute("stat /nc/Documents/notes.md")
print(await r.stdout_str())
if __name__ == "__main__":
asyncio.run(main())
```
## Shell Commands
The Nextcloud resource supports the full set of shell commands since it
operates on real file content (text, binary, JSON, CSV, etc.). Reads
benefit from HTTP `Range` requests so commands like `head -c BYTES`
don't pull the whole file.
### Read Commands
| Command | Notes |
| --------------- | ------------------------------------------ |
| `cat` | Read file content |
| `head` / `tail` | First/last N lines |
| `grep` / `rg` | Pattern search (file or directory level) |
| `jq` | Query JSON fields |
| `wc` | Line/word/byte counts |
| `stat` | File metadata (name, size, type, modified) |
| `find` | Recursive search with `-name`, `-maxdepth` |
| `tree` | Directory tree view |
| `nl` | Number lines |
| `du` | Disk usage summary |
| `file` | Detect file type |
| `strings` | Extract printable strings from binary |
| `xxd` | Hex dump |
| `md5` | MD5 checksum |
| `sha256sum` | SHA-256 checksum |
### Text Processing
| Command | Notes |
| ---------- | ------------------------------------------- |
| `awk` | Pattern scanning and processing |
| `sed` | Stream editor |
| `tr` | Translate or delete characters |
| `sort` | Sort lines |
| `uniq` | Remove duplicate lines |
| `cut` | Extract fields/columns |
| `join` | Join lines on a common field |
| `paste` | Merge lines side by side |
| `column` | Columnate output |
| `fold` | Wrap lines to a specified width |
| `expand` | Convert tabs to spaces |
| `unexpand` | Convert spaces to tabs |
| `fmt` | Simple text formatter |
| `rev` | Reverse lines |
| `tac` | Concatenate and print in reverse |
| `look` | Display lines beginning with a given string |
| `shuf` | Shuffle lines |
| `tsort` | Topological sort |
| `comm` | Compare two sorted files |
| `cmp` | Compare two files byte by byte |
| `diff` | Compare files line by line |
| `patch` | Apply a diff patch |
| `iconv` | Character encoding conversion |
### File Operations
| Command | Notes |
| -------- | --------------------------------------------- |
| `cp` | Copy files (WebDAV `COPY` method) |
| `mv` | Move/rename files (WebDAV `MOVE` method) |
| `rm` | Remove files (WebDAV `DELETE`; recursive for directories) |
| `mkdir` | Create directories (WebDAV `MKCOL`) |
| `touch` | Create empty file or update timestamp |
| `ln` | Create symbolic links |
| `tee` | Write stdin to file and stdout |
| `mktemp` | Create temporary file |
| `split` | Split file into pieces |
| `csplit` | Split file by context |
### Path Utilities
| Command | Notes |
| ---------- | -------------------------- |
| `basename` | Strip directory from path |
| `dirname` | Strip filename from path |
| `realpath` | Resolve path |
| `readlink` | Print symbolic link target |
| `ls` | List directory contents |
### Compression
| Command | Notes |
| -------- | --------------------- |
| `gzip` | Compress files |
| `gunzip` | Decompress gzip files |
| `zip` | Create zip archives |
| `unzip` | Extract zip archives |
| `tar` | Archive files |
| `zcat` | Cat compressed files |
| `zgrep` | Grep compressed files |
### Encoding
| Command | Notes |
| -------- | -------------------- |
| `base64` | Base64 encode/decode |
### Data Format Support
Commands with format-specific variants for structured data files:
| Format | Extension | Variants |
| ------- | ---------- | ---------------------------------------------- |
| Parquet | `.parquet` | cat, head, tail, wc, stat, cut, grep, ls, file |
| Feather | `.feather` | cat, head, tail, wc, stat, cut, grep, ls, file |
| ORC | `.orc` | cat, head, tail, wc, stat, cut, grep, ls, file |
| HDF5 | `.hdf5` | cat, head, tail, wc, stat, cut, grep, ls, file |
These variants auto-detect the format by extension and convert to
tabular text (CSV) for processing.
## Streaming
- **Reads**: streamed in chunks. Downstream commands like `head -n 1`
early-cancel, so you only pay for the first chunk over the wire.
- **Range reads**: `head -c BYTES` and other partial reads issue HTTP
`Range` requests that Nextcloud and most WebDAV servers honor.
- **Writes**: buffer the payload before upload. Streaming uploads
(Nextcloud's `uploads/` resumable protocol) are a possible future
follow-up.
## Use Cases
- **AI agents accessing personal cloud storage**: Mount Nextcloud so
agents can read documents, notes, and structured data on a self-hosted
cloud.
- **Self-hosted alternative to Dropbox/Box**: Same shell-command surface,
with full read+write support.
- **Multi-protocol WebDAV**: Works against any RFC 4918-compliant server,
not just Nextcloud.
- **FUSE mounting**: Expose Nextcloud through a virtual FUSE mount for
external tools.