Days
Hours
Minutes
Seconds
x

Froala Editor v4.1.4 is Here LEARN MORE

Skip to content

Python Image Server Upload

How it works

  1. Specify upload options when initializing the editor.
  2. On image insertion, the editor automatically makes an AJAX request to the server.
  3. Once the request reaches the server, it stores the image and sends back to the client the link to the uploaded image.

Jump to Complete Example

Initialize the editor

First, add the imageUploadURL option, as its value enter the upload destination for the images.

Next, set any additional options to configure upload methods and allowed file types: imageUploadParam, imageUploadParams, imageUploadMethod, imageMaxSize, imageAllowedTypes.

<script>
  new FroalaEditor('.selector', {
    // Set the image upload URL.
    imageUploadURL: '/upload_image'
  })
</script>

Receive the uploaded image and store it

The server implementation is responsible for receiving the request and handling it appropriately. In Python, the uploaded image is available in the request received by your application. However you should wrap the request object into an adapter. The Python SDK contains 3 adapters (Django, Flask and Pyramid) and you can create your custom adapter by implementing BaseAdapter class:

# Django adapter example.

from froala_editor import BaseAdapter

class DjangoAdapter(BaseAdapter):
"""
Django 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].name

def getMimetype(self, fieldname):
  self.checkFile(fieldname)
  return self.request.FILES[fieldname].content_type

def saveFile(self, fieldname, fullNamePath):
  self.checkFile(fieldname)

  with open(fullNamePath, 'wb+') as destination:
    for chunk in self.request.FILES[fieldname].chunks():
        destination.write(chunk)
You should override all methods from BaseAdapter. The Python editor SDK detects the uploaded image automatically but you have to specify the path where to store it.

Note: The path of the image is relative to the root of your application.

response = Image.upload(CustomAdapter(request), '/public/')

To store the uploaded image, the server needs write rights on the uploads folder. Additionally, check uploaded images are publicly accessible in the browser.

Return the path to the uploaded image

If the save action is successful, the SDK generates an ImageResponse object with the absolute path to the uploaded image and the server returns the path to the client side.

# Return a json. You can use json.dumps to transform the response dictionary into a json string.
json.dumps(response)

Complete Example

<script>
  new FroalaEditor('.selector', {
    // Set the image upload URL.
    imageUploadURL: '/upload_image'
  })
</script>
# Django
from django.http import HttpResponse
import json
from froala_editor import Image
from froala_editor import DjangoAdapter

def upload_image(request):
  try:
    response = Image.upload(DjangoAdapter(request), '/public/')
  except Exception:
    response = {'error': str(sys.exc_info()[1])}
  return HttpResponse(json.dumps(response), content_type="application/json")
# Flask
from flask import request
import json
from froala_editor import Image
from froala_editor import FlaskAdapter

@app.route('/upload_image', methods=['POST'])
def upload_image():
  try:
    response = Image.upload(FlaskAdapter(request), '/public/')
  except Exception:
    response = {'error': str(sys.exc_info()[1])}
  return json.dumps(response)
# Pyramid
from pyramid.response import Response
import json
from froala_editor import Image
from froala_editor import PyramidAdapter

def upload_image(request):
  try:
    response = Image.upload(PyramidAdapter(request), '/public/')
  except Exception:
    response = {'error': str(sys.exc_info()[1])}
  return Response(json.dumps(response))

Do you think we can improve this article? Let us know.

[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_1684764760" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>
[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_88822304" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>
[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_1017321803" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>