示例#1
0
def to_json_schema(obj, mode: UpdateMode, schema: Optional[Schema] = None):
    """Create JSON schema based on an object.

    Arguments:
        obj {dict} -- Dictionary object

    Keyword Arguments:
        schema {dict} -- Existing schema if exists. (default: {None})

    Returns:
        [dict] -- New or updated schema.
    """
    if schema is not None:
        schema = convert_from_openapi(schema)
    if mode == UpdateMode.GEN:
        builder = SchemaBuilder()
        if schema is not None:
            builder.add_schema(schema)
        builder.add_object(obj)
        out = builder.to_schema()
        return out
    elif schema is None:
        return {"oneOf": [to_const(obj)]}
    else:
        return {"oneOf": [to_const(obj), schema]}
示例#2
0
def path_parameter_match(
    part: str, vname: str, path_item: PathItem, operation: str, oas: OpenAPIObject,
) -> bool:
    """Matches part of a path against a path parameter with name vname

    Arguments:
        part {str} -- part of a path, ie an id
        vname {str} -- name of a parameter
        path_item {PathItem} -- a path item maybe containing the parameter
        operation {MethodNames} -- the name of the operation to check in case the parameter is in the operation
        oas {OpenAPIObject} -- the schema to traverse to find definitions

    Returns:
        bool -- Did we get a match
    """
    return reduce(
        lambda q, r: q
        and reduce(
            lambda a, b: a
            or valid_schema(
                b,
                {
                    **convert_from_openapi(r),
                    "definitions": make_definitions_from_spec(oas),
                },
            ),
            list(set([part, maybeJson(part)])),
            False,
        ),
        get_matching_parameters(vname, path_item, operation, oas),
        True,
    )
示例#3
0
 def _keep_method_if_required_request_body_is_present(
         p: PathItem) -> PathItem:
     out = (
         p if (operation_from_string(p, req.method.value) is None
               ) or (len([
                   s for s in get_required_request_body_schemas(
                       req, oai, p) if not valid_schema(
                           req.bodyAsJson if req.bodyAsJson is not None
                           else json.loads(req.body) if req.body is not None
                           else "",
                           {
                               # TODO: this line is different than the TS implementation
                               # because I think there is a logic bug there
                               # it should look like this line as we are not sure
                               # if the schema will be a reference or not
                               # perhaps I'm wrong in the assumption... only testing will tell...
                               # otherwise, change the TS implementation in unmock-js and delete this comment.
                               **convert_from_openapi(
                                   change_ref(s) if isinstance(
                                       s, Reference) else change_refs(s)),
                               "definitions":
                               make_definitions_from_schema(oai),
                           },
                       )
               ]) == 0) else omit_method_from_path_item(
                   p, req.method.value))
     return out
示例#4
0
 def _build_full_schema(self, schema: typing.Union[Schema, Reference],
                        definitions: typing.Any) -> typing.Dict:
     return {
         **convert_from_openapi(
             change_ref(schema) if isinstance(schema, Reference) else change_refs(schema)),
         "definitions":
         definitions,
     }
示例#5
0
def _json_schema_from_required_parameters(
    parameters: Sequence[Parameter], oai: OpenAPIObject
) -> Any:
    return {
        "type": "object",
        "properties": {
            param.name: convert_from_openapi(param.schema) for param in parameters
        },
        "required": [param.name for param in parameters if param.required],
        "additionalProperties": True,
        "definitions": make_definitions_from_spec(oai),
    }
示例#6
0
 def _build_full_schema(
     self, schema: typing.Union[Schema, Reference], spec: OpenAPIObject
 ) -> typing.Dict:
     return {
         **convert_from_openapi(
             change_ref(schema)
             if isinstance(schema, Reference)
             else change_refs(schema)
         ),
         "definitions": {
             k: convert_from_openapi(
                 change_ref(v) if isinstance(v, Reference) else change_refs(v)
             )
             for k, v in (
                 spec.components.schemas.items()
                 if (spec.components is not None)
                 and (spec.components.schemas is not None)
                 else []
             )
         },
     }
示例#7
0
def test_request_logging_mixed_append(tmp_dir):
    specs_dir = os.path.join(tmp_dir, "specs")
    spec_path = os.path.join(specs_dir, "another.api.com_mixed.json")
    os.makedirs(specs_dir)
    with open(spec_path, "w") as f:
        json.dump(convert_from_openapi(BASE_SCHEMA), f)

    with open(spec_path) as f:
        spec = convert_to_openapi(json.load(f))
        assert spec.servers is None

    request = RequestBuilder.from_dict(
        dict(
            method="get",
            host="another.api.com",
            pathname="/echo",
            query={"message": "Hello"},
            body="",
            bodyAsJson={},
            path="/echo",
            protocol="http",
            headers={},
        ))
    response = ResponseBuilder.from_dict(
        dict(
            statusCode=200,
            body='{"message": "hello"}',
            bodyAsJson={"message": "hello"},
            headers={},
        ))

    log_dir = os.path.join(tmp_dir, "logs")
    with RequestLoggingCallback(log_dir=log_dir,
                                specs_dir=specs_dir,
                                update_mode=UpdateMode.MIXED) as data_callback:
        data_callback.log(request, response)

    assert os.path.exists(
        os.path.join(log_dir, "another.api.com-recordings.jsonl"))
    assert os.path.exists(spec_path)

    with open(spec_path) as f:
        spec = convert_to_openapi(json.load(f))

    assert "http://another.api.com" == spec.servers[0].url
示例#8
0
文件: entity.py 项目: wilsonify/hmt
 def _build_request_entity_selectors(self,
                                     path_item: PathItem) -> typing.Dict:
     res = {}
     for method_name in self.methods:
         method: Operation = getattr(path_item, method_name)
         operation = (
             ApiOperation.UNKNOWN if method is None else ApiOperation(
                 get_x(method, "x-hmt-operation", ApiOperation.UNKNOWN)))
         if operation == ApiOperation.UPSERT or operation == ApiOperation.INSERT:
             request_body = typing.cast(RequestBody, method.requestBody)
             if "application/json" in request_body.content:
                 schema = request_body.content["application/json"].schema
                 if schema is not None:
                     entity_path = self._find_entity(
                         convert_from_openapi(schema), "$")
                     if res is not None:
                         res[method_name] = parse(entity_path)
     return res
示例#9
0
    def log(self, request: Request, response: Response):
        RequestBuilder.validate(request)
        ResponseBuilder.validate(response)

        host = request.host
        reqres = HttpExchange(request=request, response=response)
        if host not in self._logs:
            log_file = os.path.join(self._log_dir,
                                    "{}-recordings.jsonl".format(host))
            if self._append and os.path.exists(log_file):
                self._logs[host] = open(log_file, "a")
            else:
                self._logs[host] = open(log_file, "w")

        HttpExchangeWriter(self._logs[host]).write(reqres)
        self._logs[host].flush()

        logger.debug("Logs for %s were updated", host)

        if self._update_mode:
            spec_file = os.path.join(
                self._specs_dir,
                "{}_{}.json".format(host, self._update_mode.name.lower()),
            )

            if host not in self._specs:
                if os.path.exists(spec_file) and self._append:
                    with open(spec_file, "r") as f:
                        self._specs[host] = convert_to_openapi(json.load(f))
                else:
                    self._specs[host] = BASE_SCHEMA

            self._specs[host] = update_openapi(self._specs[host], reqres,
                                               self._update_mode)

            with open(spec_file, "w") as f:
                spec = convert_from_openapi(self._specs[host])
                json.dump(spec, f)
                f.flush()

            logger.debug("Schema for %s was updated", host)
示例#10
0
    def spew(
        self, request: Request, specs: Sequence[OpenAPISpecification]
    ) -> Sequence[OpenAPISpecification]:
        if len(self._endpoints) == 0:
            return specs

        req = HttpExchangeWriter.to_dict(request)
        cs = {spec.source: convert_from_openapi(spec.api) for spec in specs}
        for endpoint in self._endpoints:
            res = requests.post(endpoint, json={"request": req, "schemas": cs})
            cs = res.json()

        out = [
            OpenAPISpecification(convert_to_openapi(dict_spec), name)
            for name, dict_spec in cs.items()
        ]

        for spec in out:
            self._mock_data_store.add_mock(spec)

        return out
示例#11
0
def write_build_result(directory: str, result: BuildResult) -> None:
    """Write builder result to a directory.

    Arguments:
        directory {str} -- Directory where to write results, possibly relative.
        result {BuildResult} -- Builder result.
    """
    output_dir_path = _resolve_path(directory)
    LOGGER.info("Writing to folder %s.", str(output_dir_path))

    _ensure_dir_exists(output_dir_path)

    openapi_output = output_dir_path / OPENAPI_FILENAME

    openapi_object = result["openapi"]

    schema_json = cast(str, json.dumps(convert_from_openapi(openapi_object), indent=2))

    with openapi_output.open("wb") as f:
        LOGGER.debug("Writing to: %s\n", str(openapi_output))
        f.write(schema_json.encode(encoding="utf-8"))
示例#12
0
def validate_body(req: Request, spec: OpenAPISpecification, op: Operation) -> bool:
    request_body = get_request_body(spec.api, op.requestBody)
    if (
        request_body is not None
        and "application/json" in request_body.content
        and request_body.content["application/json"].schema
    ):
        schema = cast(
            Union[Schema, Reference], request_body.content["application/json"].schema
        )
        return valid_schema(
            req.bodyAsJson,
            {
                **convert_from_openapi(
                    change_ref(schema)
                    if isinstance(schema, Reference)
                    else change_refs(schema)
                ),
                "definitions": spec.definitions,
            },
        )

    return True
示例#13
0
def make_definitions_from_spec(o: OpenAPIObject) -> Mapping[str, Any]:
    return ({
        a: convert_from_openapi(
            change_ref(b) if isinstance(b, Reference) else change_refs(b))
        for a, b in o.components.schemas.items()
    } if o.components and o.components.schemas else {})
示例#14
0
def write_base_schema(target_file: str, schema: OpenAPIObject):
    with open(target_file, "w") as f:
        f.write(json.dumps(convert_from_openapi(schema)))