Image Upload | Flask – Froala

The following sections describe how to handle image uploads on your server using Flask as a server-side language. For information on the upload workflow refer to the image upload documentation.

Setting up the index page.

The full code should look like this:

The full code should look like this:

server.py handles the server part for flask

Inside server.py, the Image class handles the image upload

from

flask

import

Flask, request, send_from_directory, jsonify

import

base64

import

datetime

from

os.path

import

isfile, join

from

mimetypes

import

MimeTypes

from

os

import

listdir

from

wand.image

import

Image

import

wand.image

import

hashlib

import

json

import

time

import

hmac

import

copy

import

sys

import

os

import

wand.image BASE_DIR = os.path.dirname(os.path.abspath(__file__)) publicDirectory = os.path.join(BASE_DIR,

"public"

)

if

not

os.path.exists(publicDirectory): os.makedirs(publicDirectory) app = Flask(__name__, static_url_path =

""

)

def

get_main_html

()

:

return

send_from_directory(

"./"

,

"index.html"

)

def

get_public

(path)

:

return

send_from_directory(

"public/"

, path)

def

get_static

(path)

:

return

send_from_directory(

"./"

, path)

def

upload_image

()

:

try

: response = Image.upload(FlaskAdapter(request),

"/public/"

)

except

Exception: response = {

"error"

: str(sys.exc_info()[

1

])}

return

json.dumps(response)

def

upload_image_validation

()

:

def

validation

(filePath, mimetype)

:

with

wand.image.Image(filename = filePath)

as

img:

if

img.width != img.height:

return

False

return

True

options = {

"fieldname"

:

"myImage"

,

"validation"

: validation }

try

: response = Image.upload(FlaskAdapter(request),

"/public/"

, options)

except

Exception: response = {

"error"

: str(sys.exc_info()[

1

])}

return

json.dumps(response)

class

Image

(object)

: defaultUploadOptions = {

"fieldname"

:

"file"

,

"validation"

: {

"allowedExts"

: [

"gif"

,

"jpeg"

,

"jpg"

,

"png"

,

"svg"

,

"blob"

],

"allowedMimeTypes"

: [

"image/gif"

,

"image/jpeg"

,

"image/pjpeg"

,

"image/x-png"

,

"image/png"

,

"image/svg+xml"

] },

"resize"

:

None

}

def

upload

(req, fileRoute, options = None)

:

""" Image upload to disk. Parameters: req: framework adapter to http request. See BaseAdapter. fileRoute: string options: dict optional, see defaultUploadOptions attribute Return: dict: {link: "linkPath"} """

if

options

is

None

: options = Image.defaultUploadOptions

else

: options = Utils.merge_dicts(Image.defaultUploadOptions, options)

return

File.upload(req, fileRoute, options)

def

delete

(src)

:

""" Delete image from disk. Parameters: src: string """

return

File.delete(src)

def

list

(folderPath, thumbPath = None)

:

""" List images from disk. Parameters: folderPath: string thumbPath: string Return: list: list of images dicts. example: [{url: "url", thumb: "thumb", name: "name"}, ...] """

if

thumbPath ==

None

: thumbPath = folderPath response = [] absoluteFolderPath = Utils.getServerPath() + folderPath imageTypes = Image.defaultUploadOptions[

"validation"

][

"allowedMimeTypes"

] fnames = [f

for

f

in

listdir(absoluteFolderPath)

if

isfile(join(absoluteFolderPath, f))]

for

fname

in

fnames: mime = MimeTypes() mimeType = mime.guess_type(absoluteFolderPath + fname)[

0

]

if

mimeType

in

imageTypes: response.append({

"url"

: folderPath + fname,

"thumb"

: thumbPath + fname,

"name"

: fname })

return

response

class

Utils

(object)

:

""" Utils static class. """

def

hmac

(key, string, hex = False)

:

""" Calculate hmac. Parameters: key: string string: string hex: boolean optional, return in hex, else return in binary Return: string: hmax in hex or binary """

try

: hmac256 = hmac.new(key.encode()

if

isinstance(key, str)

else

key, msg = string.encode(

"utf-8"

)

if

isinstance(string, str)

else

string, digestmod = hashlib.sha256)

except

Exception: hmac256 = hmac.new(key, msg = string, digestmod = hashlib.sha256)

return

hmac256.hexdigest()

if

hex

else

hmac256.digest()

def

merge_dicts

(a, b, path = None)

:

""" Deep merge two dicts without modifying them. Source: http://stackoverflow.com/questions/7204805/dictionaries-of-dictionaries-merge/7205107#7205107 Parameters: a: dict b: dict path: list Return: dict: Deep merged dict. """

aClone = copy.deepcopy(a);

if

path

is

None

: path = []

for

key

in

b:

if

key

in

a:

if

isinstance(a[key], dict)

and

isinstance(b[key], dict): aClone[key] = Utils.merge_dicts(a[key], b[key], path + [str(key)])

else

: aClone[key] = b[key]

else

: aClone[key] = b[key]

return

aClone

def

getExtension

(filename)

:

""" Get filename extension. Parameters: filename: string Return: string: The extension without the dot. """

return

os.path.splitext(filename)[

1

][

1

:]

def

getServerPath

()

:

""" Get the path where the server has started. Return: string: serverPath """

return

os.path.abspath(os.path.dirname(sys.argv[

0

]))

def

isFileValid

(filename, mimetype, allowedExts, allowedMimeTypes)

:

""" Test if a file is valid based on its extension and mime type. Parameters: filename string mimeType string allowedExts list allowedMimeTypes list Return: boolean """

if

not

allowedExts

or

not

allowedMimeTypes:

return

False

extension = Utils.getExtension(filename)

return

extension.lower()

in

allowedExts

and

mimetype

in

allowedMimeTypes

def

isValid

(validation, filePath, mimetype)

:

""" Generic file validation. Parameters: validation: dict or function filePath: string mimetype: string """

if

not

validation:

return

True

if

callable(validation):

return

validation(filePath, mimetype)

if

isinstance(validation, dict):

return

Utils.isFileValid(filePath, mimetype, validation[

"allowedExts"

], validation[

"allowedMimeTypes"

])

return

False

class

BaseAdapter

(object)

:

""" Interface. Inherit this class to use the lib in your framework. """

def

__init__

(self, request)

:

""" Constructor. Parameters: request: http request object from some framework. """

self.request = request

def

riseError

(self)

:

""" Use this when you want to make an abstract method. """

raise

NotImplementedError(

"Should have implemented this method."

)

def

getFilename

(self, fieldname)

:

""" Get upload filename based on the fieldname. Parameters: fieldname: string Return: string: filename """

self.riseError()

def

getMimetype

(self, fieldname)

:

""" Get upload file mime type based on the fieldname. Parameters: fieldname: string Return: string: mimetype """

self.riseError()

def

saveFile

(self, fieldname, fullNamePath)

:

""" Save the upload file based on the fieldname on the fullNamePath location. Parameters: fieldname: string fullNamePath: string """

self.riseError()

class

FlaskAdapter

(BaseAdapter)

:

""" Flask Adapter: Check BaseAdapter to see what methods description. """

def

checkFile

(self, fieldname)

:

if

fieldname

not

in

self.request.files:

raise

Exception(

"File does not exist."

)

def

getFilename

(self, fieldname)

: self.checkFile(fieldname)

return

self.request.files[fieldname].filename

def

getMimetype

(self, fieldname)

: self.checkFile(fieldname)

return

self.request.files[fieldname].content_type

def

saveFile

(self, fieldname, fullNamePath)

: self.checkFile(fieldname) file = self.request.files[fieldname] file.save(fullNamePath)

Xổ số miền Bắc