HTTP server exposing local filesystem as a wcpan.drive feed API
Project description
wcpan.drive.feed
An HTTP server that watches local filesystem paths with inotify, computes file metadata lazily, and exposes a token-based change log API — similar to Google Drive's changes API. This enables clients to efficiently poll for incremental changes without full directory scans.
Features
- Watches directories recursively via inotify (Linux only)
- Computes MD5 hash, MIME type, and image/video dimensions per file
- Token-based change log API: clients request only changes since their last cursor
- Merges intermediate events (e.g. multiple modifies → single update; create+delete → skip)
- No authentication (designed for intranet use)
Requirements
- Linux (inotify)
- Python 3.12+
libmagic1andmediainfosystem packages
Installation
# Install system dependencies
apt-get install libmagic1 mediainfo
# Install Python dependencies
make venv
Configuration
Create a YAML config file:
host: "0.0.0.0"
port: 8080
database_url: "/data/db/server.db"
watches:
media: /mnt/media
photos: /mnt/photos
Running
uv run -m wcpan.drive.feed --config=/path/to/server.yaml
The --config flag defaults to /data/server.yaml.
API
GET /api/v1/cursor
Returns the current change log cursor (the latest change ID).
{ "cursor": 42 }
GET /api/v1/changes?cursor=<int>
Returns all changes since the given cursor. Missing cursor defaults to 0. Invalid cursor returns HTTP 400.
{
"cursor": 57,
"changes": [
{
"removed": false,
"node": {
"id": "...",
"parent_id": "...",
"name": "image.jpg",
"is_directory": false,
"ctime": "2026-03-04T12:00:00+00:00",
"mtime": "2026-03-04T12:00:00+00:00",
"mime_type": "image/jpeg",
"hash": "d41d8cd98f00b204e9800998ecf8427e",
"size": 204800,
"is_image": true,
"is_video": false,
"width": 1920,
"height": 1080,
"ms_duration": 0
}
},
{
"removed": true,
"node_id": "..."
}
]
}
Nodes appear in two phases: first with hash: "" immediately after detection, then again with the full hash/MIME/dimensions after metadata computation completes. Clients should treat a second update for the same node as the final state.
GET /api/v1/root
Returns the virtual super-root node (parent of all watch-root directories).
{
"id": "00000000-0000-0000-0000-000000000000",
"parent_id": null,
"name": "",
"is_directory": true,
"ctime": "2026-03-04T12:00:00+00:00",
"mtime": "2026-03-04T12:00:00+00:00",
"mime_type": "",
"hash": "",
"size": 0,
"is_image": false,
"is_video": false,
"width": 0,
"height": 0,
"ms_duration": 0
}
GET /api/v1/nodes/{id}/path
Returns the absolute filesystem path for a node.
{ "path": "/mnt/media/photos/image.jpg" }
Returns HTTP 404 if the node does not exist, HTTP 400 if the node is the super-root.
Development
# Run tests
make test
# Format code
make format
# Lint
make lint
How It Works
- On startup, the server checks the database schema version. A new database is initialized automatically; a version mismatch raises an error and stops the server. Then it scans all configured watch paths and inserts/updates nodes in the local SQLite database.
- watchdog monitors each path for filesystem events (create, modify, delete, move).
- File metadata (MD5, MIME type, image/video dimensions) is computed in a
ProcessPoolExecutorto avoid blocking the event loop. - Every change is appended to a
changestable. The/changesendpoint merges overlapping events per node — the last event wins — so clients always see the effective state.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wcpan_drive_feed-1.0.1.tar.gz.
File metadata
- Download URL: wcpan_drive_feed-1.0.1.tar.gz
- Upload date:
- Size: 92.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48262caeed8f1e142b64cbaceaa12223085e13e8bf08c47c3b07fc78ba009240
|
|
| MD5 |
7e98f095c223eb9706d7f6fc7d171250
|
|
| BLAKE2b-256 |
56513e47f35889fefaf8f6a901be0a87fa1e712ac76438cb9abfc2bdef3f7a95
|
File details
Details for the file wcpan_drive_feed-1.0.1-py3-none-any.whl.
File metadata
- Download URL: wcpan_drive_feed-1.0.1-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a463b32d80edd9b4f9169be7801f52e2dceeca23b25e164c7715274e208daae
|
|
| MD5 |
c2a5d15c8eb30d0e1e60eb6e9bb8ddcb
|
|
| BLAKE2b-256 |
c990394c99aeca1c6849e01b542e8aabd7676635722673b02a62326e2e4d844b
|