Exemple #1
0
async def handle_list_models(
        request: aiohttp.web.Request) -> aiohttp.web.Response:
    """List cached models.

    ---
    get:
      description: List cached models.
      produces:
        - application/json
      responses:
        "200":
          description: Identifier for compiled Stan model and compiler output.
          schema: Model
          schema:
            type: object
            properties:
              models:
                type: array
                items: Model
    """

    models = []
    for model_name in httpstan.cache.list_model_names():
        compiler_output = httpstan.cache.load_services_extension_module_compiler_output(
            model_name)
        stanc_warnings = httpstan.cache.load_stanc_warnings(model_name)
        models.append(schemas.Model().load({
            "name": model_name,
            "compiler_output": compiler_output,
            "stanc_warnings": stanc_warnings
        }))
    return aiohttp.web.json_response({"models": models}, status=200)
Exemple #2
0
def test_model_schema() -> None:
    result = schemas.Model().load({
        "name": "12345",
        "compiler_output": "",
        "stanc_warnings": ""
    })
    assert result
Exemple #3
0
async def handle_create_model(
        request: aiohttp.web.Request) -> aiohttp.web.Response:
    """Compile Stan model.

    ---
    post:
      description: Compile a Stan model
      consumes:
        - application/json
      produces:
        - application/json
      parameters:
        - in: body
          name: body
          description: Stan program code to compile
          required: true
          schema: CreateModelRequest
      responses:
        "201":
          description: Identifier for compiled Stan model and compiler output.
          schema: Model
        "400":
          description: Error associated with compile request.
          schema: Status

    """
    args = cast(
        dict, await
        webargs.aiohttpparser.parser.parse(schemas.CreateModelRequest(),
                                           request))

    program_code = args["program_code"]
    model_name = httpstan.models.calculate_model_name(program_code)

    # check if extension module is present in cache
    try:
        httpstan.models.import_services_extension_module(model_name)
    except KeyError:
        pass
    else:
        logger.info(f"Found Stan model in cache (`{model_name}`).")
        compiler_output = httpstan.cache.load_services_extension_module_compiler_output(
            model_name)
        stanc_warnings = httpstan.cache.load_stanc_warnings(model_name)
        response_dict = schemas.Model().load({
            "name": model_name,
            "compiler_output": compiler_output,
            "stanc_warnings": stanc_warnings
        })
        return aiohttp.web.json_response(response_dict, status=201)

    # extension module is not in cache

    # clean the directory in which the model will be compiled.
    httpstan.cache.delete_model_directory(model_name)

    # compile `program_code` to check for fatal errors. If none, save stanc warnings
    stan_model_name = f"model_{model_name.split('/')[1]}"  # stan name cannot start with number
    try:
        _, stanc_warnings = httpstan.compile.compile(program_code,
                                                     stan_model_name)
    except ValueError as exc:
        message, status = f"Exception while compiling `program_code`: `{repr(exc)}`", 400
        logger.critical(message)
        return aiohttp.web.json_response(_make_error(message, status=status),
                                         status=status)
    httpstan.cache.dump_stanc_warnings(stanc_warnings, model_name)

    # no fatal stanc errors, continue
    logger.info(
        f"Building model-specific services extension module for `{model_name}`."
    )
    try:
        # `build_services_extension_module` has side-effect of storing extension module in cache
        compiler_output = await httpstan.models.build_services_extension_module(
            program_code)
    except Exception as exc:  # pragma: no cover
        message, status = (
            f"Exception while building model extension module: `{repr(exc)}`, traceback: `{traceback.format_tb(exc.__traceback__)}`",
            400,
        )
        logger.critical(message)
        return aiohttp.web.json_response(_make_error(message, status=status),
                                         status=status)
    httpstan.cache.dump_services_extension_module_compiler_output(
        compiler_output, model_name)
    response_dict = schemas.Model().load({
        "name": model_name,
        "compiler_output": compiler_output,
        "stanc_warnings": stanc_warnings
    })
    return aiohttp.web.json_response(response_dict, status=201)