Added python attachment upload example

This commit is contained in:
Dan Brown 2022-12-03 02:45:54 +00:00
commit 482b7723a9
Signed by: danb
GPG key ID: 46D9F943C24A2EF9

3
.gitignore vendored
View file

@ -1,2 +1,3 @@
.idea/
node_modules/
node_modules/
venv/

View file

@ -0,0 +1,86 @@
import os
import sys
import requests
# This is where BookStack API details can be hard-coded if you prefer
# to write them in this script instead of using environment variables.
default_bookstack_options = {
"url": "",
"token_id": "",
"token_secret": "",
}
# Gather the BookStack API options either from the hard-coded details above otherwise
# it defaults back to environment variables.
def gather_api_options() -> dict:
return {
"url": default_bookstack_options["url"] or os.getenv("BS_URL"),
"token_id": default_bookstack_options["token_id"] or os.getenv("BS_TOKEN_ID"),
"token_secret": default_bookstack_options["token_secret"] or os.getenv("BS_TOKEN_SECRET"),
}
# Send a multipart post request to BookStack, at the given endpoint with the given data.
def bookstack_post_multipart(endpoint: str, data: dict) -> dict:
# Fetch the API-specific options
bs_api_opts = gather_api_options()
# Format the request URL and the authorization header, so we can access the API
request_url = bs_api_opts["url"].rstrip("/") + "/api/" + endpoint.lstrip("/")
request_headers = {
"Authorization": "Token {}:{}".format(bs_api_opts["token_id"], bs_api_opts["token_secret"])
}
# Make the request to bookstack with the gathered details
response = requests.post(request_url, headers=request_headers, files=data)
# Throw an error if the request was not successful
response.raise_for_status()
# Return the response data decoded from it's JSON format
return response.json()
# Error out and exit the app
def error_out(message: str):
print(message)
exit(1)
# Run this when called on command line
if __name__ == '__main__':
# Check arguments provided
if len(sys.argv) < 3:
error_out("Both <page_id> and <file_path> arguments need to be provided")
# Gather details from the command line arguments and create a file name
# from the file path
page_id = sys.argv[1]
file_path = sys.argv[2]
file_name = os.path.basename(file_path)
# Ensure the file exists
if not os.path.isfile(file_path):
error_out("Could not find provided file: {}".format(file_path))
# Gather the data we'll be sending to BookStack.
# The format matches that what the "requests" library expects
# to be provided for its "files" parameter.
post_data = {
"file": open(file_path, "rb"),
"name": (None, file_name),
"uploaded_to": (None, page_id)
}
# Send the upload request and get back the attachment data
try:
attachment = bookstack_post_multipart("/attachments", post_data)
except requests.HTTPError as e:
error_out("Upload failed with status {} and data: {}".format(e.response.status_code, e.response.text))
# Output the results
print("File successfully uploaded to page {}.".format(page_id))
print(" - Attachment ID: {}".format(attachment['id']))
print(" - Attachment Name: {}".format(attachment['name']))

View file

@ -0,0 +1,45 @@
# Upload a file attachment to a BookStack page
This script will take a path to any local file and attempt
to upload it to a BookStack page as an attachment
using the API using a multipart/form-data request.
This is a simplistic example of a Python script. You will likely want to
alter and extend this script to suit your use-case.
This was written without in-depth knowledge of Python nor experience
of Python common conventions, so the style and approaches may appear unconventional.
## Requirements
You will need Python 3 installed (3.10.7).
This also uses pip to import requests as a dependency.
## Running
First, download all the files in the same directory as this readme to a folder on your system
and run the below from within that directory.
```bash
# Install dependencies via PIP
pip install -r requirements.txt
# Setup
# ALTERNATIVELY: Open the script and add to the empty strings in the variables at the top.
export BS_URL=https://bookstack.example.com # Set to be your BookStack base URL
export BS_TOKEN_ID=abc123 # Set to be your API token_id
export BS_TOKEN_SECRET=123abc # Set to be your API token_secret
# Running the script
python main.py <page_id> <file_path>
```
- `<page_id>` - The ID of the page you want to upload the attachment to.
- `<file_path>` - File you want to upload as an attachment.
## Examples
```bash
# Upload the 'cat-image-collection.zip' file as an attachment to page of ID 205
python main.py 205 ./cat-image-collection.zip
```

View file

@ -0,0 +1,5 @@
certifi==2022.9.24
charset-normalizer==2.1.1
idna==3.4
requests==2.28.1
urllib3==1.26.13