Python发送带附件邮件报错:Data must not be a string 求助
Fixing "Data must not be a string" Error When Sending Emails with Attachments via REST API
Hey there! Let's break down why you're hitting that "Data must not be a string" error and fix it step by step.
What's Causing the Issue?
Your problem stems from two key conflicts in your original code:
- When using both
dataandfilesparameters withrequests.post(), the library automatically switches the request tomultipart/form-dataformat. But you manually setContent-Type: application/json, which clashes with this auto-generated header. - You passed a byte-string (from
json.dumps().encode()) to thedataparameter. For multipart requests,requestsexpectsdatato be a dictionary of form fields—not a raw string/byte sequence.
Corrected Code Implementation
Here's a refined version of your code that addresses these issues, plus best practices like safe file handling:
import json import requests # Build your email payload sendHTML = str(fullReportFrameSoup) sMailBody = { "resourceVO": { "email": "xxx@samsung.com", "localeStr": "ko_KR", "encoding": "utf-8", "timeZone": "GMT+9", }, "sendMailVO": { "contentText": sendHTML, "subject": "[Tizen Store] 鞚检澕韱店硠", "docSecuType": "PERSONAL", "contentType": "HTML", "from": { "email": "xxx@samsung.com" }, "attachs": [], "recipients": [ { "email": "xxx@samsung.com", "recipientType": "TO" } ] } } attachment_filename = '''20180430_'18 Tizen Store Buyer Report v2.4.xlsx''' # Use a context manager to safely handle the file handle with open(attachment_filename, 'rb') as attachment_file: # Structure files to include both your JSON payload and the attachment files = { # Send your JSON data as a form field (use the field name your API expects) 'json': (None, json.dumps(sMailBody), 'application/json'), # Attach your file with correct filename and MIME type 'file': ( attachment_filename, attachment_file, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' # Accurate MIME type for .xlsx ) } # Only include the authorization header—let requests handle Content-Type automatically headers = {'authorization': 'Bearer xx'} # Send the request res = requests.post(url, headers=headers, files=files) # Verify the response print(f"Response Status: {res.status_code}") print(f"Response Content: {res.text}")
Key Fixes Explained
- Removed manual
Content-Typeheader:requestsautomatically generates the correctmultipart/form-dataheader with a unique boundary when you use thefilesparameter. Manually settingapplication/jsonbreaks this. - JSON as a form field: We included your JSON payload directly in the
filesdictionary as a field with no filename (marked asNone) and the correctapplication/jsoncontent type. - Proper attachment formatting: The attachment entry follows the
(filename, file_object, content_type)structure required byrequests, using the accurate MIME type for Excel .xlsx files. - Safe file handling: The
withstatement ensures the file is closed automatically after the request, preventing resource leaks.
Notes on Your Previous Attempts
- Your modified code was close, but the attachment entry was missing the filename parameter (you had
(open(...), 'application/octet-stream')instead of(filename, open(...), content_type)). - Your original code mixed a raw byte-string
dataparameter withfiles, which violatesrequestsexpectations for multipart requests.
内容的提问来源于stack exchange,提问作者Jihyun Moon
相关产品推荐
相关产品推荐

