Passing files in POST using Requests in Python - python-requests

I'm getting below error when making a requests call post method
{'detail': [{'loc': ['body', 'files'], 'msg': 'field required', 'type': 'value_error.missing'}]}
I tried
response = requests.post("url",headers={mytoken},params=p,files=files)
files = { "file 1": open("sample.pdf",'rb'), "file 2":open("sample11.pdf",'rb')}
I want to get 200 status but I'm getting 422 validation error. Any Idea Why? Its for API Testing purpose, Im new to this I've been debugging this for whole day but still couldn't figure out.

It is not clear from the question what kind of a request the server is expecting. Also, its not clear the exact code snippet you are using too.
From the question, the snippet looks like as follows,
response = requests.post("url",headers={mytoken},params=p,files=files)
files = { "file 1": open("sample.pdf",'rb'), "file 2":open("sample11.pdf",'rb')}
if so, that means you are reading files after you send the request, may be thats why the server complained about missing files field.
See the below example on how you can send two files to an endpoint expecting files.
import requests
import logging
logger = logging.getLogger(__name__)
post_url = "https://exampledomain.local/upload"
file1 = open("sample1.pdf", "rb")
file2 = open("sample2.pdf", "rb")
files = {"file1": file1, "file2": file2}
headers = {"Authorization": "Bearer <your_token_here>"}
params = {"file_type": "pdf"}
response = requests.post(post_url, files=files, headers=headers, params=params)
file1.close()
file2.close()
logger.debug(response.text)

Related

Locust does response with 2xx but fails to gather request statistics

I am trying to do a local load testing with Locust. I got the test environment up and running and a local build is also working. I am trying to test the responses of a local path and the response I get in the terminal is correct. But the Locust UI and also the statistics after terminating the test give me 100% fail results.
For creating the locust code (I am pretty new to it) I use the postman content and adjusted it. This is the Code for Locust:
from locust import HttpLocust, TaskSet, task, between
import requests
url = "http://localhost:8080/registry/downloadCounter"
payload = "[\n {\n \"appName\": \"test-app\",\n \"appVersion\": \"1.6.0\"\n }\n]"
class MyTaskSet(TaskSet):
#task(2)
def index(self):
self.client.get("")
headers = {
'Content-Type': 'application/json',
'Accept':'application/json'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
class MyLocust(HttpLocust):
task_set = MyTaskSet
wait_time = between(2.0, 4.0)
For the Locust swarm I used just basic numbers:
Number of total users to simulate: 1
Hatch Rate: 3
Host: http://localhost:8080/registry/downloadCounter
I do not get any results there, the table stays blank. I guess it has something to do with the json format but I am not able to find the solution myself.
I also put a Screenshot of the Terminal response after termination in this post.
Thank you in advance for your help!
Best regards
This helped:
from locust import HttpLocust, TaskSet, task, between
import requests
url = "http://localhost:8080/registry/downloadCounter"
payload = "[\n {\n \"appName\": \"test-app\",\n \"appVersion\": \"1.6.0\"\n }\n]"
headers = {'Content-type':'application/json', 'Accept':'application/json'}
class MyTaskSet(TaskSet):
#task(2)
def index(self):
response = self.client.post(url = url, data = payload, headers=headers)
print(response.text.encode('utf8'))
print(response.status_code)
class MyLocust(HttpLocust):
task_set = MyTaskSet
wait_time = between(2.0, 4.0)
```

Can't Move DriveItem in Mocrosoft Graph

I am using Python to download PDF files from OneDrive to a local folder, and also moving the files to a different folder in OneDrive after they have been downloaded.
I am able to download the files from OneDrive to a local folder, however, I get a 400 response when trying to move (PATCH) the files to another OneDrive Folder.
Here is my successful code to download the files:
download_url = 'https://graph.microsoft.com/v1.0/me/drive/items/{item-id}/content'
headers = {'Authorization': 'Bearer ' + json_response['access_token']}
download_url_data = requests.get(download_url, headers=headers)
with open('/Users/Name/Folder/file_name, 'wb') as f:
f.write(download_url_data.content)
Here is my unsuccessful PATCH request to move the files:
move_url = 'https://graph.microsoft.com/v1.0/me/drive/items/{item-id}
move_headers = {'Authorization': 'Bearer ' + json_response['access_token'],
'Content-Type' : 'application/json'}
move_body = {'parentReference' : {'id' : '01EV3NG2F6Y2GOVW7775BZO354PUSELRRZ'}}
move_file = requests.patch(move_url, headers=move_headers, data=move_body)
return move_file.status_code
I have followed the documentation here https://learn.microsoft.com/en-us/graph/api/driveitem-move?view=graph-rest-1.0&tabs=http and I have tried different parentReference id's, but no luck.
Please help! Cheers.
What is the response you're getting (the actual content beside the 400 status code)?
I believe that requests.patch should receive it's data as a string, not a dictionary (json).
Try:
move_file = requests.patch(move_url, headers=move_headers, data=json.dumps(move_body))
And of course don't forget to import json

Python Request Session JIRA REST post http 405

Using python requests session I can connect to JIRA and retrieve issue information ...
session = requests.Session()
headers = {"Authorization": "Basic %s" % bas64_val}
session.post(jira_rest_url, headers=headers)
jira = session.get(jira_srch_issue_url + select_fields)
# select_fields = the fields I want from the issue
Now I'm trying to post a payload via the JIRA API, using a fixed issue url e.g. "https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876"
Which should be a case of the following, given: https://developer.atlassian.com/jiradev/jira-apis/about-the-jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-edit-issues
payload = { "update": {
"fixVersions": [ {"set": "release-2.139.0"} ]
}}
posted = session.post(jira_task_url, data=payload)
# returns <Response [405]>
# jira_task_url = https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876
But this doesn't appear to work! Looking into the http 405 response, suggests that my payload is not properly formatted! Which notably, is the not easiest thing to diagnose.
What am I doing wrong here? Any help on this would be much appreciated.
Please note, I am not looking to use the python jira module, I am using requests.session to manage several sessions for different systems i.e. JIRA, TeamCity, etc..
Found the solution! I had two problems:
1) The actual syntax structure should have been:
fix_version = { "update": { "fixVersions": [ {"set" : [{ "name" : "release-2.139.0" }]}]
2) To ensure the payload is actually presented as JSON, use json.dumps() which takes an object and produces a string (see here) AND set 'content-type' to 'application/json':
payload = json.dumps(fix_version)
app_json = { 'content-type': 'application/json' }
session.put(https://.../rest/api/latest/issue/KEY-9876, headers=app_json, data=payload)
Rather than trying to define the JSON manually!

post a csv file to url

I am trying to post a .csv file to a url and it works when I am using Python with this code :
import requests
url = 'http:...'
files = {'file': open('test.csv')}
response = requests.post(url, files=files)
Since all the other code is in R and I would like to have all the code at one place I tried to translate it. I tried several different things:
library(httr)
POST("http:...",
body = list(name = "test.csv",
filedata = upload_file("~/test.csv", "text/csv")))
POST("http:...",
body = list(testFile = "~/test.csv"))
POST("http:...",
body = upload_file("~/test.csv"))
But I keep on running into the same error.
Error in curl::curl_fetch_memory(url, handle = handle) : Timeout
was reached
Is there any other way I could try to upload the file to the url using R?
Any help or suggestions are appreciated!

Ruby http Get returning truncated response

I tried sending a HTTP Get to a device's Restful API via Postman and it worked fine returning all text I was expecting. Postman suggested Ruby code for the request was the following:
url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request.basic_auth 'admin', 'admin'
request["accept"] = 'Application/json'
response = http.request(request)
puts response.read_body
but when I tried that in my code, it is returning a truncated response (missing lines) and I have to resend the same Get multiple times to get the entire text response response.
Is there anything missing in the Ruby code above that's causing this truncated response?
Update 1
I tried this
url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request.basic_auth 'admin', 'admin'
request["accept"] = 'Application/json'
response = http.request(request)
puts response.read_body
response.read_body do |segment|
puts segment.to_s
end
and that generated this error
IOError (Net::HTTPOK#read_body called twice):
Update 2
I tried this
1073 url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
1074 http = Net::HTTP.new(url.host, url.port)
1075 request = Net::HTTP::Get.new(url.to_s)
1076 request.basic_auth 'admin', 'admin'
1077 request["accept"] = 'Application/json'
1078 response = http.request(request)
1079 response.read_body do |segment|
1080 puts segment.to_s
1081 end
and got this error
IOError (Net::HTTPOK#read_body called twice):
app/controllers/Apps_controller.rb:1079:in `block in get_config'
app/controllers/Apps_controller.rb:1045:in `each'
app/controllers/Apps_controller.rb:1045:in `get_config'
Based on: http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTPResponse.html#method-i-read_body
read_body returns the body as stream, so you should iterate it, something like:
response.read_body do |segment|
puts segment
end
If you want to get the full body just use: response.body
Looks very similar....
We are getting truncated responses when pulling a set of artifacts (zip files) from a Bamboo server and writing to local storage. It happens inconsistently, on only one of 8 servers, and not always the same file. Seems always to be the last portion of the file that is missing.
Using Ruby 2.0.0p598 and net/http.
The zip files range in size from 2 mb to 34 mb.
While we haven't figured out why the response body has been truncated, our workaround is to compare the expected content length (in the response header), to the response body size. If they don't match, try it again. Example code:
package = "packages/applicationname.zip"
def retrieve(package)
# generates the Bamboo url for the given package
sourceURL = package_url package
expectedLength = 0
bodyLength = 1
# Try to catch the bad download and re-issue the GET request,
while expectedLength != bodyLength do
# add a counter if worried about getting stuck
# issue the request to get the current package zip file
response = my_request_wrapper sourceURL
expectedLength = response['content-length'].to_i
theBody = response.body
bodyLength = theBody.size
if expectedLength != bodyLength then
puts "!! SIZE MISMATCH !!"
else
# the response body is good, process as needed
open package, 'wb' do |io|
io.write theBody
end
end
end
end
def my_request_wrapper(url)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Get.new(uri.request_uri)
req.basic_auth("user", "pwd")
return http.request req
end
I was using OSX Sierra, rvm, and ruby 2.3.0
Updating my rvm, ruby, and gems seems to have fixed the problem for me
I think you must call http.start before you call http.request.
Not sure why, but I see the same.

Resources