title: Salesforce Bulk Upsert with Python Requests library returns ClientInputError : LineEnding is invalid on user data
body: <p>I am unsuccessfully attempting to upsert csv data to Salesforce via the Python Requests library.  I am getting an error reported in the Salesforce interface, stating that &quot;ClientInputError : LineEnding is invalid on user data. Current LineEnding setting is LF&quot;.</p>
  <p>When I request the result, I am getting a &lt;Response [200]&gt; (Request successfully processed).</p>
  <p>I have tried the following:</p>
  <ul>
  <li>Check format of the data in file using this tool: <a href="https://www.soscisurvey.de/tools/view-chars.php" rel="nofollow noreferrer">https://www.soscisurvey.de/tools/view-chars.php</a></li>
  <li>Changed code to reflect &quot;LF&quot; with current file</li>
  <li>Converted file to LF in Notepad ++ &amp; updated code to reflect LF</li>
  <li>Trying with a smaller 2 record csv</li>
  </ul>
  <p>Any ideas?</p>
  <p>Here's my code:</p>
  <pre><code>    # Generate token
      params = {
          'grant_type':'password',
          'username': USERNAME,
          'password': SALESFORCE_PASSWORD,
          'client_id': SALESFORCE_CLIENT_ID,
          'client_secret': SALESFORCE_CLIENT_SECRET
      }
  
      r = requests.post('https://SALESFORCEWEBADDRESS/services/oauth2/token', params=params)
  
      access_token = r.json().get(&quot;access_token&quot;)
      instance_url = r.json().get(&quot;instance_url&quot;)
      print(&quot;Access Token:&quot;, access_token)
      print(&quot;Instance URL&quot;, instance_url)
  
      # STEP 3 OF UPLOADING TO SALESFORCE: Create a job
  
      headers = {
          'Authorization': 'Bearer '+ access_token,
          'Content-Type': 'application/json; charset=UTF-8',
          'lineEnding' : 'CRLF',
          'Accept': 'application/json'
      }
  
      url = 'https://SALESFORCEWEBADDRES/services/data/v53.0/jobs/ingest/' 
  
      request_body = {
          &quot;object&quot; : &quot;Account&quot;,
          &quot;externalIdFieldName&quot;: &quot;Client&quot;,
          &quot;contentType&quot; : &quot;CSV&quot;,
          &quot;operation&quot; : &quot;upsert&quot;
      }
  
  
      create = requests.post(headers=headers, data=json.dumps(request_body),url=url)
      print(create.text)
  
      # STEP 4 OF UPLOADING TO SALESFORCE: Upload csv
      headers = {
          'Authorization': 'Bearer '+ access_token,
          'Content-Type': 'text/csv',
          'Accept': 'application/json',  # I blanked this out to test and got a 409
          'lineEnding' : 'CRLF'
      }
  
      url = f'https://SALESFORCEWEBADDRESS/{step_2_url}'
  
      #data = {'file' :open('salesforce_single_records.csv', 'rb')}
      csv = 'salesforce_single_records_test.csv'
      # data = open('salesforce_single_records.csv', 'rb').read()
  
      with open(csv, 'rb') as f:
          upload = requests.put(headers=headers, url=url, files={csv: f})
          print(upload)
          
      # STEP 5 OF UPLOADING TO SALESFORCE: Close the job
      headers = {
          'Authorization': 'Bearer '+ access_token,
          'Content-Type': 'application/json; charset=UTF-8',
          'Accept': 'application/json'
      }
  
      url = f'https://SALESFORCEWEBADDRESS/services/data/{version}/jobs/ingest/{id}/' 
  
  
      request_body = {
          &quot;state&quot; : &quot;UploadComplete&quot;
      }
  
  
      close = requests.patch(headers=headers, data=json.dumps(request_body),url=url)
  
      print(close.text)
  </code></pre>