[PYTHON] Dockerfile pour serveur RESTful MeCab avec mecab-ipadic-neologd

Auparavant, il était difficile d'introduire mecab-python, alors mettons-le ensemble dans un Dockerfile.

La partie API REST a été implémentée dans Flask en faisant référence à here. La source peut être trouvée sur github. Ceci est pratique si vous essayez également d'utiliser docker-compose. Cela n'a pas très bon goût avec un seul récipient comme cette fois.

: mémo: [2016-10-07 ajouté] Ajout de la mise à jour du fichier dictionnaire. : memo: [PostScript du 11/03/2018] Ajout du frontal.

Dockerfile C'est le livrable.

FROM ubuntu:16.04

RUN apt-get update \
  && apt-get install python3 python3-pip curl git sudo cron -y \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /opt
RUN git clone https://github.com/taku910/mecab.git
WORKDIR /opt/mecab/mecab
RUN ./configure  --enable-utf8-only \
  && make \
  && make check \
  && make install \
  && ldconfig

WORKDIR /opt/mecab/mecab-ipadic
RUN ./configure --with-charset=utf8 \
  && make \
  &&make install

WORKDIR /opt
RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
WORKDIR /opt/mecab-ipadic-neologd
RUN ./bin/install-mecab-ipadic-neologd -n -y

COPY . /opt/api
WORKDIR /opt/api
RUN pip3 install -r requirements.txt

CMD ["python3", "server.py"]

: mémo: [PostScript 07/10/2016]

Autre

Structure du répertoire

.
├── README.md
├── docker-compose.yml
└── flask-mecab
    ├── Dockerfile
    ├── requirements.txt
    └── server.py

docker-compose.yml

api:
  build: ./flask-mecab
  volumes:
    - "./flask-mecab:/opt/api"
  ports:
    - "5000:5000"
  restart: always

Convertir la sortie MeCab au format JSON

Vous pouvez personnaliser le format de sortie de MeCab, mais par défaut

Type de surface\t part paroles,Sous-classification des paroles des parties 1,Sous-classification des pièces détachées 2,Sous-classification des paroles des parties 3,Type d'utilisation,Type d'utilisation,Prototype,en train de lire,prononciation

Comme c'est le cas, chaque ligne de la chaîne de caractères de sortie est divisée par '\ t'et', 'et zip () est utilisé pour correspondre à chaque élément.

server.py


def mecab_parse(sentence, dic='ipadic'):
    dic_dir = "/usr/local/lib/mecab/dic/"
    if dic == 'neologd':
        dic_name = 'mecab-ipadic-neologd'
    else:
        dic_name = dic

    m = MeCab.Tagger('-d ' + dic_dir + dic_name)

    #Format de sortie (par défaut)
    format = ['Type de surface', 'Partie','Partie細分類1', 'Partie細分類2', 'Partie細分類3', 'Type d'utilisation', 'Type d'utilisation','prototype','en train de lire','prononciation']

    return [dict(zip(format, (lambda x: [x[0]]+x[1].split(','))(p.split('\t')))) for p in m.parse(sentence).split('\n')[:-2]]

Voir également l'exemple d'exécution ci-dessous.

méthode de départ

C'est le seul démarrage car vous pouvez écrire les paramètres de transfert de port, etc. dans docker-compose.yml.

$ git clone https://github.com/matsulib/mecab-service.git
$ cd mecab-service/
$ sudo docker-compose up -d   

Méthode d'exécution

Requête HTTP

POST /mecab/v1/parse-ipadic
POST /mecab/v1/parse-neologd

En-tête de la demande

Content-Type: application/json

Demander un corps

{
  "sentence":Chaîne
}

Exemple d'exécution ipadic

$ curl -X POST http://localhost:5000/mecab/v1/parse-ipadic \
       -H "Content-type: application/json" \
       -d '{"sentence": "Programmation fonctionnelle"}'  | jq .
{
  "dict": "ipadic",
  "message": "Success",
  "results": [
    {
      "prototype": "une fonction",
      "Partie": "nom",
      "Sous-classification des paroles des parties 1": "Général",
      "Sous-classification des pièces détachées 2": "*",
      "Sous-classification des paroles des parties 3": "*",
      "Type d'utilisation": "*",
      "Type d'utilisation": "*",
      "prononciation": "Kansu",
      "Type de surface": "une fonction",
      "en train de lire": "Kansu"
    },
    {
      "prototype": "Moule",
      "Partie": "nom",
      "Sous-classification des paroles des parties 1": "suffixe",
      "Sous-classification des pièces détachées 2": "Général",
      "Sous-classification des paroles des parties 3": "*",
      "Type d'utilisation": "*",
      "Type d'utilisation": "*",
      "prononciation": "Jouer",
      "Type de surface": "Moule",
      "en train de lire": "Jouer"
    },
    {
      "prototype": "la programmation",
      "Partie": "nom",
      "Sous-classification des paroles des parties 1": "Changer de connexion",
      "Sous-classification des pièces détachées 2": "*",
      "Sous-classification des paroles des parties 3": "*",
      "Type d'utilisation": "*",
      "Type d'utilisation": "*",
      "prononciation": "la programmation",
      "Type de surface": "la programmation",
      "en train de lire": "la programmation"
    }
  ],
  "status": 200
}
 

Exemple d'exécution mecab-ipadic-neologd

mecab-ipadic-neologd est un dictionnaire fort contre la nomenclature appropriée.

$ curl -X POST http://localhost:5000/mecab/v1/parse-neologd \
       -H "Content-type: application/json" \
       -d '{"sentence": "Programmation fonctionnelle"}'  | jq .
{
  "dict": "neologd",
  "message": "Success",
  "results": [
    {
      "prototype": "Programmation fonctionnelle",
      "Partie": "nom",
      "Sous-classification des paroles des parties 1": "Nomenclature propriétaire",
      "Sous-classification des pièces détachées 2": "Général",
      "Sous-classification des paroles des parties 3": "*",
      "Type d'utilisation": "*",
      "Type d'utilisation": "*",
      "prononciation": "Programmation Kansugata",
      "Type de surface": "Programmation fonctionnelle",
      "en train de lire": "Programmation Kansugata"
    }
  ],
  "status": 200
}

À propos de la taille de l'image

L'image créée à partir de ce Dockerfile est le prochain mecabservice_api, ce qui est énorme par rapport à l'ubuntu d'origine.

$ sudo docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
mecabservice_api          latest              785bc1295e46        About an hour ago   3.375 GB
ubuntu                    16.04               c73a085dc378        4 days ago          127.1 MB

Voyons où il est devenu gonflé avec la sous-commande historique. Après tout, il semble que le fichier de dictionnaire soit très volumineux, mais ne peut-il pas être aidé?

$ sudo docker history mecabservice_api
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
785bc1295e46        About an hour ago   /bin/sh -c #(nop) CMD ["python3" "server.py"]   0 B
00339a58f77e        About an hour ago   /bin/sh -c pip3 install -r requirements.txt     5.852 MB
a397235a8e30        About an hour ago   /bin/sh -c #(nop) WORKDIR /opt/api              0 B
436ef40f928d        About an hour ago   /bin/sh -c #(nop) COPY dir:a4cb3a57cc1f117b07   2.445 kB
12456a11160d        3 hours ago         /bin/sh -c ./bin/install-mecab-ipadic-neologd   2.307 GB
18478e2f8d71        3 hours ago         /bin/sh -c #(nop) WORKDIR /opt/mecab/mecab-ip   0 B
74e6a0bffa98        3 hours ago         /bin/sh -c git clone --depth 1 https://github   114.2 MB
db6a7c716f21        3 hours ago         /bin/sh -c #(nop) WORKDIR /opt/mecab            0 B
6980af0a5afd        3 hours ago         /bin/sh -c ./configure --with-charset=utf8      106 MB
db32f32c58e6        3 hours ago         /bin/sh -c #(nop) WORKDIR /opt/mecab/mecab-ip   0 B
5745385f2342        3 hours ago         /bin/sh -c ./configure  --enable-utf8-only      11.16 MB
8c601b1fac00        3 hours ago         /bin/sh -c #(nop) WORKDIR /opt/mecab/mecab      0 B
d730397e47eb        3 hours ago         /bin/sh -c git clone https://github.com/taku9   378.8 MB
2abd825af064        3 hours ago         /bin/sh -c apt-get update   && apt-get instal   325 MB
d5abec2370fb        3 hours ago         /bin/sh -c #(nop) WORKDIR /opt                  0 B
c73a085dc378        4 days ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B

: memo: [2016/10/07 postscript] Mettre à jour automatiquement le dictionnaire de mecab-ipadic-neologd

J'ai remarqué que le dictionnaire de mecab-ipadic-neologd est mis à jour régulièrement sur le serveur. J'ai fait.

-Ce dictionnaire est mis à jour automatiquement sur le serveur de développement --Sera mis à jour au moins deux fois par semaine --Lundi et jeudi

De plus, la façon d'obtenir des mises à jour dans le dictionnaire post-installation est également fournie dans Officiel.

Il existe déjà des options utiles si vous souhaitez mettre à jour automatiquement, comme avec cron (non expliqué). Par exemple, si vous écrivez les deux lignes suivantes dans crontab etc., vous pouvez spécifier avec (-y) user author (-u) à 3h00 le mardi et vendredi sans vérifier le résultat de l'analyse> dans le répertoire (-) p [/ chemin / vers / utilisateur / répertoire]) Un fichier de dictionnaire est mis à jour.

    00 03 * * 2 ./bin/install-mecab-ipadic-neologd -n -y -u -p /path/to/user/directory > /path/to/log/file
    00 03 * * 5 ./bin/install-mecab-ipadic-neologd -n -y -u -p /path/to/user/directory > /path/to/log/file

Si vous souhaitez définir le conteneur en cours d'exécution sur mecabservice_api_1 et afficher le journal de mise à jour dans / opt / log / mecab, Vous pouvez le définir en vous connectant au conteneur avec bash comme indiqué ci-dessous.

$ sudo docker exec -it mecabservice_api_1 /bin/bash
# mkdir -p /opt/log/mecab
# (crontab -l 2>/dev/null; echo "PATH=$PATH") | crontab -
# (crontab -l 2>/dev/null; echo '00 18 * * 1 /opt/mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y >/opt/log/mecab/neologd_`date -I`.log 2>/opt/log/mecab/neologd_`date -I`.err') | crontab -
# (crontab -l 2>/dev/null; echo '00 18 * * 4 /opt/mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y >/opt/log/mecab/neologd_`date -I`.log 2>/opt/log/mecab/neologd_`date -I`.err') | crontab -
# /etc/init.d/cron restart
# exit

Ici, l'heure UTC est définie de manière à être mise à jour à 3h00 le mardi et le vendredi de l'heure JST. Par défaut, il est resté bloqué pendant un moment où mecab n'était pas inclus dans le PATH de crontab. De plus, au début, un bug mineur dans le shell ne fonctionnait pas avec les paramètres ci-dessus, mais j'ai lancé Issue and Pull Request. Dès que je l'ai fusionné, il a commencé à fonctionner (* ^^) v

: memo: [PostScript du 11/03/2018] Ajouter un frontal

Même si j'utilise docker-compose, je suis seul avec un seul service, j'ai donc ajouté une application Web qui appelle l'API REST ci-dessus du front-end à docker-compose. Voir github pour la source frontale. La communication entre les conteneurs et les paramètres CORS était bloquée.

docker-compose.yml

api:
  build: ./flask-mecab
  volumes:
    - "./flask-mecab:/opt/api"
  ports:
    - "5000:5000"
  restart: always
front:
  build: ./flask-mecab-front
  volumes:
    - "./flask-mecab-front:/opt/front"
  ports:
    - "5001:5001"
  restart: always
  links:
    - api
  environment:
    FLASK_MECAB_URI: "http://api:5000/mecab/v1"

Après le démarrage, accédez à http: // localhost: 5001 / avec votre navigateur.

capture d'écran

mecab.PNG

Recommended Posts

Dockerfile pour serveur RESTful MeCab avec mecab-ipadic-neologd
Serveur Web pour tester le navigateur avec Mocha
Serveur TFTP avec Docker
Utilisez mecab-ipadic-neologd avec igo-python
Utiliser mecab avec Python 3
Serveur proxy avec Docker
Serveur local avec python
Bibliothèque pour spécifier un serveur de noms en python et dig
Réduisons le travail requis pour la configuration du serveur avec Ansible