Fjord
Fjord

Reputation: 195

Get uploaded file name after request post - python

I have a model endpoint running in Azure Kubernetes Service and I am not using Django or Flask. I am sending local png files to score as follows:

import base64
import json
import cv2
import requests

img_path = 'C:/path/to/exampleImage.png'
link = aks_service.scoring_uri
api_key = aks_service.get_keys()[0]

def send2score(img_path, score_url, api_key):
    headers = {'Content-Type': 'application/json',
               'Authorization': ('Bearer ' + api_key)
               }
    
    img = cv2.imread(img_path)
    string = base64.b64encode(cv2.imencode('.png', img)[1]).decode()
    dict = {
        'img': string
        }
    jsonimg2 = json.dumps(dict, ensure_ascii=False, indent=4)
    resp = requests.post(url=link, data=jsonimg2, headers=headers)
    print(resp.text)    

send2score(img_path=img_path, score_url=link, api_key=api_key)

My question is: how can I get the file name (exampleImage.png) in the score script in Azure Kubernetes after I do the request.post? Please no Django or Flask specific methods

Bonus question: Feel free to suggest improvements in the way I am uploading the data (send2score function), this function is working, I get the score back, I just can't get the file name in the score script. Thank you!

Upvotes: 0

Views: 697

Answers (2)

Fjord
Fjord

Reputation: 195

I was overcomplicating things, I realized that I am sending the encoded image as a json in a dictionary. I can include other information, like the file name, in the dictionary:

import base64
import json
import cv2
import requests

img_path = 'C:/path/to/exampleImage.png'
link = aks_service.scoring_uri
api_key = aks_service.get_keys()[0]

def send2score(img_path, score_url, api_key):
    headers = {'Content-Type': 'application/json',
               'Authorization': ('Bearer ' + api_key)
               }
    
    img = cv2.imread(img_path)
    string = base64.b64encode(cv2.imencode('.png', img)[1]).decode()
    dict = {
        'imgname': os.path.basename(img_path), 
        'img': string
        }
    jsonimg2 = json.dumps(dict, ensure_ascii=False, indent=4)
    resp = requests.post(url=link, data=jsonimg2, headers=headers)
    print(resp.text)    

send2score(img_path=img_path, score_url=link, api_key=api_key)

And I can get the image and file name in the score script:

# Lots of code before

response = json.loads(path)
string = response['img']
jpg_original = base64.b64decode(string) # decode
jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
img0 = cv2.imdecode(jpg_as_np, flags=1) # image
img0name = response['imgname'] # file name

# Lots of code after

Upvotes: 0

Jim Xu
Jim Xu

Reputation: 23111

According to your code, you send your image as base64 string. It cannot contain the file name. I think you need to define a parameter to store the file name in request body. Besides, you also can post the file as a Multipart-Encoded File with the requests module. For example

send file

import requests
import magic
import os
url = ''
path = "D:/sample/image/faces.jpg"

mime = magic.Magic(mime=True)

headers = {
    'Authorization': ('Bearer ' + 'cdff')
}
files = {'file': (os.path.basename(path), open(path, 'rb'), mime.from_file(path), {'Expires': '0'})}
res = requests.post(url, files=files, headers=headers)
print(res.content.decode('utf-8'))


My backend

from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
hostName = 
hostPort = 


class MyServer(BaseHTTPRequestHandler):
    def do_POST(self):
        try:
            // use cgi to read file
            form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ={
                                    'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers['Content-Type'], })
            file = form.list[0]
            data =file.file.read()
            #process data
            .............
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(bytes(
                f"<html><head></head><body><h2>fileName : {file.filename}</h2>/html>", "utf-8"))
            

        except Exception as e:
            httperror = e.httperror if hasattr(e, "httperror") else 500
            self.send_error(httperror, str(e))  # Send an error response


myServer = HTTPServer((hostName, hostPort), MyServer)
myServer.serve_forever()

Upvotes: 1

Related Questions