def mock_generate_sample(*args, **kwargs):
    dummy_snippet_metadata = snippet_metadata_pb2.Snippet()
    dummy_snippet_metadata.client_method.method.service.short_name = args[0][
        "service"].split(".")[-1]
    dummy_snippet_metadata.client_method.method.short_name = args[0]['rpc']

    return "", dummy_snippet_metadata
Exemple #2
0
def generate_sample(sample, api_schema, sample_template: jinja2.Template) -> Tuple[str, Any]:
    """Generate a standalone, runnable sample.

    Writing the rendered output is left for the caller.

    Args:
        sample (Any): A definition for a single sample.
        api_schema (api.API): The schema that defines the API to which the sample belongs.
        sample_template (jinja2.Template): The template representing a generic sample.

    Returns:
        Tuple(str, snippet_metadata_pb2.Snippet): The rendered sample.
    """
    service_name = sample["service"]
    service = api_schema.services.get(service_name)
    if not service:
        raise types.UnknownService("Unknown service: {}", service_name)

    rpc_name = sample["rpc"]
    rpc = service.methods.get(rpc_name)
    if not rpc:
        raise types.RpcMethodNotFound(
            "Could not find rpc in service {}: {}".format(
                service_name, rpc_name)
        )

    calling_form = types.CallingForm.method_default(rpc)

    v = Validator(rpc, api_schema)
    # Tweak some small aspects of the sample to set defaults for optional
    # fields, add fields that are required for the template, and so forth.
    v.preprocess_sample(sample, api_schema, rpc)
    sample["request"] = v.validate_and_transform_request(
        calling_form, sample["request"]
    )

    v.validate_response(sample["response"])

    # Snippet Metadata can't be fully filled out in any one function
    # In this function we add information from
    # the API schema and sample dictionary.
    snippet_metadata = snippet_metadata_pb2.Snippet()  # type: ignore
    snippet_metadata.region_tag = sample["region_tag"]
    setattr(snippet_metadata.client_method, "async",
            sample["transport"] == api.TRANSPORT_GRPC_ASYNC)
    snippet_metadata.client_method.method.short_name = sample["rpc"]
    snippet_metadata.client_method.method.service.short_name = sample["service"].split(
        ".")[-1]

    return sample_template.render(
        sample=sample,
        imports=[],
        calling_form=calling_form,
        calling_form_enum=types.CallingForm,
        trim_blocks=True,
        lstrip_blocks=True,
    ), snippet_metadata
Exemple #3
0
def test_add_snippet_no_matching_service(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Clam"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    # No 'Clam' service in API Schema
    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={"Squid": DummyService(name="Squid", methods={})}))
    with pytest.raises(types.UnknownService):
        index.add_snippet(snippet)
Exemple #4
0
def test_add_snippet_no_matching_rpc(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    # No 'classify' method in 'Squid' service
    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={"Squid": DummyService(name="Squid", methods={"list": None})
                  }))
    with pytest.raises(types.RpcMethodNotFound):
        index.add_snippet(snippet)
Exemple #5
0
def test_get_metadata_json(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={
            "Squid":
            DummyService(name="Squid", methods={"classify": DummyMethod()})
        }))

    index.add_snippet(snippet)

    assert json.loads(index.get_metadata_json()) == {
        'snippets': [{
            'clientMethod': {
                'method': {
                    'shortName': 'classify',
                    'service': {
                        'shortName': 'Squid'
                    }
                }
            },
            'segments': [{
                'end': 28,
                'start': 2,
                'type': 'FULL'
            }, {
                'end': 28,
                'start': 2,
                'type': 'SHORT'
            }, {
                'end': 8,
                'start': 6,
                'type': 'CLIENT_INITIALIZATION'
            }, {
                'end': 22,
                'start': 9,
                'type': 'REQUEST_INITIALIZATION'
            }, {
                'end': 25,
                'start': 23,
                'type': 'REQUEST_EXECUTION'
            }, {
                'end': 29,
                'start': 26,
                'type': 'RESPONSE_HANDLING'
            }]
        }]
    }
Exemple #6
0
def test_add_snippet_no_matching_service(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Clam"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    # No 'Clam' service in API Schema
    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={"Squid": DummyService(name="Squid", methods={})},
        naming=DummyNaming(proto_package="google.mollusca",
                           warehouse_package_name="google-mollusca",
                           version="v1"),
    ))
    with pytest.raises(types.UnknownService):
        index.add_snippet(snippet)
Exemple #7
0
def test_add_snippet_no_matching_rpc(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    # No 'classify' method in 'Squid' service
    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={"Squid": DummyService(name="Squid", methods={"list": None})},
        naming=DummyNaming(proto_package="google.mollusca",
                           warehouse_package_name="google-mollusca",
                           version="v1"),
    ))
    with pytest.raises(types.RpcMethodNotFound):
        index.add_snippet(snippet)
Exemple #8
0
def test_add_and_get_snippet_sync(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={
            "Squid":
            DummyService(name="Squid", methods={"classify": DummyMethod()})
        }))

    index.add_snippet(snippet)

    index.get_snippet(service_name="Squid", rpc_name="classify")
Exemple #9
0
def test_add_and_get_snippet_sync(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={
            "Squid":
            DummyService(name="Squid", methods={"classify": DummyMethod()})
        },
        naming=DummyNaming(proto_package="google.mollusca",
                           warehouse_package_name="google-mollusca",
                           version="v1"),
    ))

    index.add_snippet(snippet)

    index.get_snippet(service_name="Squid", rpc_name="classify")
Exemple #10
0
def test_snippet_init(sample_str):
    # We are not trying to exhaustively test the snippet metadata protobuf,
    # just checking that fields are not unset
    sample_metadata = snippet_metadata_pb2.Snippet(title="classify_squid.py")
    sample_metadata.language = snippet_metadata_pb2.Language.PYTHON
    snippet = snippet_index.Snippet(sample_str, sample_metadata)

    assert snippet.sample_str == sample_str

    # It's easier to eyeball diffs on the dictionary representation
    assert json_format.MessageToDict(snippet.metadata) == {
        "language":
        "PYTHON",
        "title":
        "classify_squid.py",
        "segments": [
            {
                "end": 28,
                "start": 2,
                "type": "FULL"
            },
            {
                "end": 28,
                "start": 2,
                "type": "SHORT"
            },
            {
                "end": 8,
                "start": 6,
                "type": "CLIENT_INITIALIZATION"
            },
            {
                "end": 22,
                "start": 9,
                "type": "REQUEST_INITIALIZATION"
            },
            {
                "end": 25,
                "start": 23,
                "type": "REQUEST_EXECUTION"
            },
            {
                "end": 29,
                "start": 26,
                "type": "RESPONSE_HANDLING"
            },
        ]
    }

    # This is the same as the sample_str above, minus the # [START ...]
    # and # [END ...] lines
    expected_full_snipppet = """from molluscs.v1 import molluscclient


def sample_classify(video, location):
    # Create a client
    client = molluscclient.MolluscServiceClient()

    # Initialize request argument(s)
    classify_target = molluscclient.ClassifyTarget()

    # video = "path/to/mollusc/video.mkv"
    with open(video, "rb") as f:
        classify_target.video = f.read()

    # location = "New Zealand"
    classify_target.location_annotation = location

    request = molluscclient.molluscs.v1.ClassifyRequest(
        classify_target=classify_target,
    )

    # Make the request
    response = client.classify(request=request)

    # Handle the response
    print(f"Mollusc is a \"{response.taxonomy}\"")

"""

    assert snippet.full_snippet == expected_full_snipppet
Exemple #11
0
def test_get_metadata_json(sample_str):
    snippet_metadata = snippet_metadata_pb2.Snippet()
    snippet_metadata.client_method.method.service.short_name = "Squid"
    snippet_metadata.client_method.method.short_name = "classify"
    snippet = snippet_index.Snippet(sample_str, snippet_metadata)

    index = snippet_index.SnippetIndex(api_schema=DummyApiSchema(
        services={
            "Squid":
            DummyService(name="Squid", methods={"classify": DummyMethod()})
        },
        naming=DummyNaming(proto_package="google.mollusca",
                           warehouse_package_name="google-mollusca",
                           version="v1"),
    ))

    index.add_snippet(snippet)

    print(index.get_metadata_json())
    assert json.loads(index.get_metadata_json()) == {
        "clientLibrary": {
            "apis": [{
                "id": "google.mollusca",
                "version": "v1"
            }],
            "language": "PYTHON",
            "name": "google-mollusca"
        },
        "snippets": [{
            "clientMethod": {
                "method": {
                    "service": {
                        "shortName": "Squid"
                    },
                    "shortName": "classify"
                }
            },
            "segments": [{
                "end": 28,
                "start": 2,
                "type": "FULL"
            }, {
                "end": 28,
                "start": 2,
                "type": "SHORT"
            }, {
                "end": 8,
                "start": 6,
                "type": "CLIENT_INITIALIZATION"
            }, {
                "end": 22,
                "start": 9,
                "type": "REQUEST_INITIALIZATION"
            }, {
                "end": 25,
                "start": 23,
                "type": "REQUEST_EXECUTION"
            }, {
                "end": 29,
                "start": 26,
                "type": "RESPONSE_HANDLING"
            }]
        }]
    }
def _fill_sample_metadata(sample: dict, api_schema: api.API):
    """Returns snippet metadata for the sample."""

    # Snippet Metadata can't be fully filled out in any one function
    # In this function we add information from
    # the API schema and sample dictionary.
    # See `snippet_metadata.proto` for documentation on the fields

    service = api_schema.services[sample["service"]]
    method = service.methods[sample["rpc"]]
    async_ = sample["transport"] == api.TRANSPORT_GRPC_ASYNC

    snippet_metadata = snippet_metadata_pb2.Snippet()  # type: ignore
    snippet_metadata.region_tag = sample["region_tag"]
    snippet_metadata.description = f"Sample for {sample['rpc']}"
    snippet_metadata.language = snippet_metadata_pb2.Language.PYTHON  # type: ignore
    snippet_metadata.canonical = True
    snippet_metadata.origin = snippet_metadata_pb2.Snippet.Origin.API_DEFINITION  # type: ignore

    # Service Client
    snippet_metadata.client_method.client.short_name = service.async_client_name if async_ else service.client_name
    snippet_metadata.client_method.client.full_name = f"{'.'.join(sample['module_namespace'])}.{sample['module_name']}.{snippet_metadata.client_method.client.short_name}"

    # Service
    snippet_metadata.client_method.method.service.short_name = service.name
    snippet_metadata.client_method.method.service.full_name = f"{api_schema.naming.proto_package}.{service.name}"

    # RPC
    snippet_metadata.client_method.method.short_name = method.name
    snippet_metadata.client_method.method.full_name = f"{api_schema.naming.proto_package}.{service.name}.{method.name}"

    # Client Method
    setattr(snippet_metadata.client_method, "async", async_)
    snippet_metadata.client_method.short_name = utils.to_snake_case(
        method.name)
    snippet_metadata.client_method.full_name = f"{snippet_metadata.client_method.client.full_name}.{snippet_metadata.client_method.short_name}"

    if not method.void:
        snippet_metadata.client_method.result_type = method.client_output_async.ident.sphinx if async_ else method.client_output.ident.sphinx
        if method.server_streaming:
            snippet_metadata.client_method.result_type = f"Iterable[{snippet_metadata.client_method.result_type }]"

    # Client Method Parameters
    parameters = snippet_metadata.client_method.parameters
    if not method.client_streaming:
        parameters.append(
            snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
                type=method.input.ident.sphinx,
                name="request"))
        for field in method.flattened_fields.values():
            parameters.append(
                snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
                    type=field.ident.sphinx, name=field.name))
    else:
        parameters.append(
            snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
                type=f"Iterator[{method.input.ident.sphinx}]",
                name="requests"))

    parameters.append(
        snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
            name="retry", type="google.api_core.retry.Retry"))
    parameters.append(
        snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
            name="timeout", type="float"))
    parameters.append(
        snippet_metadata_pb2.ClientMethod.Parameter(  # type: ignore
            name="metadata", type="Sequence[Tuple[str, str]"))

    return snippet_metadata
    assert actual_response.file[1] == CodeGeneratorResponse.File(
        name="samples/generated_samples/clam_sample.py",
        content="\n",
    )

    assert actual_response.file[
        2].name == "samples/generated_samples/snippet_metadata_mollusc_v1.json"

    assert json.loads(
        actual_response.file[2].content) == expected_snippet_index_json


@mock.patch("gapic.samplegen.samplegen.generate_sample_specs", return_value=[])
@mock.patch(
    "gapic.samplegen.samplegen.generate_sample",
    return_value=("", snippet_metadata_pb2.Snippet()),
)
def test_generate_autogen_samples(mock_generate_sample, mock_generate_specs):
    opts = Options.build("autogen-snippets")
    g = generator.Generator(opts)
    # Need to have the sample template visible to the generator.
    g._env.loader = jinja2.DictLoader({"sample.py.j2": ""})

    api_schema = make_api(
        naming=naming.NewNaming(name="Mollusc", version="v6"))

    actual_response = g.get_response(api_schema, opts=opts)

    # Just check that generate_sample_specs was called
    # Correctness of the spec is tested in samplegen unit tests
    mock_generate_specs.assert_called_once_with(api_schema, opts=opts)