I don't know where you've learnt how HTTP works but I'm pretty sure that you did not study the actual standard which you should do when implementing a protocol. Some notes about your implementation:

  • Line ends should be \r\n not \n. This is true for both responses from the server as requests from the client.
  • You are assuming that the clients requests is never larger than 1024 bytes and that it can be read within a single recv. But, requests can have arbitrary length and there is no guarantee that you get all within a single recv (TCP is a streaming protocol and not a message protocol).
  • While it is kind of ok to simply close the TCP connection after the body it would be better to include the length of the body in the Content-length header or use chunked transfer encoding.
  • The type of the content should be given by using the Content-Type header, i.e. Content-type: text/html for HTML and Content-type: image/jpeg for JPEG images. Without this browser might guess correctly or wrongly what the type might be or depending on the context might also insist on a proper content-type header.

Apart from that, if you debug such problems it is helpful to find out what gets actually exchanged between client and server. It might be that you've checked this for yourself but you did not include such information into your question. Your only error description is "...I recive the call but cannot preset the png/JPEG in the page" and then a dump of your code.

Answer from Steffen Ullrich on Stack Overflow
Top answer
1 of 2
3

I don't know where you've learnt how HTTP works but I'm pretty sure that you did not study the actual standard which you should do when implementing a protocol. Some notes about your implementation:

  • Line ends should be \r\n not \n. This is true for both responses from the server as requests from the client.
  • You are assuming that the clients requests is never larger than 1024 bytes and that it can be read within a single recv. But, requests can have arbitrary length and there is no guarantee that you get all within a single recv (TCP is a streaming protocol and not a message protocol).
  • While it is kind of ok to simply close the TCP connection after the body it would be better to include the length of the body in the Content-length header or use chunked transfer encoding.
  • The type of the content should be given by using the Content-Type header, i.e. Content-type: text/html for HTML and Content-type: image/jpeg for JPEG images. Without this browser might guess correctly or wrongly what the type might be or depending on the context might also insist on a proper content-type header.

Apart from that, if you debug such problems it is helpful to find out what gets actually exchanged between client and server. It might be that you've checked this for yourself but you did not include such information into your question. Your only error description is "...I recive the call but cannot preset the png/JPEG in the page" and then a dump of your code.

2 of 2
2

httpServer.py

Ended up like:

while True:
# Wait for client connections
client_connection, client_address = server_socket.accept()

# Handle client request
request = client_connection.recv(10240).decode()
content = handle_request(request)

# Send HTTP response
if content:
    if str(content).find("html") > 0:
        client_connection.send('HTTP/1.1 200 OK\n\n'.encode())
        client_connection.send(content.encode())
    else:
        client_connection.send('HTTP/1.1 200 OK\r\n'.encode())
        client_connection.send("Content-Type: image/jpeg\r\n".encode())
        client_connection.send("Accept-Ranges: bytes\r\n\r\n".encode())
        client_connection.send(content)
else:
    response = 'HTTP/1.1 404 NOT FOUND\r\nFile Not Found'

client_connection.close()

And the Get method like:

class HTTPHandler:

def get(self, args, type):
    if args == '/':
        args = '/index.html'
        fin = open('htdocs' + args)
    if type != "image":
        fin = open('htdocs/' + args)

    if type.find("html") == -1:
        image_data = open('htdocs/' + args, 'rb')
        bytes = image_data.read()

        # Content-Type: image/jpeg, image/png \n\n
        content = bytes
        fin.close()
        return content

    # Read file contents
    content = fin.read()
    fin.close()
    return content
🌐
Engineering LibreTexts
eng.libretexts.org › campus bookshelves › delta college › introduction to programming concepts - python › 12: networked programs
12.3: Retrieving an image over HTTP - Engineering LibreTexts
July 27, 2020 - Instead of copying the data to the screen as the program runs, we accumulate the data in a string, trim off the headers, and then save the image data to a file as follows: %%python3 import socket import time HOST = 'data.pr4e.org' PORT = 80 ...
Discussions

How to receive images on a python server from a client.
You're opening a raw socket in the server, and you're trying to send the data using HTTP POST. That _could_ work. However, you'd have to implement the HTTP protocol in your server. You're sending more information that just the raw file. It would be much easier to write your server using something like Bottle. http://pwp.stevecassidy.net/bottle/file-upload.html Also, even though you're working with images, you're really just sending a file. More on reddit.com
🌐 r/Python
5
0
July 27, 2019
How to encode image to send over Python HTTP server? - Stack Overflow
Stack Overflow chat opening up to all users in January; Stack Exchange chat... Modernizing curation: A proposal for The Workshop and The Archive ... 0 Using python how do I convert an RGB array to an encoded image suitable for transmission via HTTP? More on stackoverflow.com
🌐 stackoverflow.com
How to send image using socketserver
I was able to send static files to the client without problems through the socketserver python module. Now I have problems when sending image files, below is the code : self.header = \ "Content-Type: image/png \n" \… More on discuss.python.org
🌐 discuss.python.org
11
0
July 9, 2021
How do I send image with Python requests and receive it with Flask request ?
remove the content-type header and set it on the file itself if desired: https://requests.readthedocs.io/en/master/user/quickstart/#post-a-multipart-encoded-file More on reddit.com
🌐 r/flask
6
0
March 4, 2021
🌐
Reddit
reddit.com › r/python › how to receive images on a python server from a client.
r/Python on Reddit: How to receive images on a python server from a client.
July 27, 2019 -

I'm trying to receive images on my python program, I've searched a lot on the internet but most of them are just tutorials about sending images. I found a few about receiving but none of them worked for me. All the other ones with receiving did it using a GET request first, which is not what I want. I'm sending a cURL POST request with a file in it (later on it will be sent from a real server, not a cURL) I want the server to keep listening until I upload/POST an image, then I want to receive the image and display it using PIL.

Here is the code I found online but doesn't work, I really have no clue how to receive images.

import socket
import struct
from PIL import Image

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 12801))
s.listen(1000)

print('Waiting for data...')

client, addr = s.accept()
print('got connected from', addr)

buf = b''            # this caused an error, I added a b so it would be read as bytes and not string
while len(buf)<4:
    buf += client.recv(4-len(buf))
size = struct.unpack('!i', buf)
print("receiving %s bytes" % size)

with open('tst.jpg', 'wb') as img:
    while True:
        data = client.recv(1024)
        if not data:
            break
        img.write(data)
print('received image')

Here is the output when I send a 101.345 bytes JPG file

Waiting for data...
got connected from ('127.0.0.1', 51861)
receiving 1347375956 bytes

1347375956 bytes... that's clearly bugged and not working properly. It's also stuck at that part just waiting.

Just to show you how I got the sending part working and how easy that was (it's not sending to a python program/server, but to an ESP webserver)..:

url = ' http://192.168.x.xx/fupload'
files = {'media': open('converted_image.bmp', 'rb')}
req.post(url, files=files)

I hope anyone can help me out.

Find elsewhere
🌐
ProxiesAPI
proxiesapi.com › articles › uploading-images-with-python-requests
Uploading Images with Python Requests | ProxiesAPI
url = "https://api.example.com/image-upload" headers = {"Authorization": "Client-ID xxx"} r = requests.post(url, headers=headers) ... The first part defines the file name on the server. The second part attaches the actual image data.
🌐
Py4inf
py4inf.com › html-270 › book013.html
Chapter 12 Networked programs
We can slow down our successive recv() calls by uncommenting the call to time.sleep(). This way, we wait a quarter of a second after each call so that the server can “get ahead” of us and send more data to us before we call recv() again. With the delay, in place the program executes as follows: $ python urljpeg.py 1460 1460 5120 6580 5120 11700 ... 5120 62900 5120 68020 2281 70301 Header length 240 HTTP/1.1 200 OK Date: Sat, 02 Nov 2013 02:22:04 GMT Server: Apache Last-Modified: Sat, 02 Nov 2013 02:01:26 GMT ETag: "19c141-111a9-4ea280f8354b8" Accept-Ranges: bytes Content-Length: 70057 Connection: close Content-Type: image/jpeg
🌐
GitHub
gist.github.com › kylehounslow › 767fb72fde2ebdd010a0bf4242371594
Send and receive images using Flask, Numpy and OpenCV · GitHub
And from a server side you don't usually have a user interface ... what I would do 1: generate the image using cv2 saving it on a file o just keeping it on memory 2: Find out how to share that image to someone outside the server (Make a RESt API maybe or generate something with sockets) Maybe this will help https://stackoverflow.com/questions/55822414/how-to-display-an-encoded-opencv-image-on-a-flask-web-server
🌐
Reddit
reddit.com › r/flask › how do i send image with python requests and receive it with flask request ?
r/flask on Reddit: How do I send image with Python requests and receive it with Flask request ?
March 4, 2021 -

Hi Flaskers,

I'm having difficulty receiving image on the Flask backend:

@auth_blueprint.route('/auth/check_image', methods=['POST'])
@cross_origin()
def check_image():
    try:
        image_given = request.files['photo']  # <-- image won't make it to Flask
        img = Image.open(image_given.stream)
        return jsonify({'status': 'OK', 'message': f'{img.width} {img.height}'})

Kivy front-end:

img = {'file': ('photo': open(f'{self.image_path}/example.jpg', 'rb'))}
try:
    response = requests.post('http://www.example.com/auth/check_image', files=img)
    print(str(response.content, 'utf-8'))

Error output:

<title>500 Internal Server Error</title>
03-02 17:06:26.295 15175 15678 I python  : <h1>Internal Server Error</h1>
03-02 17:06:26.295 15175 15678 I python  : <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>

Error output from the backend:

"content":"400 Bad Request: The browser (or proxy) sent a request that this server could not understand.","status":"fail"

I've found this block of code that allegedly works:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/im_size", methods=["POST"])
def process_image():
    file = request.files['image']
    # Read the image via file.stream
    img = Image.open(file.stream)

    return jsonify({'msg': 'success', 'size': [img.width, img.height]})


if __name__ == "__main__":
    app.run(debug=True)

url = 'http://127.0.0.1:5000/im_size'
my_img = {'image': open('test.jpg', 'rb')}
r = requests.post(url, files=my_img)

# convert server response into JSON format.
print(r.json())

I found the code here https://jdhao.github.io/2020/04/12/build_webapi_with_flask_s2/, strangely I'm getting status code 400 using it.

Thank you for any insight.

🌐
YouTube
youtube.com › watch
SEND AN IMAGE WITH SOCKETS | Python - YouTube
Andrey Ivanov - PythonUse my discount link for OKEX crypto exchange: https://www.okx.com/join/PYTHONANDREYMy UDEMY courses: https://www.udemy.com/user/andrey...
Published   November 14, 2020
🌐
GitHub
github.com › deirvlon › Python-TCP-Image
GitHub - deirvlon/Python-TCP-Image: Send and Receive Image over TCP connection in python
Convert it into bytes to be able to send over net · Receives bytes (data = connection.recv(388800)), Convert bytes into numpy array, After converting we get 1 dimentional array shape of (388800,1), Then we reshape this array into (270, 480, 3). This is the form of cv2 image . Numpy to bytes · bytes to Numpy · Link: https://stackoverflow.com/questions/49511753/python-byte-image-to-numpy-array-using-opencv/61273896#61273896
Author   deirvlon
🌐
OpenMV Forums
forums.openmv.io › openmv boards
how to send image to server by post to http? - Page 3 - OpenMV Boards - OpenMV Forums
June 21, 2021 - So I replaced it with urequests.py from Wipy link, I get following error; OSError: [Errno 107] ENOTCONN OpenMV Terminal: Traceback (most recent call last): File “”, line 47, in File “urequests.py”, line 107, in post File “urequests.py”, line 124, in urlopen File “urequests.py”, line 27, in init OSError: [Errno 107] ENOTCONN So it opens urequests.py in OpenMV and stops at line 27 as shown in abovementioned traceback.
Top answer
1 of 8
77

From wechat api doc:

curl -F [email protected] "http://file.api.wechat.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"

Translate the command above to python:

import requests
url = 'http://file.api.wechat.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE'
files = {'media': open('test.jpg', 'rb')}
requests.post(url, files=files)

Doc: https://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file

2 of 8
37

In case if you were to pass the image as part of JSON along with other attributes, you can use the below snippet.
client.py

import base64
import json                    

import requests

api = 'http://localhost:8080/test'
image_file = 'sample_image.png'

with open(image_file, "rb") as f:
    im_bytes = f.read()        
im_b64 = base64.b64encode(im_bytes).decode("utf8")

headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  
payload = json.dumps({"image": im_b64, "other_key": "value"})
response = requests.post(api, data=payload, headers=headers)
try:
    data = response.json()     
    print(data)                
except requests.exceptions.RequestException:
    print(response.text)

server.py

import io
import json                    
import base64                  
import logging             
import numpy as np
from PIL import Image

from flask import Flask, request, jsonify, abort

app = Flask(__name__)          
app.logger.setLevel(logging.DEBUG)
  
  
@app.route("/test", methods=['POST'])
def test_method():         
    # print(request.json)      
    if not request.json or 'image' not in request.json: 
        abort(400)
             
    # get the base64 encoded string
    im_b64 = request.json['image']

    # convert it into bytes  
    img_bytes = base64.b64decode(im_b64.encode('utf-8'))

    # convert bytes data to PIL Image object
    img = Image.open(io.BytesIO(img_bytes))

    # PIL image object to numpy array
    img_arr = np.asarray(img)      
    print('img shape', img_arr.shape)

    # process your img_arr here    
    
    # access other keys of json
    # print(request.json['other_key'])

    result_dict = {'output': 'output_key'}
    return result_dict
  
  
def run_server_api():
    app.run(host='0.0.0.0', port=8080)
  
  
if __name__ == "__main__":     
    run_server_api()
🌐
freeCodeCamp
forum.freecodecamp.org › python
POST both image and text - Python - The freeCodeCamp Forum
July 26, 2021 - I’m trying to send a small image and some sensor values from a remote raspberry pi using POST. I can send the sensor values just fine, and I can send the image no problem, but I can’t seem to get it to work when I try to do them both in one POST. url = { 'https://url/post' } files = { 'file': open('test.jpg','rb') } values = { 'datetime': dateTime, 'airqual': airqual, 'temperature': temperature, 'pressure': pressure, 'humidity': humidity } r = requests.post(url=...
🌐
Stack Overflow
stackoverflow.com › questions › 47569320 › sending-an-image-from-a-server-to-client-using-http-in-python
Sending an image from a server to client using HTTP in python - Stack Overflow
November 30, 2017 - req = clnt.recv(102400) a = ... + strng) clnt.close() time.sleep(30) ... You could always base64 encode your image, send that to the server and then decode it. It's how I usually handle image transfers over HTT...
🌐
OpenMV Forums
forums.openmv.io › openmv boards
how to send image to server by post to http? - OpenMV Boards - OpenMV Forums
January 10, 2019 - Dear, I am so sorry to send this message to you.I want to ask for some advice. I am working on a project related to gesture recognition. Currently, there are OpenMV3 and WIFI extensions. I want to capture images through OpenMV CAM, convert the images to binary data or base64 encoding, use wifi to access the server, and access the server through the browser.
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › python
how do i send a image file over http? - Raspberry Pi Forums
Traceback (most recent call last): File "<stdin>", line 87, in <module> UnicodeError: just trying to send a few small image asset files (8.5K, 11K, 68K, 87K, and 207K) ... #!/usr/bin/python3 from machine import Pin as GPIO from _thread import start_new_thread from uasyncio import create_task from time import sleep from os import stat import json import network import socket def file_exists(filename): try: return (stat(filename)[0] & 0x4000) == 0 except OSError: return False ssid="my WiFi" password="notMyWiFiPassword" wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect(ssid, pass