drafts.create() fails with "only JSON and multipart supported" error since v6.13.1
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 109
- Forks
- 85
- Merge moyen
- 1 j 21 h
- PR mergées (30 j)
- 1
Description
Describe the bug
Draft creation fails with NylasApiError: only JSON and multipart supported when using the Nylas Python SDK v6.13.1+. The Nylas API returns
a 400 error rejecting the draft creation request, even though the request appears to be properly formatted JSON.
Root Cause:
In v6.13.1 (commit d226ff113a62, PR #442), the HTTP client was changed to manually serialize JSON using json.dumps(request_body,
ensure_ascii=False) and pass it via the data= parameter instead of using the json= parameter in requests.request(). While this fixed UTF-8
encoding for multipart requests, it appears to have broken JSON-only requests for draft creation.
The issue is that when using data=json_string instead of json=dict, the requests library doesn't automatically set the correct
Content-Type header, or the manually added application/json; charset=utf-8 header is not being accepted by the Nylas API for draft
creation.
To Reproduce
from nylas import Client
from nylas.models.drafts import CreateDraftRequest
# Initialize client
nylas = Client(api_key="your_api_key", api_uri="https://api.us.nylas.com")
# Attempt to create a draft
draft_request = CreateDraftRequest(
to=[{"email": "recipient@example.com"}],
subject="Test Subject",
body="Test body content"
)
try:
# This will fail with "only JSON and multipart supported"
response = nylas.drafts.create(
grant_id="your_grant_id",
request_body=draft_request
)
except Exception as e:
print(f"Error: {e}")
# Output: NylasApiError: only JSON and multipart supported
Expected behavior
The draft should be created successfully without errors. The Nylas API should accept the JSON request and return the created draft object.
Workaround:
Bypass the SDK's drafts.create() method and use requests directly with the json= parameter:
import requests
from nylas.models.response import Response
from nylas.models.drafts import Draft
# Get API credentials from the SDK client
api_server = nylas.drafts._http_client.api_server
api_key = nylas.drafts._http_client.api_key
url = f"{api_server}/v3/grants/{grant_id}/drafts"
headers = {
"Authorization": f"Bearer {api_key}",
"X-Nylas-API-Wrapper": "python",
}
# Use requests directly with json= parameter
http_response = requests.post(url, headers=headers, json=draft_request_dict, timeout=30)
if http_response.status_code >= 400:
raise Exception(f"Draft creation failed: {http_response.json()}")
draft_data = http_response.json()
response = Response.from_dict(draft_data, Draft, http_response.headers)
This workaround succeeds because requests.post() with json=dict properly handles Content-Type headers.
SDK Version:
- Broken: v6.13.1 and later (including v6.13.1, v6.14.0, v6.14.1, v6.14.2)
- Last working: v6.13.0 and earlier
Additional context
The breaking change was introduced in commit d226ff113a62 (PR #442) which modified nylas/handler/http_client.py:
- Changed from: requests.request(..., json=request_body, data=data)
- Changed to: requests.request(..., data=json_data or data) where json_data = json.dumps(request_body, ensure_ascii=False)
- Changed Content-Type header from application/json to application/json; charset=utf-8
While PR #442 successfully fixed UTF-8 encoding issues for multipart requests with large attachments, it appears to have broken standard
JSON requests for draft creation. The requests library handles the json= parameter differently than data= with a pre-serialized JSON
string, particularly regarding header management.
Suggested Fix:
Consider using json= parameter for JSON-only requests and data= with manual serialization only for multipart/form-data requests where
UTF-8 encoding is needed.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Lisez nylas/handler/http_client.py et le chemin de requête utilisé par drafts.create(), en vous concentrant sur le passage du paramètre json= à des données sérialisées manuellement. Exécutez la reproduction fournie de la création d’un brouillon et vérifiez que les requêtes de brouillons JSON aboutissent, tout en vous assurant que le comportement multipart traité par PR #442 reste intact.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- api
- Type d'issue
- Bug
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 48/100