A simple RESTful API that allows you to manipulate files and directories.
Warning
This project is in early development stage.
Important
💀 There are no robust protections against malicious users. This API is intended to be used as an internal API for simple projects. Usage of a service mesh that encrypts traffic between services is recommended.
The easiest way to run the File API is to use the Docker image. The image is available on Docker Hub:
docker run -d \
-p 3210:3000 \
-e API_KEY=YOUR_API_KEY \
-v /your/directory/to/mount:/data:rw \
xkonti/file-api:latest
Available configuration options:
- Internal port:
3000
- Mount point for the directory to be managed via API:
/data
API_KEY
environment variable: the API key to use for authentication
An API key must be configured in order to use the API. The API key can be configured using the API_KEY
environment variable. Please use something that is base64 encoded so that it can be used in HTTP headers and URL query.
Each HTTP request will be first checked for API key. If the API key is not provided, the request will be rejected with a 401 Unauthorized
response. The API key can be provided in two ways:
- HTTP header:
api-key
- example:curl --request GET --url 'http://localhost:3000/list?path=%2F' --header 'apikey: YOUR_API_KEY'
- Query parameter:
apikey
- example:curl --request GET --url 'http://localhost:3000/list?path=%2F&apikey=YOUR_API_KEY'
You can list files and/or directories by using the GET /list
endpoint with the following query parameters:
path
- the path of the directory to list (remember to url-encode it)dirs
- whether to include directories or not (default:false
). If directories are listed their contents will be nested.depth
- how deep to list directories. The default1
will list only files and directories within the specified directory - no contents of subdirectories will be listed.
Examples [click to expand]
-
curl --request GET --url 'http://localhost:3000/list?path=%2F'
- list only files in the root directory (%2F
is the encoded/
):[ { "name": "Expenses 2022.xlsx", "fullPath": "/Expenses 2022.xlsx", "type": "file" } ]
-
curl --request GET --url 'http://localhost:3000/list?path=%2F&dirs=true'
- list files and directories in the root directory (%2F
is the encoded/
):[ { "name": "repos", "fullPath": "/repos", "type": "dir" }, { "name": "Expenses 2022.xlsx", "fullPath": "/Expenses 2022.xlsx", "type": "file" } ]
-
curl --request GET --url 'http://localhost:3000/list?path=%2F&dirs=true&depth=2'
- list files and directories in the root directory. Additionally increase depth to2
so that the contents of therepos
directory are listed:[ { "name": "repos", "fullPath": "/repos", "type": "dir", "contents": [ { "name": "rusty-result-ts", "fullPath": "/repos/rusty-result-ts", "type": "dir" }, { "name": "vue-smart-routes", "fullPath": "/repos/vue-smart-routes", "type": "dir" }, { "name": "todo.md", "fullPath": "/repos/todo.md", "type": "file" }, { "name": "clean-node-package-typescript", "fullPath": "/repos/clean-node-package-typescript", "type": "dir" }, { "name": "notes.md", "fullPath": "/repos/notes.md", "type": "file" } ] }, { "name": "Expenses 2022.xlsx", "fullPath": "/Expenses 2022.xlsx", "type": "file" } ]
-
curl --request GET --url 'http://localhost:3000/list?path=%2F&dirs=true&depth=2'
- list only files in the root directory. Additionally increase depth to2
so that the contents of therepos
directory are listed. This will present all the files as a flat list:[ { "name": "todo.md", "fullPath": "/repos/todo.md", "type": "file" }, { "name": "notes.md", "fullPath": "/repos/notes.md", "type": "file" }, { "name": "Expenses 2022.xlsx", "fullPath": "/Expenses 2022.xlsx", "type": "file" } ]
-
curl --request GET --url 'http://localhost:3000/list?path=repos%2Frusty-result.ts&dirs=true'
- list files and directories in therepos/rusty-result.ts
directory. Additionally increase depth to2
so that the contents of therepos
directory are listed:[ { "name": "repos", "fullPath": "/repos", "type": "dir", "contents": [ { "name": "rusty-result-ts", "fullPath": "/repos/rusty-result-ts", "type": "dir" }, { "name": "vue-smart-routes", "fullPath": "/repos/vue-smart-routes", "type": "dir" }, { "name": "todo.md", "fullPath": "/repos/todo.md", "type": "file" }, { "name": "clean-node-package-typescript", "fullPath": "/repos/clean-node-package-typescript", "type": "dir" }, { "name": "notes.md", "fullPath": "/repos/notes.md", "type": "file" } ] }, { "name": "Expenses 2022.xlsx", "fullPath": "/Expenses 2022.xlsx", "type": "file" } ]
You can download a specific file by using the GET /file
endpoint with the following query parameters:
path
- the path of the file to download (remember to url-encode it)
If the file does not exist or a path is pointing to a directory, a 404 Not Found
response will be returned.
Examples [click to expand]
curl --request GET --url 'http://localhost:3000/file?path=%2FExpenses%202022.xlsx'
- download theExpenses 2022.xlsx
file (%2FExpenses%202022.xlsx
is the encoded/Expenses 2022.xlsx
)
You can upload a specific file by using the POST /file
endpoint with the following query parameters:
path
- the destination path of the file to upload (remember to url-encode it)overwrite
- whether to overwrite the file if it already exists (default:false
)
All the parent directories of the destination path will be created automatically if they do not exist.
The file contents should be sent in the request body in one of the following ways:
multipart/form-data
- the file contents should be sent as afile
fieldapplication/octet-stream
- the file contents should be sent as the request body
Possible responses:
201
- the file was uploaded successfully400
- the request was malformed in some way:- the
path
parameter is missing - the
path
parameter is pointing to a directory - the file contents are missing
- the
415
- unsupported content type422
- unrecognized file contents format
Examples [click to expand]
curl --request POST --url 'http://localhost:3000/file?path=%2FExpenses%202022.xlsx' --header 'Content-Type: application/octet-stream' --data-binary @/path/to/file
- upload theExpenses 2022.xlsx
file (%2FExpenses%202022.xlsx
is the encoded/Expenses 2022.xlsx
)
You can check if a specific file exists by using the GET /file/exists
endpoint with the following query parameters:
path
- the path of the file to check (remember to url-encode it)
Possible responses:
204
- the file exists404
- the file does not exist400
- the request was malformed in some way:- the
path
parameter is missing - the
path
parameter is pointing to a directory
- the
You can get the size of a specific file by using the GET /file/size
endpoint with the following query parameters:
path
- the path of the file to check (remember to url-encode it)
Possible responses:
200
- the file exists and the size is returned in the response body404
- the file does not exist400
- the request was malformed in some way:- the
path
parameter is missing - the
path
parameter is pointing to a directory
- the
Response body with file size in bytes:
{
"size": 123456
}
- List files and directories in a directory as a flat list:
GET /list
- List files and directories in a directory as a tree:
GET /tree
- Check if a directory exists:
GET /dir/exists
- Create a directory:
POST /dir
- Delete a directory:
DELETE /dir
- Rename a directory: :
POST /dir/rename
- Move a directory:
POST /dir/move
- Copy a directory:
POST /dir/copy
- Check if a file exists:
GET /file/exists
- Download a file:
GET /file
- Upload a file:
POST /file
- Delete a file:
DELETE /file
- Create an empty file:
POST /file/touch
- Rename a file:
POST /file/rename
- Move a file:
POST /file/move
- Copy a file:
POST /file/copy
- Get file metadata:
GET /file/meta
- Get file size:
GET /file/size
- API key authentication
- Protect paths with API keys
- Protect operation categories with API keys
- Listing files and directories
- Downloading files
- Uploading/copying files & creating directories
- Deleting/moving/renaming files & directories
- Docker image on Docker Hub
- Docker image on GitHub Container Registry
- CI/CD pipeline using GitHub Actions and Dagger