Online Document Scanning Apps with Django and Dynamic Web TWAIN

Django is a popular framework of Python for web development. In this tutorial, we will create an web application with Django and Dynamic Web TWAIN.

Download and Installation

Version:

Python: 3.8.5
Django: 3.1.1
Dynamic Web TWAIN: 16.1.1

For the download and installation of Python and Django, please refer to their respective documentation for details.

If you have not installed Dynamic Web Twain yet, please refer to https://www.dynamsoft.com/docs/dwt/Dev-Guide/Obtain-WebTWAIN.html for installation details.

Overall steps

The steps that integrates django with Dynamic Web Twain are:

  1. Create a django project
  2. Create an app inside the project
  3. Develop an HTML template that loads the Dynamic Web Twain library. Use template syntax to generate the actual path of library.
  4. Configure the path of static files and templates.

Create your project with Django

Open your terminal to create a project with Django using the following command (applicable for Windows, Linux, macOS):

python -m django startproject djangodwt

Once completed, you will see the newly created project folder under your working directory.

Then, change your directory to djangodwt and run the app using the following command.

cd djangodwt
python manage.py runserver

After the server been successfully up, open a browser and visit the page. By default, the URL is http://127.0.0.1:8000.

Now, a django project has been successfully created.

Integrating with Dynamic Web TWAIN

Create the App

To build your web scanner app, you should firstly create an app.

python manage.py startapp dwt

In Django, project and app are different terminologies. An app is a Web application that does something. A project is a collection of apps that serve a particular website. For more details, refer to Writing your first Django app.

Now, the project structure is as follows.

djangodwt
  - djangodwt
    - __pycache__
    - asgi.py
    - settings.py
    - urls.py
    - wsgi.py
    - __init__.py
  - dwt
    - migrations
      - __init__.py
    - admin.py
    - apps.py
    - models.py
    - tests.py
    - views.py
    - __init__.py
  - db.sqlite3
  - manage.py

Create the view for Dynamic Web Twain

We will use a template to create our view. Conventionally, your template files should be placed under {project_folder/templates/{app_named_folder}/}. Let’s create one named index.html.

<!DOCTYPE html>
<head>
  <title>Dynamic Web Twain</title>
  <meta charset="utf-8">
  {% load static %}
  <!-- Import Dynamic Web Twain library. Template will compile the actual path for us. -->
  <script type="text/javascript" src="{% static 'dwt/Resources/dynamsoft.webtwain.initiate.js' %}"></script>
  <script type="text/javascript" src="{% static 'dwt/Resources/dynamsoft.webtwain.config.js' %}"></script>
</head>
<body>
  <div id="app">
    <div id="dwtcontrolContainer"></div>
    <button onclick="AcquireImage()">Scan</div>
  </div>
  <script type="text/javascript">
    function AcquireImage() {
      const DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
      if (DWObject) {
        if (DWObject.UseLocalService) {
          DWObject.SelectSource(() => {
            var OnAcquireImageSuccess = () => DWObject.CloseSource();
            var OnAcquireImageFailure = () => {
              DWObject.CloseSource();
              alert('image acquire failed');
            };
            DWObject.OpenSource()
            DWObject.IfDisableSourceAfterAcquire = true;
            DWObject.AcquireImage(OnAcquireImageSuccess, OnAcquireImageFailure);
          }, () => {
            console.error('SelectSource failed');
          });
        }
      } else {
        DWObject.LoadImageEx('', -1)
      }
    }
  </script>
</body>

Notice that the library path uses different syntax to let the template engine substitute the actual path of JS resources for us.

Moreover, we should specify its URL so that we can let Django know how to access it via HTTP request. In the app folder ({project_folder}/dwt in this case), create another file called urls.py and include the following code.

from django.urls import path
from . import views

urlpatterns = [
  path('', views.index, name='index')
]

Next, moving to the project’s urls.py. It is located in {project_folder}/{project_name}. We include the newly defined rules.

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
  path('admin/', admin.site.urls),
  path('', include('dwt.urls'))
]

Finally, remember to configure the templates directory in settings.py. We specify the template DIR as follows.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # this field
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Now running the server would get an exception saying that ‘You’re using the staticfiles app without having set the required STATIC_URL setting.’

Import Dynamic Web Twain

Since the js scripts are not added yet, we got the errors. Now, it’s time to import them to make our app working.

Preparing steps:

  1. Create a static folder under the project root.
  2. Create a dwt folder under previously created static folder.
  3. Copy and paste Dynamic Web Twain to static/dwt/.

Afterwards, we should configure where to find the static files in settings.py.

Tips: The js scripts are located under your DWT installed path. Just copy the Resources folder directly to your project’s static folder.

Append the following code to settings.py

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]

Finally, it is compulsory to configure Resource path of Dynamic Web Twain. Open the file static/dwt/Resources/dynamsoft.webtwain.config.js and uncomment the setting Dynamsoft.WebTwainEnv.ResourcesPath = 'Resources';. Update it with value 'static/dwt/Resources';.

The piece of code near ResourcesPath are shown as below. However, you can add the path anywhere inside the configure file.

///
Dynamsoft.WebTwainEnv.ResourcesPath = 'static/dwt/Resources'; // This line

///
Dynamsoft.WebTwainEnv.IfAddMD5InUploadHeader = false;

///
Dynamsoft.WebTwainEnv.IfConfineMaskWithinTheViewer = false;

Once they have all been set, you would get your Dynamic Web Twain application working properly.

Final Project Structure

djangodwt
  - djangodwt
    - __pycache__
    - asgi.py
    - settings.py
    - urls.py
    - wsgi.py
    - __init__.py
  - dwt
    - migrations
      - __init__.py
    - admin.py
    - apps.py
    - models.py
    - tests.py
    - urls.py
    - views.py
    - __init__.py
  - templates
    - dwt
      - index.html
  - static
    - dwt
      - Resources
  - db.sqlite3
  - manage.py

Source Code

https://github.com/dynamsoft-dwt/Scan-Documents-with-Python


References