Conversation
|
Not done, don't merge. Also I want to fix the tests but can't figure out how to run them. |
|
@jmdobry can you summarize the changes? |
|
Will do |
|
Top-level comments:
I did like the separation of iam-related samples in its own file. I organized these to match doc pages.
I'm pretty -1 on this. I've gotten feedback that these confuse users. Principle of least surprise.
I'm -1 on this, the justification "Avoid massive duplication of boilerplate import/instantiate code that gets out of date" isn't relevant when it's literally one statement with zero parameters. |
pubsub/cloud-client/subscriptions.py
Outdated
| from google.cloud import pubsub | ||
|
|
||
|
|
||
| pubsub_client = pubsub.Client() |
There was a problem hiding this comment.
This is no bueno:
- It's a global variable (not a constant)
- There should not be side-effects for top-level statements.
- This is not easily testable.
pubsub/cloud-client/subscriptions.py
Outdated
| # References an existing topic, e.g. "my-topic" | ||
| topic = pubsub_client.topic(topic_name) | ||
|
|
||
| project_id = os.environ['GCLOUD_PROJECT'] or 'YOUR_PROJECT_ID' |
There was a problem hiding this comment.
Please, lets not do this. pubsub_client.project.
There was a problem hiding this comment.
Ah cool, yeah that works better.
There was a problem hiding this comment.
TIL google-cloud-node supports this too, nice!
pubsub/cloud-client/subscriptions.py
Outdated
|
|
||
|
|
||
| # [START pubsub_get_subscription_metadata] | ||
| def get_subscription_metadata(topic_name, subscription_name): |
There was a problem hiding this comment.
get_subscription is just a good as get_subscription_metadata and is more succinct.
pubsub/cloud-client/subscriptions.py
Outdated
| # Retrieves the IAM policy for the subscription | ||
| policy = subscription.get_iam_policy() | ||
|
|
||
| print('Policy for subscription: {}'.format(policy.to_api_repr())) |
There was a problem hiding this comment.
to_api_repr shouldn't be used.
e4305ae to
96ec3bc
Compare
The docs are being completely rewritten and won't have the same organization, so here I just went for consistency with other languages and the somewhat common "organization by resource type"
Yeah, still pending on whether we can reliably track samples using regular expressions.
Fixed |
That seems.. weird. These samples are getting big - the cognitive load of completely understanding one is now getting high. I'm not a fan of it. |
|
My feedback on the proposed samples
Method Definitions
I propose that code without a wrapping method definition is more clear and makes it easier for the reader to adapt the code to his/her own needs. As an example, see the code samples for the API reference docs, Documenting snippet variablesMethod definitions typically include simple parameter names such as To solve this, each variable MUST include a description. I see 3 options for how to include a description of the variable in the code snippet:
Method parameters1. For the first option, each language typically uses its own idiomatic commenting style for documenting parameters. For example: These comments can take up many lines of code, using up valuable vertical space. Because they follow language idioms for method parameter documentation, they can often be more syntactically complex and difficult to read at a glance than simple comments. C# parameter documentation, for example, is written in XML and is overkill for use in snippets. These are not ideal due to readability and vertical space. Comments in method code2. The second option might be to add comments near where each variable is used. For example, when This is helpful, although... what if multiple variables are introduced on the same line? These are not ideal because:
Placeholder variables3. The third option might be to add placeholder variables with example values / descriptions for each of the variables required to successfully run the snippet code. This is similar to what is currently used by some of the code snippets shown in API usage documentation 1. The third option might allow users to copy/paste the snippet into their own file and uncomment existing variable definitions to run the code successfully without having to define any variables by themselves. Users will very likely also find it useful to see a list of all required variables at the top of the snippet. I propose that this is ideal.
Why we do not need to include method signaturesFor all of the 3 possible options above, none of them benefit from being wrapped in a method definition. Method definitions take up 2 extra lines of vertical space and they result in the first line of code may be something like Import Client Library in snippets
We have found that many users copy/paste our snippets into their own code files. When a developer copy/pastes a snippet following these proposals, they will discover that the snippet DOES NOT FUNCTION independently for 2 reasons:
As a developer, I may search Google looking for how to use a product such as Google Cloud Storage looking for a way to upload a file. When I scan through the documentation and find the documentation for uploading a file, I am likely to read the snippet code and attempt to upload a file using that code. I may not take the time to read the text surrounding the code snippet. I propose that this is ideal.
ExampleAs an example, this is the template that Ruby code sample snippets use today. This snippet follows all of the proposals included in this comment and are the result of templatizing code sample snippets based on opinions of those gathering user study data on sample usability. Translating a string using the Google Translate API Occassionally, variables are not simple strings but rather complex objects. BigQuery, for example, includes a snippet for inserting row data into a table and the row data is a complex object ( |
+1 I adore small, simple samples. Whenever I see |
|
He meant that the
The problem is that most languages can't do imports within a method definition. Perhaps this works out okay in Ruby, but in Node.js dynamic imports are an anti-pattern. They can't be statically analyzed, and when Node.js implements ES2015 modules the language itself will enforce that imports be top-level statements only. This definitely won't work with Go, Java, and .NET, unless we want to do one snippet per file, which I don't think we want to do, and even then the samples for those languages would have to show a method definition. An argument could be made that a method signature can be self-documenting. The majority of our samples deal with primitives like strings and numbers. This example seems pretty clear to me (though maybe not a good measure?): Granted, this is a really simple example. For more complex samples, like writing a log entry (and your BigQuery row example), it's not enough for the method signature to simply accept a We could change the Cloud Storage sample to this: but now it's not clear where the But why not just show the method signature? I would say that decomposition and code re-use via functions is more common than writing apps that import, instantiate, and make a method call all at the top level. To reduce inconsistencies between our samples are how people write apps, my vote goes for showing the method definition. (Also, the user doesn't have to copy the method definition when they copy code from our docs. But if it's not there, they definitely can't copy it.) This would be my ideal "quickstart" Cloud Storage sample, which would be shown on the Cloud Storage Client Libraries page: And this would be my ideal "everything else" type of snippet: (The snippet would be prefaced with a sentence like this: "For how to create a Cloud Storage client, refer to Cloud Storage Client Libraries.". The linked page would show installing and importing the client library.) I'm okay with adding more comments that make it clear what type value a variable holds, e.g. |
Summary of changes:
masterbefore this PR gets merged)topics.pyandsubscriptions.pyto match the Node.js and Ruby PRsget_subscriptionsamplelist_subscriptionssample (in addition to the existinglist_topic_subscriptionssampleCompare to:
Proposals implemented by the 3 PRs: