You can use the Session object

import requests
headers = {'User-Agent': 'Mozilla/5.0'}
payload = {'username':'niceusername','password':'123456'}

session = requests.Session()
session.post('https://admin.example.com/login.php',headers=headers,data=payload)
# the session instance holds the cookie. So use it to get/post later.
# e.g. session.get('https://example.com/profile')
Answer from atupal on Stack Overflow
๐ŸŒ
Medium
techkamar.medium.com โ€บ sending-form-data-post-using-python-requests-library-55850c7a93d5
Sending FORM data POST using Python Requests library - tech kamar - Medium
June 26, 2024 - import requests url = "http://localhost:8080/login" form_data = {"username":"johndoe", "password": "user@1234"} resp = requests.post(url, data=form_data)
Discussions

Python Requests - multipart form data
Looks like the API expects a request structured like this. More on reddit.com
๐ŸŒ r/learnpython
6
1
February 14, 2022
How to send a "multipart/form-data" with requests in python? - Stack Overflow
How to send a multipart/form-data with requests in python? How to send a file, I understand, but how to send the form data by this method can not understand. ... your question is not really clear. What do you want to achieve? Do you wish to send "multipart/form-data" without a file upload in the form? ... Basically, if you specify a files parameter (a dictionary), then requests will send a multipart/form-data POST ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Python Requests library - post method with form data help
All I had to do was add "accept": "*/*" to the header and I did have to copy the entire form-data into a dictionary and pass it in with the request. ... No probs, well done! ... I built a Google Reviews scraper with advanced features in Python. More on reddit.com
๐ŸŒ r/webscraping
5
1
December 17, 2021
request.FILES is empty. File didn't upload
I run into this problem about once a month and it's always a missing enctype . And yes, that link is my answer on my question. I'm glad I posted them because they're the posts I keep finding when I run into this problem :) Can't deny it makes me feel like an idiot when I'm answering my own questions a decade after I initially had the problem. More on reddit.com
๐ŸŒ r/django
21
0
March 19, 2019
People also ask

How do I send form data with Python Requests?
Pass a dict via data. Requests encodes it as application/x-www-form-urlencoded. For files, combine data for fields with files for uploads.
๐ŸŒ
scrapingbee.com
scrapingbee.com โ€บ blog โ€บ how-to-send-post-python-requests
How to send a POST with Python Requests? | ScrapingBee
How can I upload a file with Python Requests POST?
Use files with an open file handle (filename, fileobj, mime). Requests builds a multipart/form-data body for you.
๐ŸŒ
scrapingbee.com
scrapingbee.com โ€บ blog โ€บ how-to-send-post-python-requests
How to send a POST with Python Requests? | ScrapingBee
What is the difference between data and json in Python Requests POST?
data sends form-encoded fields; json serializes your dict and sets Content-Type: application/json. Use data for web forms and json for APIs.
๐ŸŒ
scrapingbee.com
scrapingbee.com โ€บ blog โ€บ how-to-send-post-python-requests
How to send a POST with Python Requests? | ScrapingBee
๐ŸŒ
Reddit
reddit.com โ€บ r/webscraping โ€บ python requests library - post method with form data help
r/webscraping on Reddit: Python Requests library - post method with form data help
December 17, 2021 - All I had to do was add "accept": "*/*" to the header and I did have to copy the entire form-data into a dictionary and pass it in with the request. ... No probs, well done! ... I built a Google Reviews scraper with advanced features in Python.
๐ŸŒ
Requests
requests.readthedocs.io โ€บ en โ€บ latest โ€บ user โ€บ quickstart
Quickstart โ€” Requests 2.33.0.dev1 documentation
To do this, simply pass a dictionary to the data argument. Your dictionary of data will automatically be form-encoded when the request is made: >>> payload = {'key1': 'value1', 'key2': 'value2'} >>> r = requests.post('https://httpbin.org/post', data=payload) >>> print(r.text) { ...
๐ŸŒ
ScrapingBee
scrapingbee.com โ€บ blog โ€บ how-to-send-post-python-requests
How to send a POST with Python Requests? | ScrapingBee
January 11, 2026 - To send a POST request in Python, you typically use requests.post. The main difference is what kind of data you're sending: Form data โ†’ use data=.... This sends application/x-www-form-urlencoded (similar to a regular web form).
๐ŸŒ
ScrapeOps
scrapeops.io โ€บ home โ€บ python web scraping playbook โ€บ python requests post requests
Python Requests - How to Send POST Requests | ScrapeOps
April 12, 2023 - In this guide, we walk through how to send POST requests with Python Requests. Including how to POST form data and JSON data.
Find elsewhere
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ ref_requests_post.asp
Python Requests post Method
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING INTRO TO HTML & CSS BASH RUST ยท Python HOME Python Intro Python Get Started Python Syntax ... Python Variables Variable Names Assign Multiple Values Output Variables Global Variables Variable Exercises Code Challenge Python Data Types ... Python Strings Slicing Strings Modify Strings Concatenate Strings Format Strings Escape Characters String Methods String Exercises Code Challenge Python Booleans
๐ŸŒ
GitHub
gist.github.com โ€บ srafay โ€บ 19e0a13fe7e402f0a79715b1ed3f6560
Python Request for form-data ยท GitHub
Python Request for form-data. GitHub Gist: instantly share code, notes, and snippets.
๐ŸŒ
Scrapfly
scrapfly.io โ€บ blog โ€บ posts โ€บ how-to-python-requests-post
Guide to Python requests POST method - Scrapfly Blog
November 5, 2024 - It allows for customizable and straightforward data sending by specifying the URL, headers, and the data itself. The most common data types include JSON, form data, or raw body data, all handled easily with python requests POST method.
๐ŸŒ
ScrapeOps
scrapeops.io โ€บ home โ€บ python web scraping playbook โ€บ python requests how to submit forms
How To Submit Forms With Python Requests | ScrapeOps
July 8, 2024 - ... Whether you're automating form ... this is your go-to function for submitting forms. It allows you to send form data to a server using an HTTP POST request....
๐ŸŒ
Stack Abuse
stackabuse.com โ€บ bytes โ€บ how-to-send-multipart-form-data-with-requests-in-python
How to Send "multipart/form-data" with Requests in Python
January 29, 2025 - This code creates an HTTPS connection to "example.com", sends a POST request with our file as multipart/form-data, and then prints the response from the server. In this Byte, you've seen how to send multipart/form-data with the Python requests library, handle potential errors, and also looked at some common errors and their solutions.
๐ŸŒ
ProxiesAPI
proxiesapi.com โ€บ articles โ€บ sending-form-data-with-python-requests
Sending Form Data with Python Requests | ProxiesAPI
JSON is a popular format for passing structured data. To send JSON, pass your Python dict to the ... data = { 'name': 'John Doe', 'hobbies': ['hiking', 'diving'] } response = requests.post(url, json=data)
๐ŸŒ
Quora
quora.com โ€บ How-do-you-pass-form-data-in-Python-requests
How to pass form data in Python requests - Quora
In simple terms, we are using the name="" attribute from the <input> tags to define the php variables, to change this to a get method, change POST to GET (case sensitive) and to add new ones use the syntax, $var = $_POST['inputname']; ... It really ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ how-to-upload-files-using-python-requests-library
How to Upload Files Using Python Requests Library - GeeksforGeeks
July 23, 2025 - In this example, below Python code sends a POST request to "https://httpbin.org/post", including both form data ('key': 'value') and a file ('file.txt') uploaded via the `requests` library.
๐ŸŒ
Oxylabs
oxylabs.io โ€บ blog โ€บ how-to-send-post-python-request
How to Send a POST with Python Requests?
To send a POST request using the Python requests library, you need to use the requests.post() method. This method allows you to send data to a server or API and is useful for tasks such as submitting form data or uploading files.
๐ŸŒ
ReqBin
reqbin.com โ€บ req โ€บ python โ€บ yjok4snr โ€บ post-html-form-example
Python | How to post HTML form to the Server?
To post HTML form data to the server in URL-encoded format using Python, you need to make an HTTP POST request to the server and provide the HTML form data in the body of the Python POST message in key=value format.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ python requests - multipart form data
r/learnpython on Reddit: Python Requests - multipart form data
February 14, 2022 -

I am new to python requests and python in general - I have a somewhat intermediate java background.

I am trying to figure out why this post request throws a 400 error when trying to upload a file.

Any hints?

def upload_a_document(self, library_id, folder_id, filepath):
        url = "https://xxx" \
              "/{library_id}!{folder_id}/documents".format(
            server=self.server,
            customer_id=self.customer_id,
            library_id=library_id,
            folder_id=folder_id)
        params = \
            {
                "profile":
                    {
                        "doc_profile": {
                            "access": "full_access",
                            "comment": f"{filepath}",
                            "database": f"{library_id}",
                            "default_security": "public",
                            "name": f"{os.path.basename(filepath)}",
                            "size": os.path.getsize(filepath),
                            "type": "WORDX",
                            "type_description": "WORD 2010",
                            "wstype": "document"
                        },
                        "warnings_for_required_and_disabled_fields": True
                    },
                "file": {open(f"{filepath}", "rb").read()}
            }
        payload = ""

        # encoded formdata for multipart
        encoded_formdata = encode_multipart_formdata(params)

        headers = {'X-Auth-Token': self.x_auth_token, 'Content-Type': encoded_formdata[1]}
        response = requests.request("POST", url, data=payload, headers=headers, params=params)
        myJSON = response.json()
        print(json.dumps(myJSON, indent=4))

Getting this error -

requests.exceptions.JSONDecodeError: [Errno Expecting value] <html><body><h1>400 Bad request</h1>

Your browser sent an invalid request.

๐ŸŒ
ScrapingDog
scrapingdog.com โ€บ blog โ€บ send-post-python-requests
How To Send A Post Requests in Python?
October 2, 2024 - The Python requests library is commonly used to send POST requests to web servers. Data can be sent in JSON format using the json= parameter or as form data using data=.
Top answer
1 of 16
397

Basically, if you specify a files parameter (a dictionary), then requests will send a multipart/form-data POST instead of a application/x-www-form-urlencoded POST. You are not limited to using actual files in that dictionary, however:

>>> import requests
>>> response = requests.post('http://httpbin.org/post', files=dict(foo='bar'))
>>> response.status_code
200

and httpbin.org lets you know what headers you posted with; in response.json() we have:

>>> from pprint import pprint
>>> pprint(response.json()['headers'])
{'Accept': '*/*',
 'Accept-Encoding': 'gzip, deflate',
 'Connection': 'close',
 'Content-Length': '141',
 'Content-Type': 'multipart/form-data; '
                 'boundary=c7cbfdd911b4e720f1dd8f479c50bc7f',
 'Host': 'httpbin.org',
 'User-Agent': 'python-requests/2.21.0'}

And just to be explicit: you should not set the Content-Type header when you use the files parameter, leave this to requests because it needs to specify a (unique) boundary value in the header that matches the value used in the request body.

Better still, you can further control the filename, content type and additional headers for each part by using a tuple instead of a single string or bytes object. The tuple is expected to contain between 2 and 4 elements; the filename, the content, optionally a content type, and an optional dictionary of further headers.

I'd use the tuple form with None as the filename, so that the filename="..." parameter is dropped from the request for those parts:

>>> files = {'foo': 'bar'}
>>> print(requests.Request('POST', 'http://httpbin.org/post', files=files).prepare().body.decode('utf8'))
--bb3f05a247b43eede27a124ef8b968c5
Content-Disposition: form-data; name="foo"; filename="foo"

bar
--bb3f05a247b43eede27a124ef8b968c5--
>>> files = {'foo': (None, 'bar')}
>>> print(requests.Request('POST', 'http://httpbin.org/post', files=files).prepare().body.decode('utf8'))
--d5ca8c90a869c5ae31f70fa3ddb23c76
Content-Disposition: form-data; name="foo"

bar
--d5ca8c90a869c5ae31f70fa3ddb23c76--

files can also be a list of two-value tuples, if you need ordering and/or multiple fields with the same name:

requests.post(
    'http://requestb.in/xucj9exu',
    files=(
        ('foo', (None, 'bar')),
        ('foo', (None, 'baz')),
        ('spam', (None, 'eggs')),
    )
)

If you specify both files and data, then it depends on the value of data what will be used to create the POST body. If data is a string, only it willl be used; otherwise both data and files are used, with the elements in data listed first.

There is also the excellent requests-toolbelt project, which includes advanced Multipart support. It takes field definitions in the same format as the files parameter, but unlike requests, it defaults to not setting a filename parameter. In addition, it can stream the request from open file objects, where requests will first construct the request body in memory:

from requests_toolbelt.multipart.encoder import MultipartEncoder

mp_encoder = MultipartEncoder(
    fields={
        'foo': 'bar',
        # plain file object, no filename or mime type produces a
        # Content-Disposition header with just the part name
        'spam': ('spam.txt', open('spam.txt', 'rb'), 'text/plain'),
    }
)
r = requests.post(
    'http://httpbin.org/post',
    data=mp_encoder,  # The MultipartEncoder is posted as data, don't use files=...!
    # The MultipartEncoder provides the content-type header with the boundary:
    headers={'Content-Type': mp_encoder.content_type}
)

Fields follow the same conventions; use a tuple with between 2 and 4 elements to add a filename, part mime-type or extra headers. Unlike the files parameter, no attempt is made to find a default filename value if you don't use a tuple.

2 of 16
147

Requests has changed since some of the previous answers were written. Have a look at this Issue on Github for more details and this comment for an example.

In short, the files parameter takes a dictionary with the key being the name of the form field and the value being either a string or a 2, 3 or 4-length tuple, as described in the section POST a Multipart-Encoded File in the Requests quickstart:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

In the above, the tuple is composed as follows:

(filename, data, content_type, headers)

If the value is just a string, the filename will be the same as the key, as in the following:

>>> files = {'obvius_session_id': '72c2b6f406cdabd578c5fd7598557c52'}

Content-Disposition: form-data; name="obvius_session_id"; filename="obvius_session_id"
Content-Type: application/octet-stream

72c2b6f406cdabd578c5fd7598557c52

If the value is a tuple and the first entry is None the filename property will not be included:

>>> files = {'obvius_session_id': (None, '72c2b6f406cdabd578c5fd7598557c52')}

Content-Disposition: form-data; name="obvius_session_id"
Content-Type: application/octet-stream

72c2b6f406cdabd578c5fd7598557c52
๐ŸŒ
LabEx
labex.io โ€บ tutorials โ€บ python-how-to-send-data-in-a-post-request-using-python-requests-398065
How to send data in a POST request using Python requests | LabEx
When you send a POST request using the requests library in Python, the server will respond with a response object that contains information about the server's response. Understanding how to work with this response object is crucial for handling ...