For anybody that stumbles upon this thread looking for help, the trick was to decode the string. Here is what I did that finally worked (also to move/copy attachments from one feature to another):
import requests, base64, json
# get image string
urlAttachment = "https://services1.arcgis.com/d2krQaXxxwrynqoe/arcgis/rest/services/{}/FeatureServer/{}/{}/attachments/{}?f=json&token={}".format(feature_service_to_copy_from, feature_layer_id, feature_id, attachment_id, token)
response = requests.get(urlAttachment)
attachString = json.loads(response.text)["Attachment"]
# this is what took me a long time to figure out, decode the string
attachBinary = base64.b64decode(attachString)
# upload image to other feature service
params = {"f": "json", "token", token}
files = {"attachments": ('name_of_image.jpg', attachBinary, 'image/jpeg')}
urlAddAttachment = "https://services1.arcgis.com/d2krQaXxxwrynqoe/arcgis/rest/services/{}/FeatureServer/{}/{}/addAttachment".format(feature_service_to_copy_to, feature_layer_id, feature_id, token)
response = requests.post(urlAddAttachment, params=params, files=files)
result = json.loads(response.text)
if "addAttachmentResult" in result:
if "success" in result["addAttachmentResult"]:
if result["addAttachmentResult"]["success"] == True:
print("SUCCESS!")
Also, did not have to change the headers or anything. It was always resulting in an error.