Quoting from the docs

data – (optional) Dictionary or bytes to send in the body of the Request.

So this should work (not tested):

 filepath = 'yourfilename.txt'
 with open(filepath) as fh:
     mydata = fh.read()
     response = requests.put('https://api.elasticemail.com/attachments/upload',
                data=mydata,                         
                auth=('omer', 'b01ad0ce'),
                headers={'content-type':'text/plain'},
                params={'file': filepath}
                 )
Answer from raben on Stack Overflow
🌐
Codecademy
codecademy.com › docs › python › requests module › .put()
Python | Requests Module | .put() | Codecademy
May 15, 2024 - These parameters allow a user to communicate additional information to the web server, such as data or JSON to send in the request body in order to create or update a resource. ... The response object returned by the .put() method contains various types of data, such as the webpage text, JSON (if returned), status code, and the reason for that response: ... Learn to analyze and visualize data using Python and statistics.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-requests-post-request-with-headers-and-body
Python requests - POST request with headers and body - GeeksforGeeks
July 23, 2025 - Headers can be Python Dictionaries like, { “Name of Header”: “Value of the Header” } The Authentication Header tells the server who you are. Typically, we can send the authentication credentials through the Authorization header to make an authenticated request. ... POST requests pass their data through the message body, The Payload will be set to the data parameter.
Top answer
1 of 2
11

Even after three attempts to clarify the question, it still isn't clear what you're asking here, but I can try to throw out enough info that you can figure out the answer.

First, r = requests.put(url, data = string) returns a Response, which doesn't have a body, but it does have a request, and a history of 0 or more redirect requests, all of which are PreparedRequest objects, which do have body attributes.

On the other hand, if you did r.requests.Request(method='PUT', url=url, data=string), that would return a Request, which has to be prepare()d before it has a body.

Either way, if I do a simple test and look at the results, I find that the body is always correct:

Copy>>> resp = requests.put('http://localhost/nosuchurl', data='abc')
>>> resp.request.body
'abc'
>>> resp = requests.put('http://localhost/redirect_to_https', data='abc')
>>> resp.history[-1].request.body
'abc'
>>> req = requests.Request(method='PUT', url='http://localhost/nosuchurl', data='abc')
>>> preq = req.prepare()
>>> preq.body
'abc'

My best guess is that you need to be looking at resp.history[0].request.body, but you're looking at resp.request.body, or something similar.

If Redirection and History in the quickstart tutorial doesn't help, read the detailed API docs, or just experiment with all of them until you figure it out.

Or do this:

Copyresp = request.put('http://localhost/nosuchurl', data='abc', allow_redirects=False)

And then do the redirect-handling manually.

2 of 2
0

To send json string in body:

Copyresponse = requests.put(url, data=json.dumps(json_string))
🌐
FastAPI
fastapi.tiangolo.com › tutorial › body
Request Body - FastAPI
You can also declare body, path and query parameters, all at the same time. FastAPI will recognize each of them and take the data from the correct place. ... from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str description: str | None = None price: float tax: float | None = None app = FastAPI() @app.put("/items/{item_id}") async def update_item(item_id: int, item: Item, q: str | None = None): result = {"item_id": item_id, **item.model_dump()} if q: result.update({"q": q}) return result
Top answer
1 of 1
5

It seams this page expects data as JSON so you need

page = session.post(url, json=data)

BTW:

Server always assigns new cookies to new client - especially cookie line ASP.NET_SessionId - so better GET main page to get new cookies before you do other requests.

After session.headers.update(headers) you don't have to use headers=headers in get()/post(). You may have to only change some headres if some request need some extra header.

If you use json= then it automatically add header "Content-Type": "application/json;charset=utf-8"

Full code could look like this:

import requests

# -- create session ---

session = requests.session()

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0",
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "en-US,en;q=0.5",
    "Connection": "keep-alive"
}

# set headers for all requests
session.headers.update(headers)

# --- get cookies ---

url = "https://www.pocruises.com.au/"
page = session.get(url)

# --- search ---

data = {
    "searchParameters": {
        "p": [],
        "c": [],
        "d": [],
        "s": [],
        "ms": [],
        "adv": [],
        "sort": "dpa",
        "page": 5
    },
    "renderingParameters": {
        "DefaultSortOption": "dpa",
        "LargeScreenFlag": "true",
        "NewModelIsLoading": "false",
        "PagingAnchor": "",
        "ViewStyleSelectorVisible": "true",
        "FilterBarVisible": "true",
        "NumberOfResultsAndSortByPanelVisible": "true",
        "DefaultResultsView": "Grid",
        "MaxNumberOfResults": 0,
        "PaginationEnabled": "true",
        "KeepPageState": "true",
        "PageSize": 9,
        "DefaultResultsGrouping": "Itinerary",
        "Duration": [],
        "CruiseItinerary": [],
        "Voyage": [],
        "ExcludeVoyage": [],
        "PromoCode": [],
        "AdditionalPromoCodes": []
    }
}

url = "https://www.pocruises.com.au/sc_ignore/b2c/cruiseresults/searchresults"

# `json=` add `"Content-Type": "application/json;charset=utf-8"`

page = session.post(url, json=data)

print(page.text)
cruise_data = page.json()
print(cruise_data)
🌐
GeeksforGeeks
geeksforgeeks.org › put-method-python-requests
PUT method - Python requests - GeeksforGeeks
April 12, 2025 - If the resource exists at the given URI, it is updated with the new data. If the resource does not exist, the server can create it at that URI. The request includes the data to be stored in the request body.
🌐
Tutorialspoint
tutorialspoint.com › python › python_requests_put_method.htm
Python Requests put() Method
Following is the basic example of a basic PUT request using python requests put() method − · import requests # Define the URL url = 'https://httpbin.org/put' # Define the data to be sent in the request body data = {'key1': 'value1', 'key2': 'value2'} # Send the PUT request with the data response = requests.put(url, json=data) # Print the response status code print('Status Code:', response.status_code) # Print the response content print('Response Content:', response.text)
🌐
Requests
requests.readthedocs.io › en › latest › user › quickstart
Quickstart — Requests 2.33.0.dev1 documentation
Requests will also use custom encodings in the event that you need them. If you have created your own encoding and registered it with the codecs module, you can simply use the codec name as the value of r.encoding and Requests will handle the decoding for you. You can also access the response body as bytes, for non-text requests:
Find elsewhere
🌐
Real Python
realpython.com › python-requests
Python's Requests Library (Guide) – Real Python
July 23, 2025 - According to the HTTP specification, POST, PUT, and the less common PATCH requests pass their data through the message body rather than through parameters in the query string.
🌐
ReqBin
reqbin.com › req › python › p2fujlvb › put-request-example
Python | How to send a PUT request?
January 15, 2023 - To send a PUT request with Python, use the HTTP PUT method and provide the data in the body of the PUT message. The HTTP PUT request method creates a new resource or replaces an existing resource on the server.
🌐
Apidog
apidog.com › blog › python-put-request
How to make a PUT Request in Python (2026 Guide)
February 2, 2026 - In simple terms, a PUT request is used to update a resource on the server. It sends data to the server to be stored at a specified resource or URL. Think of it as the command that tells the server, "Hey, I've got some new information for you; ...
🌐
Apidog
apidog.com › blog › python-put-request-headers
How to make a PUT Request in Python with headers
October 28, 2024 - A PUT request is an HTTP request ... representation of the target resource with the request payload. The request has a body and the successful response has a body....
🌐
ProxiesAPI
proxiesapi.com › articles › sending-string-data-in-request-body-with-python-requests
Sending String Data in Request Body with Python Requests | ProxiesAPI
February 3, 2024 - This sends a PUT request to update or create the resource at the given URL, with the string data in the body. The server will receive the textual data and process it appropriately based on the resource.
🌐
TutorialsPoint
tutorialspoint.com › python-requests-post-request-with-headers-and-body
Python requests - POST request with headers and body
The 'requests' module in Python simplifies HTTP requests by offering a user-friendly interface for sending and handling responses. It supports various HTTP methods such as GET, POST, PUT, DELETE, HEAD and OPTIONS, where each accessible through corresponding functions.
🌐
Python-requests
docs.python-requests.org › en › latest › api
Developer Interface — Requests 2.33.0.dev1 documentation
October 16, 2014 - json – (optional) A JSON serializable Python object to send in the body of the Request. **kwargs – Optional arguments that request takes. ... Sends a PUT request.
🌐
Requests
requests.readthedocs.io › en › latest › api
Developer Interface — Requests 2.33.0.dev1 documentation
json – (optional) A JSON serializable Python object to send in the body of the Request. **kwargs – Optional arguments that request takes. ... Sends a PUT request.
🌐
ScrapeOps
scrapeops.io › home › python web scraping playbook › python requests post requests
Python Requests - How to Send POST Requests | ScrapeOps
April 12, 2023 - To send POST requests with Python Requests use the requests.post() method and add the POST body and Content-Type using the body and headers parameters.