Source code for mira.dkg.metaregistry.utils

"""Constants for the MIRA Metaregistry."""

import json
import os
from pathlib import Path
from typing import Union

import bioregistry
import bioregistry.app.impl
import pystow
from bioregistry import Collection, Manager, Resource
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from flask import Flask

from mira.dkg.models import Config

__all__ = ["get_app"]


def parse_config(path: Path) -> Config:
    k = json.loads(path.read_text())
    return Config(
        web=k["web"],
        registry={
            prefix: Resource(prefix=prefix, **value) for prefix, value in k["registry"].items()
        },
        collections={
            collection: Collection(**data) for collection, data in k.get("collections", {})
        },
    )


def simple(env, resp):
    """A simple mock root endpoint to mount another flask app to"""
    resp('200 OK', [('Content-Type', 'text/plain')])
    return [b'Metaregistry root']


[docs]def get_app( config: Union[None, str, Path, Config] = None, root_path: str = "", client_base_url: str = "", ) -> Flask: """Get the MIRA metaregistry app.""" if config is None: config_path = Path( os.getenv("MIRA_REGISTRY_CONFIG") or pystow.get_config("mira", "registry_config", raise_on_missing=True) ) config = parse_config(config_path) elif isinstance(config, (str, Path)): config = parse_config(config) manager = Manager( registry=config.registry, collections=config.collections, contexts={} ) if client_base_url: # fixme: Set this better when the http-banana in bioregistry is fixed manager.base_url = client_base_url app = bioregistry.app.impl.get_app(manager=manager, config=config.web) if root_path: # Set basePath for swagger to know where to send example requests if app.swag.template is None: app.swag.template = {} app.swag.template["basePath"] = root_path # Follows # https://stackoverflow.com/a/18967744/10478812 and # https://gist.github.com/svieira/3434cbcaf627e50a4808 app.config['APPLICATION_ROOT'] = root_path # 'simple' becomes the root and the actual app is served at root_path app.wsgi_app = DispatcherMiddleware(simple, mounts={root_path: app.wsgi_app}) return app