Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(snippetgen): turn resource path strings into f-strings #1012

Merged
merged 6 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 57 additions & 23 deletions gapic/samplegen/samplegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class TransformedRequest:
def build(
cls,
request_type: wrappers.MessageType,
api_schema,
api_schema: api.API,
base: str,
attrs: List[AttributeRequestSetup],
is_resource_request: bool,
Expand Down Expand Up @@ -163,25 +163,22 @@ def build(
#
# It's a precondition that the base field is
# a valid field of the request message type.
resource_typestr = (
request_type.fields[base]
.options.Extensions[resource_pb2.resource_reference]
.type
)
resource_reference = request_type.fields[base].options.Extensions[resource_pb2.resource_reference]
resource_typestr = resource_reference.type or resource_reference.child_type

resource_message_descriptor = next(
(
msg.options.Extensions[resource_pb2.resource]
for msg in api_schema.messages.values()
if msg.options.Extensions[resource_pb2.resource].type
== resource_typestr
),
None,
)
if not resource_message_descriptor:
resource_message = None
for service in api_schema.services.values():
resource_message = service.resource_messages_dict.get(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched to looking through service.resource_messages_dict as the common resources (projects/{project}, folders/{folder}, ...) aren't in api_schema.messages.

resource_typestr)
if resource_message is not None:
break

if resource_message is None:
raise types.NoSuchResource(
f"No message exists for resource: {resource_typestr}"
f"No message exists for resource: {resource_typestr}",
)
resource_message_descriptor = resource_message.options.Extensions[
resource_pb2.resource]

# The field is only ever empty for singleton attributes.
attr_names: List[str] = [a.field for a in attrs] # type: ignore
Expand Down Expand Up @@ -944,6 +941,37 @@ def parse_handwritten_specs(sample_configs: Sequence[str]) -> Generator[Dict[str
yield spec


def _generate_resource_path_request_object(field_name: str, message: wrappers.MessageType) -> List[Dict[str, str]]:
"""Given a message that represents a resource, generate request objects that
populate the resource path args.

Args:
field_name (str): The name of the field.
message (wrappers.MessageType): The message the field belongs to.

Returns:
List[Dict[str, str]]: A list of dicts that can be turned into TransformedRequests.
"""
request = []

# Look for specific field names to substitute more realistic values
special_values_dict = {
"project": '"my-project-id"',
"location": '"us-central1"'
}

for resource_path_arg in message.resource_path_args:
value = special_values_dict.get(
resource_path_arg, f'"{resource_path_arg}_value"')
request.append({
# See TransformedRequest.build() for how 'field' is parsed
"field": f"{field_name}%{resource_path_arg}",
"value": value,
})

return request


def generate_request_object(api_schema: api.API, service: wrappers.Service, message: wrappers.MessageType, field_name_prefix: str = ""):
"""Generate dummy input for a given message.

Expand Down Expand Up @@ -972,12 +1000,18 @@ def generate_request_object(api_schema: api.API, service: wrappers.Service, mess

# TODO(busunkim): Properly handle map fields
if field.is_primitive:
placeholder_value = field.mock_value_original_type
# If this field identifies a resource use the resource path
if service.resource_messages_dict.get(field.resource_reference):
placeholder_value = service.resource_messages_dict[
field.resource_reference].resource_path
request.append({"field": field_name, "value": placeholder_value})
resource_reference_message = service.resource_messages_dict.get(
field.resource_reference)
# Some resource patterns have no resource_path_args
# https://github.com/googleapis/gapic-generator-python/issues/701
if resource_reference_message and resource_reference_message.resource_path_args:
request += _generate_resource_path_request_object(
field_name,
resource_reference_message
)
else:
request.append(
{"field": field_name, "value": field.mock_value_original_type})
elif field.enum:
# Choose the last enum value in the list since index 0 is often "unspecified"
request.append(
Expand Down
5 changes: 3 additions & 2 deletions gapic/templates/examples/feature_fragments.j2
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ client = {{ module_name }}.{{ client_name }}()
{# This is a resource-name patterned lookup parameter #}
{% with formals = [] %}
{% for attr in parameter_block.body %}
{% do formals.append("%s=%s"|format(attr.field, attr.input_parameter or attr.value)) %}
{{ attr.field }} = {{ attr.input_parameter or attr.value }}
{% endfor %}
{{ parameter_block.base }} = "{{parameter_block.pattern }}".format({{ formals|join(", ") }})
{{ parameter_block.base }} = f"{{parameter_block.pattern }}"

{% endwith %}
{% else %}{# End resource name construction #}
{{ parameter_block.base }} = {{ module_name }}.{{ request_type.get_field(parameter_block.base).type.name }}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def sample_batch_get_assets_history():

# Initialize request argument(s)
request = asset_v1.BatchGetAssetsHistoryRequest(
parent="*",
parent="parent_value",
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def sample_batch_get_assets_history():

# Initialize request argument(s)
request = asset_v1.BatchGetAssetsHistoryRequest(
parent="*",
parent="parent_value",
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_delete_feed():
client = asset_v1.AssetServiceAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
feed = "feed_value"
name = f"projects/{project}/feeds/{feed}"

request = asset_v1.DeleteFeedRequest(
name="projects/{project}/feeds/{feed}",
name=name,
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_delete_feed():
client = asset_v1.AssetServiceClient()

# Initialize request argument(s)
project = "my-project-id"
feed = "feed_value"
name = f"projects/{project}/feeds/{feed}"

request = asset_v1.DeleteFeedRequest(
name="projects/{project}/feeds/{feed}",
name=name,
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async def sample_export_assets():
output_config.gcs_destination.uri = "uri_value"

request = asset_v1.ExportAssetsRequest(
parent="*",
parent="parent_value",
output_config=output_config,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def sample_export_assets():
output_config.gcs_destination.uri = "uri_value"

request = asset_v1.ExportAssetsRequest(
parent="*",
parent="parent_value",
output_config=output_config,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_get_feed():
client = asset_v1.AssetServiceAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
feed = "feed_value"
name = f"projects/{project}/feeds/{feed}"

request = asset_v1.GetFeedRequest(
name="projects/{project}/feeds/{feed}",
name=name,
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_get_feed():
client = asset_v1.AssetServiceClient()

# Initialize request argument(s)
project = "my-project-id"
feed = "feed_value"
name = f"projects/{project}/feeds/{feed}"

request = asset_v1.GetFeedRequest(
name="projects/{project}/feeds/{feed}",
name=name,
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def sample_list_assets():

# Initialize request argument(s)
request = asset_v1.ListAssetsRequest(
parent="*",
parent="parent_value",
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def sample_list_assets():

# Initialize request argument(s)
request = asset_v1.ListAssetsRequest(
parent="*",
parent="parent_value",
)

# Make the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_generate_access_token():
client = credentials_v1.IAMCredentialsAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.GenerateAccessTokenRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
scope=['scope_value_1', 'scope_value_2'],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_generate_access_token():
client = credentials_v1.IAMCredentialsClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.GenerateAccessTokenRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
scope=['scope_value_1', 'scope_value_2'],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_generate_id_token():
client = credentials_v1.IAMCredentialsAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.GenerateIdTokenRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
audience="audience_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_generate_id_token():
client = credentials_v1.IAMCredentialsClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.GenerateIdTokenRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
audience="audience_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_sign_blob():
client = credentials_v1.IAMCredentialsAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.SignBlobRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
payload=b'payload_blob',
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_sign_blob():
client = credentials_v1.IAMCredentialsClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.SignBlobRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
payload=b'payload_blob',
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ async def sample_sign_jwt():
client = credentials_v1.IAMCredentialsAsyncClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.SignJwtRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
payload="payload_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ def sample_sign_jwt():
client = credentials_v1.IAMCredentialsClient()

# Initialize request argument(s)
project = "my-project-id"
service_account = "service_account_value"
name = f"projects/{project}/serviceAccounts/{service_account}"

request = credentials_v1.SignJwtRequest(
name="projects/{project}/serviceAccounts/{service_account}",
name=name,
payload="payload_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ async def sample_create_bucket():
client = logging_v2.ConfigServiceV2AsyncClient()

# Initialize request argument(s)
project = "my-project-id"
location = "us-central1"
bucket = "bucket_value"
parent = f"projects/{project}/locations/{location}/buckets/{bucket}"

request = logging_v2.CreateBucketRequest(
parent="projects/{project}/locations/{location}/buckets/{bucket}",
parent=parent,
bucket_id="bucket_id_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ def sample_create_bucket():
client = logging_v2.ConfigServiceV2Client()

# Initialize request argument(s)
project = "my-project-id"
location = "us-central1"
bucket = "bucket_value"
parent = f"projects/{project}/locations/{location}/buckets/{bucket}"

request = logging_v2.CreateBucketRequest(
parent="projects/{project}/locations/{location}/buckets/{bucket}",
parent=parent,
bucket_id="bucket_id_value",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ async def sample_create_exclusion():
client = logging_v2.ConfigServiceV2AsyncClient()

# Initialize request argument(s)
project = "my-project-id"
exclusion = "exclusion_value"
parent = f"projects/{project}/exclusions/{exclusion}"

exclusion = logging_v2.LogExclusion()
exclusion.name = "name_value"
exclusion.filter = "filter_value"

request = logging_v2.CreateExclusionRequest(
parent="projects/{project}/exclusions/{exclusion}",
parent=parent,
exclusion=exclusion,
)

Expand Down
Loading