Skip to content

Quickstart

Run with Docker

git clone https://github.com/dataresearchcenter/putfs
cd putfs
docker compose up

This starts two services:

  • api – PutFS on a unix socket (internal, not exposed)
  • nginx – reverse proxy on port 8000 (exposed)

The storage root defaults to ./data and is configured via the PUTFS_ROOT environment variable.

Set up a key

Create a keys file at ./keys/keys.conf:

map "$http_x_api_key:$http_x_api_secret" $key_ok {
    default           0;
    "putfs_demo:demo" 1;
}

map "$http_x_api_key:$request_method:$request_uri" $auth_ok {
    default                          0;
    "~^putfs_demo:[^:]+:/.+"        1;
}

Then reload nginx: docker compose exec nginx nginx -s reload

See Auth for key scoping by path and method.

Usage

Upload a file:

curl -X PUT \
  -H "X-Api-Key: putfs_demo" \
  -H "X-Api-Secret: demo" \
  http://localhost:8000/my-dataset/hello.txt \
  -d "hello world"

Download it:

curl \
  -H "X-Api-Key: putfs_demo" \
  -H "X-Api-Secret: demo" \
  http://localhost:8000/my-dataset/hello.txt

List objects in a path prefix (trailing slash):

curl \
  -H "X-Api-Key: putfs_demo" \
  -H "X-Api-Secret: demo" \
  http://localhost:8000/my-dataset/

Delete it:

curl -X DELETE \
  -H "X-Api-Key: putfs_demo" \
  -H "X-Api-Secret: demo" \
  http://localhost:8000/my-dataset/hello.txt

How requests flow

Nginx serves files directly from the data volume for reads. Writes, deletes, and listing go through the PutFS API upstream.

client -> nginx
            |-- GET static file -> serve from /data (fast path)
            `-- PUT/DELETE/LIST -> proxy to PutFS API

API endpoints

Method Pattern Action
PUT /:path Upload an object
GET /:path Download an object
HEAD /:path Check if an object exists
DELETE /:path Delete an object
GET /:path/ List objects in path prefix

Install from PyPI

If you prefer running without Docker:

pip install putfs

Then run with granian:

export PUTFS_ROOT=/srv/putfs
granian --interface asgi --host 127.0.0.1 --port 5000 putfs.api:app