python making a post file request - python

Hi guys I'm developing a Python 3 quart asyncio application and I'm trying to setup a test framework around my http API.
Quart has methods to build json, form and raw requests but no files request. I believe I need build the request packet myself and post a "raw" request.
Using postman I can see that the requests need to look like this:
----------------------------298121837148774387758621\r\n
Content-Disposition: form-data; name="firmware"; filename="image.bin"\r\n
Content-Type: application/octet-stream\r\n
\r\n
\x00#\x00\x10\x91\xa0\t\x08+\xaa\t\x08/\xaa\t\x083\xaa\t\x087\xaa\t\x08;\xaa\t\x08\x00\x00\x00\
....
\xff\xff\xff\xff\xff\xff\xff\xa5\t\tZ\x0c\x00Rotea MLU Main V0.12\x00\x00k%\xea\x06\r\n
----------------------------298121837148774387758621--\r\n
I'd prefer not to encode this myself if there is a method that exists.
Is there an module in Python where I can build the raw packet data and send it with the Quart API?
I have tried using quart requests:
import requests
from .web_server import app as quart_app
test_client = quart_app.test_client()
firmware_image = 'test.bin'
with open(firmware_image, 'rb') as f:
data = f.read()
files = {'firmware': (firmware_image, data , 'application/octet-stream')}
firmware_req = requests.Request('POST', 'http://localhost:5000/firmware_update', files=files).prepare()
response = await test_client.post('/firmware_update',
data=firmware_req.body,
headers={'Content-type': 'multipart/form-data'})
Any suggestions would be greatly appreciated.
Cheers. Mitch.

Python's requests module provides a prepare function that you can use to get the raw data it would send for the request.
import requests
url = 'http://localhost:8080/'
files = {'file' : open('z', 'rb'),
'file2': open('zz', 'rb')}
req = requests.Request('POST',url, files=files)
r = req.prepare()
print(r.headers)
print(r.body)

Related

Telegram Bot SendDocument pdf

I am having a real headache with the way of sending a pdf file to a Telegram Bot.
Apparently I am following the documentation but never get it sent.
I am using the url: https://api.telegram.org/botBOTID/sendDocument?chat_id=CHATID&document=/home/lix/Downloads/2.pdf
It is a pdf file storaged locally, but I think it is just the way I am presenting it.
The error getting is:
{"ok":false,"error_code":400,"description":"Bad Request: URL host is empty"}
Does anybody knows how to send a pdf local file?
Many thanks
You should send a POST request, with the PDF as a payload, using the Python Requests library, your code should look something like this:
import requests
# Url with bot token + user id
url = "https://api.telegram.org/bot<MY-BOT-TOKEN>/sendDocument?chat_id=<MY_CHAT_ID>"
# Create payload with PDF file
payload = {}
files = [
('document', open('/home/lix/Downloads/2.pdf','rb'))
]
headers= {}
# Request
response = requests.request("POST", url, headers=headers, data = payload, files = files)
# Log reponse as UTF-8
print(response.text.encode('utf8'))

How to set up Accept-Encoding to gzip in Python client?

This is probably a very newbie question, but I'm reading HTTP Request library and I need to write a code that will make a request to a server and asks for gzip compression (since the server supports gzip compression).
For instance, I have:
import requests
r = requests.get('some_url')
r.json()
I know it has something to do with sending Accept-Encoding: gzip in the header of the HTTP request, but I'm not sure how to do that.
You should be able to set the header by using the header argument.
import requests
headers = {'Accept-Encoding': 'gzip'}
r = requests.get('some_url',headers=headers)
result = r.json()

Get and Put requests for json data format using urllib(2)

I need to implement "put" and "get" REST API requests for sending a JSON file.
The problem is that it has to be done using urllib or urllib2 module (e.g. no requests module).
Is there any brief tutorial on how to do it?
Thanks!
I assume that you're using python3. Here's how you can make simple put request with the standard library:
from urllib.request import Request, urlopen
import json
url, data = 'https://example.com', {'key': 'value'}
data_bytes = bytes(json.dumps(data), encoding='utf8')
request = Request(url, method='PUT', data=data_bytes, headers={'Content-Type': 'application/json'})
with urlopen(request) as response:
print(response.read())

Sending authenticated multipart/form-data request using Python Requests

Using Python and Requests, I am trying to upload a file to an API using multipart/form-data POST requests with a custom authentication mechanism (Just adding an 'Authentication-Token' header).
Here is the code I use:
import requests
from requests.auth import AuthBase
class MyAuth(AuthBase):
def __init__(self, token):
self.token = token
def __call__(self, r):
r.headers['Authentication-Token'] = self.token
return r
token = "175a5607d2e79109539b490f0f8ffe60"
url = "https://my-ap.com/files"
r = requests.post(url,
files={'file': open('qsmflkj.jpg', 'rb')},
data={'id': 151},
auth=MyAuth(token)
)
Unfortunately, this request causes the following exception on the server (the backend is using the Spring framework) :
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
I have tried a lot of things, like adding the header myself, but this seems to be the "right" way to do it, and it fails. I know that the API is used from various mobile clients, and hence, that it is possible to upload picture there. What could I do differently to be able to use this API in Python?
In the end, I never managed to do this with Requests, but I succeeded with urllib2 and the poster library:
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import urllib2
register_openers()
token = "175a5607d2e79109539b490f0f8ffe60"
with open('qsmflkj.jpg', 'rb') as f:
datagen, headers = multipart_encode({"file": f})
headers['Authentication-Token'] = token
request = urllib2.Request("https://myserver.com/files", \
datagen, headers)
response = urllib2.urlopen(request)

Send a request to webservice via an xml file?

I have a webservice running at "tcs-webdev2:8200/scheduler/requestgroup" to which new build requests can be sent using an xml file(sample xml file below). I need some guidance
on how requests to a webserive via n xml file work.
Sample xml file:-
<BuildInfo>
<BuildSource>DEV_CI</BuildSource>
<SoftwareProductBuild>MAAAAANLGD0000211.1_101</SoftwareProductBuild>
<PriorrootBuild>MAAAAANLGD0000211.1</PriorrootBuild>
<NewSIBuilds>
<Image>
<Type>LNX</Type>
<SoftwareImageBuild>buildlocation</SoftwareImageBuild>
<Location>\\\sever\buildlocation\checkout</Location>
<Variant>Default</Variant>
<LoadType>Debug</LoadType>
</Image>
</NewSIBuilds>
</BuildInfo>
It depends on your web service, how exactly you need to send the request, but you have to something like the following:
import httplib
with open("your_xml_filename.xml") as f:
body = f.read()
headers = {"Content-type": "application/xml"}
conn = httplib.HTTPConnection("tcs-webdev2", 8200)
conn.request("POST", "/scheduler/requestgroup", body, headers)
response = conn.getresponse()
print( response.status )
print( response.read())
conn.close()
It assumes that tcs-webdev2 is a valid hostname (if not, you can use the IP address). Also this request is an HTTP POST, your service might need different request type. Also some additional headers and authentication might be needed.

Categories

Resources