如何用Python结合OAuth1调用Confluence API上传附件?已可更新页面
Hey there! Let's tackle this Confluence OAuth1 attachment upload issue you're facing—since you already got page updates working, we're halfway there. Here's a step-by-step breakdown of what you might be missing and how to implement it properly:
First, it’s important to note that uploading attachments uses a different request structure than updating pages. Page updates typically send JSON payloads, but attachments require a multipart/form-data request (since you’re sending binary file content alongside metadata). This is the most common pitfall when moving from page edits to attachments.
Let’s walk through a working example using Python (since requests-oauthlib simplifies OAuth1 handling), but the logic applies to any language:
1. Set Up OAuth1 Credentials
Use the same OAuth1 credentials that work for your page updates—no new keys needed, just ensure your user has permission to upload attachments to the target page.
2. Construct the Multipart Request
Here’s a complete code snippet:
import requests from requests_oauthlib import OAuth1 # Replace with your actual OAuth1 credentials oauth = OAuth1( client_key="YOUR_CLIENT_KEY", client_secret="YOUR_CLIENT_SECRET", resource_owner_key="YOUR_RESOURCE_OWNER_KEY", resource_owner_secret="YOUR_RESOURCE_OWNER_SECRET" ) # Configuration page_id = "123456789" # Replace with your target page ID file_path = "/path/to/your/document.pdf" # Local file to upload attachment_name = "My_Uploaded_Document.pdf" # Name to show in Confluence confluence_base_url = "https://your-instance.atlassian.net" # Cloud instance; adjust for Server/Data Center # API endpoint for attachments upload_url = f"{confluence_base_url}/rest/api/content/{page_id}/child/attachment" # Build multipart form data: file + optional metadata files = { "file": (attachment_name, open(file_path, "rb"), "application/pdf") # Adjust MIME type for your file } form_data = { "minorEdit": "true", # Set to false if you want to trigger notifications "comment": "Uploaded via OAuth1 API" # Optional: add a description for the attachment } # Send the request response = requests.post(upload_url, auth=oauth, files=files, data=form_data) # Handle response if response.status_code in (200, 201): print("Attachment uploaded successfully!") print("Attachment details:", response.json()) else: print(f"Upload failed with status code {response.status_code}") print("Error details:", response.text)
- Don’t manually set the
Content-Typeheader: Therequestslibrary automatically generates the correctmultipart/form-dataheader with boundary values. If you set it manually, you’ll break the request. - Verify file permissions: Ensure your script has read access to the local file you’re trying to upload.
- Check Confluence permissions: Confirm your OAuth1 user has "Edit" permissions on the target page and isn’t restricted by space-level attachment rules.
- Cloud vs. Server URLs: For Confluence Server/Data Center, your base URL will look like
https://your-domain/confluenceinstead of the.atlassian.netcloud URL.
- Debug request details: Enable logging to see exactly what’s being sent to Confluence (helps spot signature or payload issues):
import logging import http.client http.client.HTTPConnection.debuglevel = 1 logging.basicConfig(level=logging.DEBUG) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True - Check error responses: Confluence’s API returns detailed error messages in the response body. For example, a
403might mean missing permissions, while a400could indicate a malformed file or metadata. - Test with Postman first: Configure OAuth1 in Postman, manually upload the attachment, and confirm it works. Then compare the request structure to your code to spot differences.
Give these steps a try—since you already have OAuth1 working for page updates, the main fix is likely adjusting the request to use multipart/form-data correctly. If you hit a specific error message, feel free to share it and we can narrow it down further!
内容的提问来源于stack exchange,提问作者Nitin Chauhan

