Added python attachment upload example
This commit is contained in:
parent ed1748f060
commit 482b7723a9
4 changed files with 138 additions and 1 deletions
3 .gitignore vendored
3
.gitignore vendored | @ -1,2 +1,3 @@ | |||
.idea/ | ||||
node_modules/ | ||||
node_modules/ | ||||
venv/ | ||||
| |
86 python-upload-attachment/main.py Normal file
86
python-upload-attachment/main.py Normal 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'])) |
45 python-upload-attachment/readme.md Normal file
45
python-upload-attachment/readme.md Normal 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 | ||||
``` |
5 python-upload-attachment/requirements.txt Normal file
5
python-upload-attachment/requirements.txt Normal 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 |
Loading…
Add table
Add a link
Reference in a new issue