You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. When using both data and files parameters with requests.post(), the library automatically switches the request to multipart/form-data format. But you manually set Content-Type: application/json, which clashes with this auto-generated header.
  2. You passed a byte-string (from json.dumps().encode()) to the data parameter. For multipart requests, requests expects data to 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-Type header: requests automatically generates the correct multipart/form-data header with a unique boundary when you use the files parameter. Manually setting application/json breaks this.
  • JSON as a form field: We included your JSON payload directly in the files dictionary as a field with no filename (marked as None) and the correct application/json content type.
  • Proper attachment formatting: The attachment entry follows the (filename, file_object, content_type) structure required by requests, using the accurate MIME type for Excel .xlsx files.
  • Safe file handling: The with statement 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 data parameter with files, which violates requests expectations for multipart requests.

内容的提问来源于stack exchange,提问作者Jihyun Moon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:42:40