The method i used is to send an image to a chatbot and enter the server.
I want to send the image to the server without going through the chatbot.
I'm encoding the image file into base64 and sending it to the same port, but 400 or 500 errors keep coming out.
I was going to send it this way.
import os
import glob
import requests
import base64
folder_path = "./images"
image_files = glob.glob(os.path.join(folder_path, "*.jpg")) +
glob.glob(os.path.join(folder_path, "*.jpeg")) +
glob.glob(os.path.join(folder_path, "*.png"))
url="http://000000000/"
headers = {'Content-type':'application/json; charset=utf-8'}
for file_path in image_files:
with open(file_path, "rb") as file:
file_content = file.read()
encoded_file = base64.b64encode(file_content).decode()
data = {"file": (os.path.basename(file_path), encoded_file)}
r = requests.post(url, files=data, headers=headers)
print(f'{os.path.basename(file_path)} sent with status code {r.status_code}')
error message is :
requests.exceptions.ChunkedEncodingError: ("Connection broken: ConnectionAbortedError(10053
it is using ocr system which is in server
since i have to change the method to send imgae files. i wrote those codes but it's not working
Related
I am trying to make a code for image style transfer based on FastAPI. I found it effective to convert the byte of the image into base64 and transmit it.
So, I designed my client codeto encode the image into a base64 string and send it to the server, which received it succesfully. However, I face some difficulties in restoring the image bytes to ndarray.
I get the following this errors:
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
ValueError: cannot reshape array of size 524288 into shape (512,512,4)
This is my client code :
import base64
import requests
import numpy as np
import json
from matplotlib.pyplot import imread
from skimage.transform import resize
if __name__ == '__main__':
path_to_img = "my image path"
image = imread(path_to_img)
image = resize(image, (512, 512))
image_byte = base64.b64encode(image.tobytes())
data = {"shape": image.shape, "image": image_byte.decode()}
response = requests.get('http://127.0.0.1:8000/myapp/v1/filter/a', data=json.dumps(data))
and this is my server code:
import json
import base64
import uvicorn
import model_loader
import numpy as np
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
#app.get("/")
def read_root():
return {"Hello": "World"}
#app.get("/myapp/v1/filter/a")
async def style_transfer(data: dict):
image_byte = data.get('image').encode()
image_shape = tuple(data.get('shape'))
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
if __name__ == '__main__':
uvicorn.run(app, port='8000', host="127.0.0.1")
Option 1
As previously mentioned here, as well as here and here, one should use UploadFile, in order to upload files from client apps (for async read/write have a look at this answer). For example:
server side:
#app.post("/upload")
def upload(file: UploadFile = File(...)):
try:
contents = file.file.read()
with open(file.filename, 'wb') as f:
f.write(contents)
except Exception:
return {"message": "There was an error uploading the file"}
finally:
file.file.close()
return {"message": f"Successfuly uploaded {file.filename}"}
client side:
import requests
url = 'http://127.0.0.1:8000/upload'
file = {'file': open('images/1.png', 'rb')}
resp = requests.post(url=url, files=file)
print(resp.json())
Option 2
If, however, you still need to send a base64 encoded image, you can do it as previously described here (Option 2). On client side, you can encode the image to base64 and send it using a POST request as follows:
client side:
import base64
import requests
url = 'http://127.0.0.1:8000/upload'
with open("photo.png", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
payload ={"filename": "photo.png", "filedata": encoded_string}
resp = requests.post(url=url, data=payload)
On server side you can receive the image using a Form field, and decode the image as follows:
server side:
#app.post("/upload")
def upload(filename: str = Form(...), filedata: str = Form(...)):
image_as_bytes = str.encode(filedata) # convert string to bytes
img_recovered = base64.b64decode(image_as_bytes) # decode base64string
try:
with open("uploaded_" + filename, "wb") as f:
f.write(img_recovered)
except Exception:
return {"message": "There was an error uploading the file"}
return {"message": f"Successfuly uploaded {filename}"}
I want to download the file, it may be zip/7z. when I used the following code it is giving an error for the 7z file.
import requests, zipfile, StringIO
zip_file_url = "http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip"
try:
r = requests.get(zip_file_url, stream=True)
z = zipfile.ZipFile(StringIO.StringIO(r.content))
except requests.exceptions.ConnectionError:
print "Connection refused"
Just ensure the HTTP status code is 200 when requesting the file, and write out the file in binary mode:
import os
import requests
URL = "http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip"
filename = os.path.basename(URL)
response = requests.get(URL, stream=True)
if response.status_code == 200:
with open(filename, 'wb') as out:
out.write(response.content)
else:
print('Request failed: %d' % response.status_code)
The downloaded file will then appear in the directory where the script is being run if the request was successful, or an indication the file could not be downloaded.
I am using the python requests library's Session feature to request dynamically generated images from a remote server and write them to a file. The remote server is often unreliable and will respond with an html document, or pieces of the image. What is the best way to verify that the content is indeed the right format (not html), and has completely loaded? (my formats are png and csv) An example of my code is as follows:
import requests
ses = requests.Session()
data = ses.get("http://url")
localDest = os.path.join("local/file/path")
with open(localDest,'wb') as f:
for chunk in data.iter_content()
f.write(chunk)
How would I modify this code to check that it is the right format, and is a complete file?
You have two options:
If the server gave correct information in the headers about the content, check that for an invalid content type or an invalid content length.
If the server is lying about the content type or sets a content length to the size of the incomplete image, validate the content afterwards.
The following does both:
import imghdr
import os
import os.path
import requests
import shutil
ses = requests.Session()
r = ses.get("http://url", stream=True)
localDest = os.path.join("local/file/path")
if r.status_code == 200:
ctype = r.headers.get('content-type', '')
if ctype.partition('/')[0].lower() != 'image':
raise ValueError('Not served an image')
clength = r.headers.get('content-length')
clength = clength and int(clength)
with open(localDest, 'wb') as f:
r.raw.decode_content = True
shutil.copyfileobj(r.raw, f)
if clength and os.path.getsize(localDest) != clength:
os.remove(localDest)
raise ValueError('Served incomplete response')
image_type = imghdr.test(localDest)
if image_type is None:
os.remove(localDest)
raise ValueError('Not served an image')
You can also install Pillow and validate the image further with that.
The API I'm working on has a method to send images by POSTing to /api/pictures/ with the picture file in the request.
I want to automate some sample images with Python's requests library, but I'm not exactly sure how to do it. I have a list of URLs that point to images.
rv = requests.get('http://api.randomuser.me')
resp = rv.json()
picture_href = resp['results'][0]['user']['picture']['thumbnail']
rv = requests.get(picture_href)
resp = rv.content
rv = requests.post(prefix + '/api/pictures/', data = resp)
rv.content returns bytecode. I get a 400 Bad Request from the server but no error message. I believe I'm either 'getting' the picture wrong when I do rv.content or sending it wrong with data = resp. Am I on the right track? How do I send files?
--Edit--
I changed the last line to
rv = requests.post('myapp.com' + '/api/pictures/', files = {'file': resp})
Server-side code (Flask):
file = request.files['file']
if file and allowed_file(file.filename):
...
else:
abort(400, message = 'Picture must exist and be either png, jpg, or jpeg')
Server aborts with status code 400 and the message above. I also tried reading resp with BytesIO, didn't help.
The problem is your data is not a file, its a stream of bytes. So it does not have a "filename" and I suspect that is why your server code is failing.
Try sending a valid filename along with the correct mime type with your request:
files = {'file': ('user.gif', resp, 'image/gif', {'Expires': '0'})}
rv = requests.post('myapp.com' + '/api/pictures/', files = files)
You can use imghdr to figure out what kind of image you are dealing with (to get the correct mime type):
import imghdr
image_type = imghdr.what(None, resp)
# You should improve this logic, by possibly creating a
# dictionary lookup
mime_type = 'image/{}'.format(image_type)
I would like to deploy artifacts using Python (with a zip file which is like a set of artifacts and the dir-structure should be preserved - according to the docs)
When I use the following docs nothing happens (no files created in the repo) but I get an OK response:
import httplib
import base64
import os
dir = "/home/user/"
file = "archive.zip"
localfilepath = dir + file
artifactory = "www.stg.com"
url = "/artifactory/some/repo/archive.zip"
f = open(localfilepath, 'r')
filedata = f.read()
f.close()
authheader = "Basic %s" % base64.encodestring('%s:%s' % ("my-username", "my-password"))
conn = httplib.HTTPConnection(artifactory)
conn.request('PUT', url, filedata, {"Authorization": authheader, "X-Explode-Archive": "true"})
resp = conn.getresponse()
content = resp.read()
How could I make it work?
Edit: Solved it!
I put up a local artifactory and played with it, curl and requests to figure out what was going wrong. The issue is that artifactory expects the file to be uploaded in a streaming fashion. Luckily, requests also handles that easily. Here is
code I was able to get working with an artifactory instance.
import requests
import os
dir = "/home/user"
filename = "file.zip"
localfilepath = os.path.abspath(os.path.join(dir, filename))
url = "http://localhost:8081/artifactory/simple/TestRepository/file.zip"
headers = {"X-Explode-Archive": "true"}
auth = ('admin', 'password')
with open(localfilepath, 'rb') as zip_file:
files = {'file': (filename, zip_file, 'application/zip')}
resp = requests.put(url, auth=auth, headers=headers, data=zip_file)
print(resp.status_code)