Extension:Math/RESTBase

From Linux Web Expert

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Configure Restbase to work with the Math extension

To install mathoid and restbase to work with the math extension the following steps are required:

Mathoid

npm i mathoid
cd node_modules/mathoid

edit config.yaml as follows

# Number of worker processes to spawn.
# Set to 0 to run everything in a single process without clustering.
# Use 'ncpu' to run as many workers as there are CPU units
num_workers: ncpu

# Log error messages and gracefully restart a worker if v8 reports that it
# uses more heap (note: not RSS) than this many mb.
worker_heap_limit_mb: 500

# Logger info
logging:
  level: warn

# Statsd metrics reporter
metrics:
  type: log
  #host: localhost
  #port: 8125

services:
  - name: mathoid
    # a relative path or the name of an npm package, if different from name
    module: ./app.js
    # optionally, a version constraint of the npm package
    # version: ^0.4.0
    # per-service config
    conf:
      port: 10042
      # interface: localhost # uncomment to only listen on localhost
      # more per-service config settings
      svg: true
      img: true
      png: true
      texvcinfo: true
      speech: true
      speech_on: false
      chem: true
      no_check: true

run mathoid as a screen session

screen
node server.js -c config.yaml

testing mathoid

Now the following test

curl -d 'q=E=mc^2' localhost:10042/mml

should return

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <semantics>
    <mrow>
      <mi>E</mi>
      <mo>=</mo>
      <mi>m</mi>
      <msup>
        <mi>c</mi>
        <mn>2</mn>
      </msup>
    </mrow>
    <annotation encoding="application/x-tex">E=mc^2</annotation>
  </semantics>
</math>

RESTBase

npm i restbase
cd node_modules/restbase

edit config.yaml as follows

paths:
  /{api:v1}:
    x-modules:
        # swagger options, overriding the shared ones from the merged specs (?)
      - spec:
          info:
            version: 1.0.0-beta
            title: Formulasearchengine REST API
            description: >
                This API aims to provide a preview of new features reagarding
                Math rendering and search, supposed to be integrated to
                the [wikimedia restbase api](https://wikimedia.org/api/rest_v1/?doc).

                ### High-volume access
                  - Don't perform more than 500 requests/s to this API.
                  - Set a unique `User-Agent` header that allows us to contact you
                    quickly. Email addresses or URLs of contact pages work well.

            termsOfService: https://wikimediafoundation.org/wiki/Terms_of_Use
            contact:
              name: the Wikimedia Services team
              url: http://mediawiki.org/wiki/RESTBase
            license:
              name: Apache2
              url: http://www.apache.org/licenses/LICENSE-2.0

          securityDefinitions: &wp/content-security/1.0.0
            mediawiki_auth:
              description: Checks permissions using MW api
              type: apiKey
              in: header
              name: cookie
              x-internal-request-whitelist:
                - /http:\/\/[a-zA-Z0-9\.]+\/w\/api\.php/
          # Override the base path for host-based (proxied) requests. In our case,
          # we proxy https://{domain}/api/rest_v1/ to the API.
          x-host-basePath: /api/rest_v1
          x-route-filters:
            - path: ./lib/normalize_title_filter.js
              options:
                redirect_cache_control: '{{options.purged_cache_control}}'
          paths:
            /media:
              x-modules:
                - path: v1/mathoid.yaml
                  options: '{{options.mathoid}}'
            /testing:
              x-modules:
                - path: ../mathpipe.yaml
                 # options: '{{options.mathoid}}'
        options: '{{options}}'

  /{api:sys}:
    x-modules:
      - spec:
          paths:
            /mathoid:
              x-modules:
                - path: sys/mathoid.js
                  options: '{{options.mathoid}}'
            /table:
              x-modules:
                - path: sys/table.js
                  options:
                    conf: '{{options.table}}'
            /key_value:
              x-modules:
                - path: sys/key_value.js
            /key_rev_value:
              x-modules:
                - path: sys/key_rev_value.js
            /key_rev_latest_value:
              x-modules:
                - path: sys/key_rev_latest_value.js
            /post_data: &sys_post_data
              x-modules:
                - path: sys/post_data.js
            /events:
              x-modules:
                - path: sys/events.js
                  options: '{{options.events}}'
        options: '{{options}}'

run restbase as a screen session

screen
node server.js -c config.yaml

testing restbase

Navigate to http://localhost:8081/wikimedia.org/v1/?doc you should be able to enter a texvc formula to the check command POST endpoing i.e. /media/math/check/{type} (See screenshot 1)[1] In the response headers you should find something like

"x-resource-location": "4c0004393a88f350a93bcef62106d556c7fc827b"

If you copy the value 4c0004393a88f350a93bcef62106d556c7fc827b and paste it to the GET endpoint /media/math/render/{format}/{hash} as value you should be able to see the PNG image if you select that as an output format. (See screenshot 2)[2]

Configuration Example for arbitrary domain in RESTBase setup

If you want to use domain other than wikimedia.org, you can follow below example;

  • mathoid/config.yaml
# Number of worker processes to spawn.
# Set to 0 to run everything in a single process without clustering.
# Use 'ncpu' to run as many workers as there are CPU units
num_workers: 0

# Log error messages and gracefully restart a worker if v8 reports that it
# uses more heap (note: not RSS) than this many mb.
worker_heap_limit_mb: 250

# Logger info
logging:
  level: trace
#  streams:
#  # Use gelf-stream -> logstash
#  - type: gelf
#    host: logstash1003.eqiad.wmnet
#    port: 12201

# Statsd metrics reporter
metrics:
  #type: log
  #host: localhost
  #port: 8125

services:
  - name: mathoid
    # a relative path or the name of an npm package, if different from name
    module: ./app.js
    # optionally, a version constraint of the npm package
    # version: ^0.4.0
    # per-service config
    conf:
      port: 10044
      # interface: localhost # uncomment to only listen on localhost
      # more per-service config settings
      # the location of the spec, defaults to spec.yaml if not specified
      # spec: ./spec.template.yaml
      # allow cross-domain requests to the API (default '*')
      #cors: '*'
      # to disable use:
      # cors: false
      # to restrict to a particular domain, use:
      # cors: restricted.domain.org
      # content for the CSP headers
      # csp: false  # uncomment this line to disable sending them
      # URL of the outbound proxy to use (complete with protocol)
      # proxy: http://my.proxy.org:8080
      # the list of domains for which not to use the proxy defined above
      # no_proxy_list:
      #   - domain1.com
      #   - domain2.org
      # the list of incoming request headers that can be logged; if left empty,
      # the following headers are allowed: cache-control, content-length,
      # content-type, if-match, user-agent, x-request-id
      # log_header_whitelist:
      #   - cache-control
      #   - content-length
      #   - content-type
      #   - if-match
      #   - user-agent
      #   - x-request-id
      # list of enabled renders
      svg: true
      img: true
      png: true #new feature
      speech: true #new feature
      texvcinfo: true
      speech_on: true
      no_check: false
      dpi: 180
      svgo: false
      # the user agent to use when issuing requests
      # user_agent: service-template-node
      # the template used for contacting the MW API
      #mwapi_req:
      #  method: post
      #  uri: https://{{domain}}/w/api.php
      #  headers:
      #    user-agent: '{{user-agent}}'
      #  body: '{{ default(request.query, {}) }}'
      # the template used for contacting RESTBase
      #restbase_req:
      #  method: '{{request.method}}'
      #  uri: https://{{domain}}/api/rest_v1/{+path}
      #  query: '{{ default(request.query, {}) }}'
      #  headers: '{{request.headers}}'
      #  body: '{{request.body}}'
  • restbase/config.yaml
services:
  - name: restbase
    module: hyperswitch
    conf:
      port: 7231
      salt: secret
      default_page_size: 125
      user_agent: RESTBase
      ui_name: RESTBase
      ui_url: https://www.mediawiki.org/wiki/RESTBase
      ui_title: RESTBase docs
      spec:
        x-request-filters:
          - path: lib/security_response_header_filter.js
        x-sub-request-filters:
          - type: default
            name: http
            options:
            allow:
              - pattern: http://localhost/api.php
                forward_headers: true
              - pattern: http://localhost:8000
                forward_headers: true
              - pattern: http://localhost:10044
                forward_headers: true
              - pattern: /^https?:\/\//
        paths:
          /{domain:localhost}: &arbitary_domain
            x-modules:
              - path: projects/MR.yaml
                options:
                  action:
                    # XXX Check API URL!
                    apiUriTemplate: http://localhost/api.php
                    # XXX Check the base RESTBase URI
                    baseUriTemplate: "{{'http://localhost:7231/{domain}/v1'}}"
                  parsoid:
                    # XXX Check Parsoid URL!
                    host: http://localhost:8000
                  mathoid:
                    # XXX Check Mathoid URL!
                    host: http://localhost:10044
                  table:
                    backend: sqlite
                    dbname: db.sqlite3
                    pool_idle_timeout: 20000
                    retry_delay: 250
                    retry_limit: 10
                    show_sql: false
          /{domain:your.some.domain}: *arbitary_domain

# Finally, a standard service-runner config.
info:
  name: restbase

logging:
  name: restbase
  level: info
  • restbase/project/MR.yaml
# will work with Mathoid on any {domain}
paths:
  /{api:v1}:
    x-modules:
        # swagger options, overriding the shared ones from the merged specs (?)
      - spec:
          info:
            version: 1.0.0
            title: Wikimedia REST API
            description: Welcome to your RESTBase API.
          #securityDefinitions: &wp/content-security/1.0.0
          #  mediawiki_auth:
          #    description: Checks permissions using MW api
          #    type: apiKey
          #    in: header
          #    name: cookie
          #    x-internal-request-whitelist:
          #      - /http:\/\/[a-zA-Z0-9\.]+\/w\/api\.php/
          # Override the base path for host-based (proxied) requests. In our case,
          # we proxy https://{domain}/api/rest_v1/ to the API.
          #x-host-basePath: /api/rest_v1
          x-route-filters:
            - path: ./lib/normalize_title_filter.js
              options:
                redirect_cache_control: '{{options.purged_cache_control}}'
          paths:
            /media:
              x-modules:
                - path: v1/mathoid.yaml
                  options: '{{options.mathoid}}'
            #/testing:
            #  x-modules:
            #    - path: ../mathpipe.yaml
                 # options: '{{options.mathoid}}'
            /page:
              x-modules:
                - path: v1/content.yaml
                  options:
                    purged_cache_control: '{{options.purged_cache_control}}'
                - path: v1/common_schemas.yaml # Doesn't really matter where to mount it.
            /transform:
              x-modules:
                - path: v1/transform.yaml
        options: '{{options}}'

  /{api:sys}:
    x-modules:
      - spec:
          paths:
            /mathoid:
              x-modules:
                - path: sys/mathoid.js
                  options: '{{options.mathoid}}'
            /table:
              x-modules:
                - path: sys/table.js
                  options:
                    conf: '{{options.table}}'
            /key_value:
              x-modules:
                - path: sys/key_value.js
            /key_rev_value:
              x-modules:
                - path: sys/key_rev_value.js
            /key_rev_latest_value:
              x-modules:
                - path: sys/key_rev_latest_value.js
            /post_data: &sys_post_data
              x-modules:
                - path: sys/post_data.js
            /events:
              x-modules:
                - path: sys/events.js
                  options: '{{options.events}}'
            /page_revisions:
              x-modules:
                - path: sys/page_revisions.js
            /action:
              x-modules:
                - path: sys/action.js
                  options: '{{options.action}}'
            /page_save:
              x-modules:
                - path: sys/page_save.js
            /parsoid:
              x-modules:
                - path: sys/parsoid.js
                  options:
                    parsoidHost: '{{options.parsoid.host}}'
                    response_cache_control: '{{options.purged_cache_control}}'
        options: '{{options}}'
  • restbase/v1/mathoid.yaml
# Mathoid - math formula rendering service :simply replaced /wikimedia.org/sys to /{domain}/sys
tags:
  - name: Math
    description: formula rendering
paths:
  /math/check/{type}:
    post:
      tags: ['Math']
      summary: Check and normalize a TeX formula.
      description: |
        Checks the supplied TeX formula for correctness and returns the
        normalised formula representation as well as information about
        identifiers. Available types are tex and inline-tex. The response
        contains the `x-resource-location` header which can be used to retrieve
        the render of the checked formula in one of the supported rendering
        formats. Just append the value of the header to `/media/math/{format}/`
        and perform a GET request against that URL.

        Stability: [stable](https://www.mediawiki.org/wiki/API_versioning#Stable).
      produces:
        - application/json
      parameters:
        - name: type
          in: path
          description: The input type of the given formula; can be tex or inline-tex
          type: string
          required: true
          enum:
            - tex
            - inline-tex
            - chem
        - name: q
          in: formData
          description: The formula to check
          type: string
          required: true
      responses:
        '200':
          description: Information about the checked formula
        '400':
          description: Invalid type
          schema:
            $ref: '#/definitions/problem'
        default:
          description: Error
          schema:
            $ref: '#/definitions/problem'
      x-monitor: true
      x-amples:
        - title: Mathoid - check test formula
          request:
            params:
              domain: wikimedia.org
              type: tex
            body:
              q: E=mc^{2}
          response:
            status: 200
            headers:
              content-type: /^application\/json/
              x-resource-location: /.+/
              cache-control: 'no-cache'
            body:
              success: true
              checked: /.+/
      x-request-handler:
        - get_from_sys:
            request:
              method: post
              uri: /{domain}/sys/mathoid/check/{type}
              headers: '{{ request.headers }}'
              body: '{{ request.body }}'

  /math/formula/{hash}:
    get:
      tags: ['Math']
      summary: Get a previously-stored formula
      description: |
        Returns the previously-stored formula via `/media/math/check/{type}` for
        the given hash.

        Stability: [stable](https://www.mediawiki.org/wiki/API_versioning#Stable).
      produces:
        - application/json
      parameters:
        - name: hash
          in: path
          description: The hash string of the previous POST data
          type: string
          required: true
          minLength: 1
      responses:
        '200':
          description: Information about the checked formula
        '404':
          description: Data for the given hash cannot be found
          schema:
            $ref: '#/definitions/problem'
        default:
          description: Error
          schema:
            $ref: '#/definitions/problem'
      x-monitor: false
      x-request-handler:
        - get_from_sys:
            request:
              method: get
              uri: /{domain}/sys/mathoid/formula/{hash}
              headers: '{{ request.headers }}'

  /math/render/{format}/{hash}:
    get:
      tags: ['Math']
      summary: Get rendered formula in the given format.
      description: |
        Given a request hash, renders a TeX formula into its mathematic
        representation in the given format. When a request is issued to the
        `/media/math/check/{format}` POST endpoint, the response contains the
        `x-resource-location` header denoting the hash ID of the POST data. Once
        obtained, this endpoint has to be used to obtain the actual render.

        Stability: [stable](https://www.mediawiki.org/wiki/API_versioning#Stable).
      produces:
        - image/svg+xml
        - application/mathml+xml
        - image/png
      parameters:
        - name: format
          in: path
          description: The output format; can be svg or mml
          type: string
          required: true
          enum:
            - svg
            - mml
            - png
        - name: hash
          in: path
          description: The hash string of the previous POST data
          type: string
          required: true
          minLength: 1
      responses:
        '200':
          description: The rendered formula
        '404':
          description: Unknown format or hash ID
          schema:
            $ref: '#/definitions/problem'
        default:
          description: Error
          schema:
            $ref: '#/definitions/problem'
      x-monitor: false
      x-setup-handler:
        - init_svg:
            uri: /{domain}/sys/key_value/mathoid.svg
            body:
              keyType: string
              valueType: string
        - init_mml:
            uri: /{domain}/sys/key_value/mathoid.mml
            body:
              keyType: string
              valueType: string
        - init_png:
            uri: /{domain}/sys/key_value/mathoid.png
            body:
              keyType: string
              valueType: blob
      x-request-handler:
        - check_storage:
            request:
              method: get
              uri: /{domain}/sys/key_value/mathoid.{$.request.params.format}/{$.request.params.hash}
              headers:
                cache-control: '{{ cache-control }}'
            catch:
              status: 404
            return_if:
              status: '2xx'
            return:
              status: 200
              headers: "{{ merge({ 'cache-control': options.cache-control }, check_storage.headers) }}"
              body: '{{ check_storage.body }}'
        - postdata:
            request:
              uri: /{domain}/sys/mathoid/formula/{request.params.hash}
        - mathoid:
            request:
              method: post
              uri: /{domain}/sys/mathoid/render/{request.params.format}
              headers:
                content-type: application/json
                x-resource-location: '{{ request.params.hash }}'
              body: '{{postdata.body}}'
  • Apache proxy config : /etc/httpd/conf.d/restbase.conf
#
# Restbase
#

<VirtualHost *:80>
          ProxyPreserveHost On

          ProxyPass /your.some.domain/ http://localhost:7231/your.some.domain/
          ProxyPassReverse /your.some.domain/ http://localhost:7231/your.some.domain/

          ProxyPass /localhost/ http://localhost:7231/localhost/
          ProxyPassReverse /localhost/ http://localhost:7231/localhost/

          # MediaWiki is located here:
          DocumentRoot /var/www/html
 </VirtualHost>

you can test the APIs at http://your.some.domain/your.some.domain/v1/

setup apache proxy

To load the images from the same location where the main wiki site is hosted a simple apache proxy can be used. Enable apache mod proxy ... and then add a config file along the lines of this file

cat /etc/apache2/sites-available/restbase.conf
<VirtualHost *:80>
    ServerName  restbase.formulasearchengine.com
    ServerAlias api.formulasearchengine.com png.formulasearchengine.com
    ServerAdmin wiki@physikerwelt.de
    ProxyPreserveHost On
    ProxyPass /v1/ http://localhost:8081/wikimedia.org/v1/
    ProxyPass /wikimedia.org/v1/ http://localhost:8081/wikimedia.org/v1/
</VirtualHost>
a2ensite restbase.conf

You can use letsencrypt to also generate a HTTPS version for that site.

Helpful commands to check the state of the database

Clean cache

run cqlsh

use "local_group_default_T_mathoid_svg";
truncate data;
truncate meta;
use "local_group_default_T_mathoid_mml";
truncate data;
truncate meta;
use "local_group_default_T_mathoid_input";
truncate data;
truncate meta;
use "local_group_default_T_mathoid_png";
truncate data;
truncate meta;

Browse the data

Task retrieve the input given a key ... in this example we'll use 0f7fa7bb7d214c60f8d2f0b8d356c41bfe5c5d1d as key run cqlsh

use "local_group_test_T_mathoid_input";
SELECT * from data WHERE key = '0f7fa7bb7d214c60f8d2f0b8d356c41bfe5c5d1d' and "_domain" = 'wikimedia.org';
 _domain       | key                                      | tid                                  | _del | content-location | content-sha256 | content-type     | headers                             |latestTid | tags | value
 ---------------+------------------------------------------+--------------------------------------+------+------------------+----------------+------------------+-------------------------------------+-----------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------
 wikimedia.org | 0f7fa7bb7d214c60f8d2f0b8d356c41bfe5c5d1d | e736aba4-9edc-11e5-927a-301f88a60cb9 | null |             null |           null | application/json | {"content-type":"application/json"} |      null | null | {"q":"=nf(x)\\left({n-1 \\choose k-1}F(x)^{k-1}(1-F(x))^{(n-1)-(k-1)}-\\underbrace {{n-1 \\choose n}F(x)^{n}(1-F(x))^{(n-1)-n}} \\right)","type":"inline-tex"}