コード例 #1
0
def test_matcher():
    _bfoo = {
        "parameters": [
            {
                "in": "path",
                "name": "foo",
                "schema": {"type": "string", "pattern": "^[abc]+$"},
            },
        ],
        "get": {
            "responses": {
                "200": {"description": "some", "content": {"application/json": {}},}
            }
        },
    }
    bfoo = convert_to_PathItem(_bfoo)
    oai: OpenAPIObject = convert_to_openapi(
        {
            "openapi": "",
            "info": {"title": "", "version": ""},
            "paths": {"/b/{foo}": _bfoo},
        }
    )
    assert matches(["a", "b"], "/a/b", bfoo, "get")
    assert not matches(["a"], "/a/b", bfoo, "get")
    assert not matches(["a", "b"], "/a", bfoo, "get")
    assert matches(["a", "b", "c"], "/a/{fewfwef}/c", bfoo, "get")
    assert matches(["b", "ccaaca"], "/b/{foo}", bfoo, "get")
    assert matches(["b", "ccaaca"], "/b/{foo}", bfoo, "get")
    assert not matches(["a", "b", "c"], "/a/{fewfwef}/c", bfoo, "post")
コード例 #2
0
ファイル: __main__.py プロジェクト: wilsonify/hmt
def build(input_file, out, initial_openapi_spec, mode, source):
    """
    Build an OpenAPI specification from HTTP recordings.
    """

    if input_file is not None and source != "file":
        raise Exception("Only specify input-file for --source file")

    sinks = [FileSystemSink(out)]

    if source == "kafka":
        # TODO Kafka configuration
        source = KafkaSource(
            config=KafkaSourceConfig(broker="localhost:9092", topic="http_recordings")
        )
    elif source == "file":
        if input_file is None:
            raise Exception("Option --input-file for source 'file' required.")
        source = FileSource(input_file)
    else:
        raise Exception("Unknown source {}".format(source))

    openapi_spec: OpenAPIObject = BASE_SCHEMA

    if initial_openapi_spec is not None:
        try:
            maybe_openapi = safe_load(initial_openapi_spec.read())
            # will raise if not an API spec
            openapi_spec = convert_to_openapi(maybe_openapi)
        except Exception:
            pass  # just use the initial schema
    run_from_source(source, UpdateMode[mode.upper()], openapi_spec, sinks=sinks)
コード例 #3
0
def test_match_urls():
    assert ["https://api.foo.com"] == match_urls(
        "https",
        "api.foo.com",
        convert_to_openapi(
            {
                "openapi": "",
                "paths": {},
                "info": {"title": "", "version": ""},
                "servers": [
                    {"url": "https://api.foo.commm/v2"},
                    {"url": "https://api.foo.com"},
                ],
            }
        ),
    )
    assert ["https://api.foo.com/v2/a/b/c"] == match_urls(
        "https",
        "api.foo.com",
        convert_to_openapi(
            {
                "openapi": "",
                "paths": {},
                "info": {"title": "", "version": ""},
                "servers": [
                    {"url": "https://api.foo.commm/v2"},
                    {"url": "https://api.foo.com/v2/a/b/c"},
                ],
            }
        ),
    )
    assert [] == match_urls(
        "https",
        "api.foo.com/v2",
        convert_to_openapi(
            {
                "openapi": "",
                "paths": {},
                "info": {"title": "", "version": ""},
                "servers": [
                    {"url": "https://api.foo.commm/v2"},
                    {"url": "https://api.foo.cooom/v2"},
                ],
            }
        ),
    )
コード例 #4
0
ファイル: test_data_callback.py プロジェクト: wilsonify/hmt
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
コード例 #5
0
ファイル: specs.py プロジェクト: wilsonify/hmt
def load_spec(spec_source: str, is_http: bool) -> OpenAPISpecification:
    spec_text: str
    if is_http:
        try:
            response = requests.get(spec_source)
            spec_text = response.text
        except RequestException:
            raise Exception(f"Failed to load {spec_source}")
    else:
        with open(spec_source, encoding="utf8") as spec_file:
            spec_text = spec_file.read()

    spec = convert_to_openapi((json.loads if spec_source.endswith("json") else
                               yaml.safe_load)(spec_text))
    return OpenAPISpecification(spec, spec_source,
                                make_definitions_from_spec(spec))
コード例 #6
0
ファイル: data_callback.py プロジェクト: wilsonify/hmt
    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)
コード例 #7
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
コード例 #8
0
def test_matcher():
    _bfoo = {
        "parameters": [
            {
                "in": "path",
                "name": "foo",
                "schema": {"type": "string", "pattern": "^[abc]+$"},
            },
        ],
    }
    bfoo = convert_to_PathItem(_bfoo)
    oai: OpenAPIObject = convert_to_openapi(
        {
            "openapi": "",
            "info": {"title": "", "version": ""},
            "paths": {"/b/{foo}": _bfoo},
        }
    )
    assert matches("/a/b", "/a/b", bfoo, "get", oai)
    assert not matches("/a/", "/a/b", bfoo, "get", oai)
    assert not matches("/a/b", "/a", bfoo, "get", oai)
    assert matches("/a/b/c", "/a/{fewfwef}/c", bfoo, "get", oai)
    assert matches("/b/ccaaca", "/b/{foo}", bfoo, "get", oai)
    assert not matches("/b/ccaacda", "/b/{foo}", bfoo, "get", oai)
コード例 #9
0
ファイル: test_matcher.py プロジェクト: wilsonify/hmt
 convert_to_openapi({
     "openapi": "",
     "servers": [{
         "url": "api.foo.com"
     }],  # we omit the protocol and it should still match
     "info": {
         "title": "",
         "version": ""
     },
     "paths": {
         "/user": {
             "get": {
                 "responses": {
                     "200": {
                         "description": "userget"
                     }
                 }
             },
             "post": {
                 "responses": {
                     "200": {
                         "description": "userpost"
                     }
                 }
             },
             "description": "",
         },
         "/user/{id}": {
             "parameters": [
                 {
                     "name": "id",
                     "in": "path",
                     "required": True,
                     "schema": {
                         "type": "integer"
                     },
                 },
             ],
             "get": {
                 "responses": {
                     "200": {
                         "description": "useridget"
                     }
                 }
             },
             "post": {
                 "responses": {
                     "201": {
                         "description": "useridpost"
                     }
                 }
             },
         },
         "/user/{id}/name": {
             "get": {
                 "responses": {
                     "200": {
                         "description": "useridnameget"
                     }
                 }
             },
             "post": {
                 "responses": {
                     "201": {
                         "description": "useridnamepost"
                     }
                 }
             },
             "description": "",
         },
     },
 }),
コード例 #10
0
    assert not matches(["a"], "/a/b", bfoo, "get")
    assert not matches(["a", "b"], "/a", bfoo, "get")
    assert matches(["a", "b", "c"], "/a/{fewfwef}/c", bfoo, "get")
    assert matches(["b", "ccaaca"], "/b/{foo}", bfoo, "get")
    assert matches(["b", "ccaaca"], "/b/{foo}", bfoo, "get")
    assert not matches(["a", "b", "c"], "/a/{fewfwef}/c", bfoo, "post")


def test_ref_name():
    assert "Foo" == ref_name(Reference(_ref="#/components/schemas/Foo", _x=None))


baseO: OpenAPIObject = convert_to_openapi(
    {
        "openapi": "hello",
        "info": {"title": "", "version": ""},
        "servers": [{"url": "https://hello.api.com"}],
        "paths": {},
    }
)


# def test_use_if_header():
#     assert (
#         use_if_header(baseO, convert_to_Parameter({"name": "foo", "in": "query"}))
#         is None
#     )
#     assert use_if_header(
#         baseO, convert_to_Parameter({"name": "foo", "in": "header"})
#     ) == ("foo", convert_to_Schema({"type": "string"}))
#     assert use_if_header(
#         baseO,
コード例 #11
0
ファイル: test_paths.py プロジェクト: wilsonify/hmt
def schema():
    with open("tests/build/schemas/petstore/index.yaml", "r") as f:
        oas = convert_to_openapi(safe_load(f.read()))
        return oas