Here is an example function for performing "multipart/form-data" POST (file upload) using the urllib2 library (it uses only built-in libraries, does not require any external packages).
Note that the urllib2 documentation suggests "The Requests package is recommended for a higher-level HTTP client interface" but I was aiming for a solution that did not require import of any external packages, and this works.
This version is hard-coded for a content type of "audio/mpeg" but could be tweaked to use another content type.
Fill disclosure, this code was created with the assistance of ChatGPT after a good amount of coaxing (updated prompts) and manual tweaks.
My specific use case is uploading sound files to an Axis network speaker using it's Media Clip API within Ignition v8.1.28+.
import os
import urllib2
import base64
def upload_file(url, file_path, username, password):
if not os.path.isfile(file_path):
print("Error: File not found at {}".format(file_path))
return
try:
# Open the file for reading
with open(file_path, 'rb') as file_stream:
file_data = file_stream.read()
# Prepare the request
request = urllib2.Request(url)
boundary = "-----" + hex(hash(file_data))[2:]
request.add_header("Content-Type", "multipart/form-data; boundary={}".format(boundary))
# Encode credentials for basic authentication
credentials = base64.b64encode("{}:{}".format(username, password))
request.add_header("Authorization", "Basic {}".format(credentials))
# Build the request body
body = b''
body += b"--" + boundary + b"\r\n"
body += b"Content-Disposition: form-data; name=\"file\"; filename=\"{}\"\r\n".format(os.path.basename(file_path))
body += b"Content-Type: audio/mpeg\r\n\r\n"
body += file_data
body += b"\r\n--" + boundary + b"--\r\n"
# Set the request method and data
request.get_method = lambda: 'POST'
request.add_data(body)
# Send the request
response = urllib2.urlopen(request)
# Print debug information, see https://docs.python.org/2/library/urllib2.html#urllib2.urlopen
print "** DEBUG INFO - START, comment out in final code **"
print "** URL: ", response.geturl()
print "** Code: ", response.getcode()
print "** Info: \n", response.info()
print "** DEBUG INFO - END\n"
# Get the response code
response_code = response.getcode()
if response_code == 200:
print("File uploaded successfully.")
else:
print("Error: Failed to upload file. Response code: {}".format(response_code))
except Exception as e:
print("Error: {}".format(e))