Doccano標註系統安裝與二次開發

Doccano標註系統安裝與二次開發(機器學習從業開發者標註工具,支持多語言)

Doccano是面向機器學習專業人員的開源文本標註工具。
doccano_001

Doccano標註系統安裝

在doccano項目中,已經簡單介紹過安裝方法。項目實際文件時在app中。

  1. git目錄結構如下: doccano_002

1.1 linux上單獨部署

git clone https://github.com/doccano/doccano.git
cd doccano/

doccano_003

  • 修改docker-compose.prod.yml文件中的用戶名和密碼
ADMIN_USERNAME: "admin"
ADMIN_PASSWORD: "password"
  • 運行項目
docker-compose -f docker-compose.dev.yml up

在doccano項目中,已經介紹了上面方法部署。這裏不再做過多介紹。

1.1 linux上,前後端分離部署

經過分析,doccano後端代碼在app目錄中,前端代碼在app/server/static目錄中。

  • 後端目錄 004
  • 前端目錄
    005
  1. 修改前端啓動ip及其他

    • 本次使用域名"www.mumuxi.online"
    • vim webpack.config.js修改後的文件如下
    const fs = require('fs');
    const path = require('path');
    const process = require('process');
    const BundleTracker = require('webpack-bundle-tracker');
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    const { ContextReplacementPlugin } = require('webpack');
    const hljsLanguages = require('./components/hljsLanguages');
    
    const devMode = process.env.DEBUG !== 'False';
    const hotReload = process.env.HOT_RELOAD === '1';
    const webpackHost = process.env.WEBPACK_HOST || '0.0.0.0';
    const webpackPort = process.env.WEBPACK_PORT ? parseInt(process.env.WEBPACK_PORT, 10) : 8080;
    const pollMillis = process.env.WEBPACK_POLL_MILLIS ? parseInt(process.env.WEBPACK_POLL_MILLIS, 10) : false;
    const noSourceMap = process.env.SOURCE_MAP === 'False';
    
    const pagesRoot = path.join(__dirname, 'pages');
    const entryPoints = {};
    fs.readdirSync(pagesRoot).forEach((scriptName) => {
        const bundleName = path.parse(scriptName).name;
        const scriptPath = path.join(pagesRoot, scriptName)
        entryPoints[bundleName] = scriptPath;
    });
    
    module.exports = {
        mode: devMode ? 'development' : 'production',
        entry: entryPoints,
        output: {
            publicPath: hotReload ? `http://www.mumuxi.online:${webpackPort}/` : '',
            path: path.join(__dirname, 'bundle'),
            filename: '[name].js'
        },
        devtool: noSourceMap ? false : (devMode ? 'cheap-eval-source-map' : 'source-map'),
        devServer: {
            port: webpackPort,
            host: webpackHost,
            disableHostCheck: true,
            hot: true,
            quiet: false,
            headers: { 'Access-Control-Allow-Origin': '*' }
        },
        watchOptions: {
            poll: pollMillis,
        },
        module: {
            rules: [
                {
                    test: /\.pug$/,
                    loader: 'pug-plain-loader'
                },
                {
                    test: /\.css$/,
                    use: [
                        'vue-style-loader',
                        'css-loader'
                    ]
                },
                {
                    test: /\.vue$/,
                    loader: 'vue-loader'
                }
            ]
        },
        plugins: [
            new ContextReplacementPlugin(
                /highlight\.js\/lib\/languages$/,
                new RegExp(`^./(${hljsLanguages.join('|')})$`)
            ),
            new BundleTracker({ filename: './webpack-stats.json' }),
            new VueLoaderPlugin()
        ],
        resolve: {
            extensions: ['.js', '.vue'],
            alias: {
                vue$: 'vue/dist/vue.esm.js',
            },
        },
    }
    

006

  1. 爲前端創建Dockerfile文件,內容如下

    FROM node
    
    WORKDIR /usr/src/app
    
    # 設置時區
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo 'Asia/Shanghai' >/etc/timezone
    
    
    CMD [ "bash"]
    
  2. 創建並運行前端容器

     # 構建鏡像文件
     docker build -t doccanoweb .  
    
    # 初始化npm
     docker run -i --rm --name doccanoweb --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccanoweb npm install
    
    # 使用npm編譯項目
     docker run -i --rm --name doccanoweb --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccanoweb npm run build
    
    # 啓動項目
    docker run --name doccanoweb --restart=always --network host -v "$PWD"/:/usr/src/app/ -d doccanoweb npm start
    

007
008
4. 創建後端dockerfile文件

* 進入目錄`/root/doccano001/doccano/app`目錄。刪除原來的Dockerfile文件,重新川劇新的Dockerfile文件,文件內容如下

````dockerfile
FROM python:3.7

WORKDIR /usr/src/app

RUN apt-get update \
    && apt-get install --no-install-recommends -y python3-dev libpq-dev unixodbc-dev

COPY requirements.txt ./

RUN pip install --no-cache-dir -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt

# 設置時區
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone


CMD [ "bash"]

````
  1. 創建後端鏡像,啓動後端。
# 根據dockerfile文件,構建後端鏡像doccano
docker build -t doccano .
# 初始化後端項目
docker run -i --rm --name doccano --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccano python manage.py makemigrations
docker run -i --rm --name doccano --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccano python manage.py migrate
# 創建管理員賬號密碼
docker run -i --rm --name doccano --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccano python manage.py create_admin --noinput --username "admin" --email "[email protected]" --password "admin"
# 項目初始化配置
docker run -i --rm --name doccano --network host -v "$PWD"/:/usr/src/app/ -e PYTHONUNBUFFERED=0 doccano python manage.py create_roles
# 啓動項目
docker run --name doccano --restart=always --network host -v "$PWD"/:/usr/src/app/ -d doccano gunicorn --bind 0.0.0.0:8000 app.wsgi -w 4 -k gthread --thread 16 --timeout 300

009010

  • 現在訪問:後端啓動端口127.0.0.1:8000(注意,由於自己服務器定義了域名,所以下面自己直接使用域名www.mumuxi.online:8000訪問)
    011

  • 使用admin用戶登錄後就可以創建項目了
    012

windows上二次開發環境部署

  1. 解壓下載後的文件進入下項目目錄D:\MyPythonUse\doccano\doccano\app014

  2. 使用pycharm代開次目錄,並創建虛擬開發環境

    • 虛擬環境python版本:Python 3.6.8
      015
  3. 安裝必要插件,及初始化項目。並啓動

    # 安裝插件
    pip install -r requirements.txt
    #初始化項目
    python manage.py makemigrations
    python manage.py migrate
    # 創建管理員用戶密碼
    python manage.py create_admin --noinput --username "admin" --email "[email protected]" --password "admin"
    # 初始化項目角色
    python manage.py create_roles
    #啓動項目(注意,現在啓動後還不能訪問,因爲前段還沒部署)
    python manage.py runserver
    

    017

  4. 使用cmd,進入前端目錄,本地部署前端

    • 前端目錄: \MyPythonUse\doccano\doccano\app\server\static
      016

    • 初始化前端,並部署

    # 初始化前端項目
    npm install
    # 編譯前端項目
    npm run build
    # 啓動前端項目
    npm start
    

018

  1. 現在前後端都啓動後,訪問:"http://127.0.0.1:8000"端口就可以看到項目已經部署成功。使用之前創建的用戶admin/admin可以直接登錄。
    019

  2. 創建一個簡單的項目text
    020

  3. 導入標註測試文件

    昆明長水機場南區vvip貴賓室在哪裏?
    昆明長水機場打包業務的營業時間?
    昆明長水機場貨運站在哪
    求 昆明長水機場客服電話
    求助!昆明長水機場裏面的肯德基或者麥當勞是24小時營業不?航班凌晨一點纔到昆明,想知道那時候肯德基
    昆明長水機場的貴賓廳哪家好?
    昆明長水機場2號航站樓有什麼銀行的自動取款服務?
    昆明長水機場T1航站樓的兒童樂園是哪裏做的啊?
    昆明長水機場可以兌換外幣嗎
    昆明長水機場有聯通貴賓室嗎?
    昆明長水機場有沒有更衣室
    昆明長水機場裏面有郵局嗎?我下了飛機後想直接把一個包裹郵寄掉,有什麼最快捷的方法麼?謝謝
    昆明長水國際機場有沒有盧布兌換櫃檯
    昆明長水機場附近有什麼酒店可以住宿麼?
    昆明長水機場有ATM機嗎?
    機場的頭等艙休息室裏面有吸菸室嗎
    昆明長水機場國內候機廳內有肯德基麥當勞嗎
    昆明長水機場有沒有工行ATM機
    從航天博物館到長沙黃花機場最快要多長時間啊?
    順豐速運在北京國際機場集散中心2,可是我就是在天津,這是要走空運嗎?不用吧應該
    一嗨租車 長沙黃花機場店怎麼樣
    九寨溝景區到長沙黃花機場需要多少過路費。
    寶安租車到機場去哪家租車公司能方便一些啊?
    長沙黃花機場的詳細地址,在哪個區?
    長沙黃花機場到中山
    花之城打車到長水機場多少錢?
    

021
022

基於doccano項目的二次開發,爲不同用戶平均分配標註任務

  • 問題:
    對於目前標註系統中,經過使用發現,當多用戶同時操作時,標註文檔是共享的。如果對於需要給每個參加標註的用戶平均分配標註任務。目前系統無法做到。

  • 解決:
    本次源碼修改,完善對sequence labeling做到權限文檔分配。
    1. admin管理員用戶,可以預覽和標註項目中所有文檔
    2. 其他用戶平均分配項目中所有文檔,每個用戶標註時,只能看見自己文檔。

  • 修改內容如下:

  1. 修改app/api/models.py文件中Document模型。增加一個字段userid

    userid = models.IntegerField(null=True)
    

023
2. 修改app/api/serializers.py中。對DocumentSerializer中的fields增加userid

024

  1. 在app/api/views.py中添加如下函數

    # 無線循環生成器(對列表中的值,依次循環返回)
    def getuserid(userids:list):
        nums = len(userids)
        def _getuserid():
            k = 0
            while True:
                if nums==0:
                    yield 0
                elif k<nums:
                    yield userids[k]
                    k+= 1
                else:
                    k = 0
        return _getuserid()
    

025
4. 修改app/api/views.py中TextUploadAPI類的的save_file方法如下:

````py
@classmethod
def save_file(cls, user, file, file_format, project_id):
    project = get_object_or_404(Project, pk=project_id)
    parser = cls.select_parser(file_format)
    data = parser.parse(file)
    storage = project.get_storage(data)
    # 動態注入屬性。爲id生成器
    storage.getuserid = getuserid([k.id for k in project.users.all() if k.username!="admin"])
    storage.save(user)
````

026

  1. 修改app/api/utils.py中BaseStorage中save_doc方法

    def save_doc(self, data):
        # 分配用戶id
        for k in data:
            k["userid"] = next(self.getuserid)
        serializer = DocumentSerializer(data=data, many=True)
        serializer.is_valid(raise_exception=True)
        doc = serializer.save(project=self.project)
        return doc
    

027

  1. 修改app/api/views.py中DocumentList類中get_queryset方法,根據用戶id獲取不同用戶數據

    def get_queryset(self):
        project = get_object_or_404(Project, pk=self.kwargs['project_id'])
    
        queryset = project.documents
        if self.request.user.username != "admin":
            queryset = queryset.filter(userid=self.request.user.id)
        if project.randomize_document_order:
            queryset = queryset.annotate(sort_id=F('id') % self.request.user.id).order_by('sort_id')
        else:
            queryset = queryset.order_by('id')
    
        return queryset
    

028
7. 修改app/api/views.py中StatisticsAPI中的progress方法。調整顯示進度情況

````py
# 修改用戶顯示總數情況
def progress(self, project):
    docs = project.documents
    annotation_class = project.get_annotation_class()
    if self.request.user.username != "admin":
        docs = docs.filter(userid=self.request.user.id)
    total = docs.count()
    annotation_filter = Q(document_id__in=docs.all())
    user_data = self._get_user_completion_data(annotation_class, annotation_filter)
    if not project.collaborative_annotation:
        annotation_filter &= Q(user_id=self.request.user)
    done = annotation_class.objects.filter(annotation_filter)\
        .aggregate(Count('document', distinct=True))['document__count']
    remaining = total - done
    return {'total': total, 'remaining': remaining, 'user': user_data}
````

029
8. 重啓項目

````py
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
````

030
9. 使用管理員用戶登錄,在users表中創建三個用戶t1,t2,t3
* 管理員頁面:http://127.0.0.1:8000/admin/

031
032
10. 使用admin登錄web,創建項目tt,並添t1,t2,t3用戶到項目中。

033

  1. 導出如下測試文件後,分別使用admin,t1,t2,t3登錄,可以看到,t1,t2,t3中的可標註數量已經平均分配。admin可以看到全部標註文檔

    1111111111111111111111111111111
    22222222222222222222
    3333333333333333333333333
    44444444444444444444444
    5555555555555555
    666666666666666666666666666666666
    777777777777777777777777777
    8888888888888888888888888888
    9999999999999999999999999999999999999
    00000000000000000000000000000
    121212121212121212121212121
    1313131313131313131313131
    14141414141414141414
    1515151515151515151515
    16161616161616161616
    171717171717171717
    18181818181818
    1919191919191919191919191919
    2020202020202002020202020
    212121212121212121212121212121
    
    • admin用戶可以看到20條數據
      034
    • t1用戶可以看到7條數據
      035
    • t2用戶可以看到7條數據
      036
    • t3用戶可以看到7條數據
      037
      作者:木木夕,郵箱:[email protected].正在python相關尋找工作。如有意向請聯繫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章