Extension:Math/RESTBase
Configure Restbase to work with the Math extension
[edit]To install mathoid and restbase to work with the math extension the following steps are required:
Mathoid
[edit]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
[edit]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
[edit]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
[edit]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
[edit]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
[edit]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
[edit]Clean cache
[edit]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
[edit]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"}