Skip to content
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
63 changes: 39 additions & 24 deletions .github/workflows/update_sdk_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,29 @@ def link_description(format_type, full_description, link_text, link_url):

return linked_description

## Fetch just the first sentence from an override file (first text string terminated by '.\n'), ignoring hugo
## shortcodes like alerts ('{{% alert %}}...{{% /alert %}}'), which precede some override files' (proto descriptions')
## first sentence. The closing tag must match the same shortcode name as the opener (via backreference), so a
## self-closing shortcode earlier in the file (e.g. {{< glossary_tooltip ... >}}, no closing tag of its own) can't
## get matched up with an unrelated block shortcode's closer later in the file. Used for the API summary tables:
def override_first_sentence(override_file):
with open(override_file, 'r') as f:
file_contents = f.read().strip()
file_contents = regex.sub(r'\{\{\%\s*(\w+)[^%]*\%\}\}.*?\{\{\%\s*\/\1\s*\%\}\}', '', file_contents, flags=regex.DOTALL)
## Same, for angle-bracket shortcodes ({{< alert >}}...{{< /alert >}}), which
## otherwise leak an unclosed shortcode opener into the table description:
file_contents = regex.sub(r'\{\{<\s*(\w+)[^>]*>\}\}.*?\{\{<\s*\/\1\s*>\}\}', '', file_contents, flags=regex.DOTALL)
search_result = file_contents.split('.\n', 1)[0].strip().replace("\n", " ")

## If the description contains any MD links, strip them out:
search_result = regex.sub(r'\[([A-Za-z0-9\.\(\)\-\_\`\s]*)\]\([A-Za-z0-9\.\:\/\-\_\#]*\)', r'\1', search_result)

## If the description is missing a trailing period, or we stripped it off during the above matching, append
## (restore) the period character:
if not search_result.endswith('.'):
return search_result + '.'
return search_result

## Fetch SDK documentation for each language in sdks array, by language, by type, by resource, by method.
def parse(type, names):

Expand Down Expand Up @@ -930,6 +953,18 @@ def write_markdown(type, names, methods):

proto_override_filename = resource + '.' + proto + '.md'

## Protos that viamrobotics/api marks `option deprecated = true` get a hand-written note naming
## the replacement (the proto itself doesn't say what to use instead), rendered as an alert above
## the description and in place of the description in the summary table. See CLAUDE.md
## ("Generated SDK reference docs") for how to find newly deprecated protos:
## .../overrides/protos/{resource}.{proto}.deprecated.md
proto_deprecated_file = os.path.join(path_to_protos_override, resource + '.' + proto + '.deprecated.md')
if os.path.isfile(proto_deprecated_file):
output_file.write('{{% alert title="Deprecated" color="caution" %}}\n\n')
for line in open(proto_deprecated_file, 'r', encoding='utf-8'):
output_file.write(line)
output_file.write('\n{{% /alert %}}\n\n')

## .../overrides/protos/{resource}.{proto}
proto_override_file = os.path.join(path_to_protos_override, proto_override_filename)
if os.path.isfile(proto_override_file):
Expand Down Expand Up @@ -987,31 +1022,8 @@ def write_markdown(type, names, methods):
elif type == 'robot':
proto_anchor_link = '/reference/apis/' + resource + '/#' + proto_link

## Fetch just the first sentence from the proto_override_file (first text string terminated by '.\n'), ignoring hugo
## shortcodes like alerts ('{{% alert %}}...{{% /alert %}}'), which precede some override files' (proto descriptions')
## first sentence. The closing tag must match the same shortcode name as the opener (via backreference), so a
## self-closing shortcode earlier in the file (e.g. {{< glossary_tooltip ... >}}, no closing tag of its own) can't
## get matched up with an unrelated block shortcode's closer later in the file:


if os.path.isfile(proto_override_file):
with open(proto_override_file, 'r') as f:
file_contents = f.read().strip()
file_contents = regex.sub(r'\{\{\%\s*(\w+)[^%]*\%\}\}.*?\{\{\%\s*\/\1\s*\%\}\}', '', file_contents, flags=regex.DOTALL)
## Same, for angle-bracket shortcodes ({{< alert >}}...{{< /alert >}}), which
## otherwise leak an unclosed shortcode opener into the table description:
file_contents = regex.sub(r'\{\{<\s*(\w+)[^>]*>\}\}.*?\{\{<\s*\/\1\s*>\}\}', '', file_contents, flags=regex.DOTALL)
search_result = file_contents.split('.\n', 1)[0].strip().replace("\n", " ")

## If the proto description contains any MD links, strip them out:
search_result = regex.sub(r'\[([A-Za-z0-9\.\(\)\-\_\`\s]*)\]\([A-Za-z0-9\.\:\/\-\_\#]*\)', r'\1', search_result)

## If the proto description is missing a trailing period, or we stripped it off during the above matching, append
## (restore) the period character:
if not search_result.endswith('.'):
proto_description_first_sentence = search_result + '.'
else:
proto_description_first_sentence = search_result
proto_description_first_sentence = override_first_sentence(proto_override_file)
else:
## No proto description override file (for example a proto whose
## docs section was removed); leave the description blank instead
Expand All @@ -1020,6 +1032,9 @@ def write_markdown(type, names, methods):
print(f"WARNING: {type} {resource} {proto} has no proto description override file ({proto_override_file}); leaving description blank")
proto_description_first_sentence = ''

if os.path.isfile(proto_deprecated_file):
proto_description_first_sentence = '**Deprecated.** ' + override_first_sentence(proto_deprecated_file)

## Write out this proto's entry to this resource's table_file:
if resource != 'movement_sensor':
if micro_rdk_support != '':
Expand Down
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ The docs health dashboard (`viamrobotics/docs-health`, a private repo) rebuilds
- **Not covered by the standard pre-PR checks above.** `prettier-lint.yml` only checks `docs/**/*.md`, and `markdown-lint.yml` explicitly excludes `static/`. Running `prettier --write` on generated files introduces unrelated reformatting noise (quote style, indentation) that CI never enforced. `make build-prod` still applies and is the right check for changes here.
- **Script dependencies aren't in `requirements.txt`.** That file is for the `docs.yml` index-sync jobs. `update_sdk_methods.py` needs `beautifulsoup4` and `markdownify`—see the `pip install` line in `check-methods.yml` for the authoritative list. Run it in a scratch venv; don't install into a shared environment.
- **Proto descriptions are hand-maintained, not scraped**, even though method signatures/params/examples are scraped live from each SDK's docs site. One override file per proto, `static/include/<app|components|services|robot>/apis/overrides/protos/<resource>.<ProtoName>.md`, holding a one-sentence description used both verbatim on the detail page and (first-sentence-only) in the summary table. A missing override doesn't fail the build—it just leaves that method's description blank and prints a `WARNING: ... has no proto description override file` from the weekly coverage job (`check-methods.yml`, `continue-on-error: true`). No README covers this system; the rationale is in comments around `update_sdk_methods.py`'s `write_markdown()`.
- **Deprecated protos need a hand-written note.** `viamrobotics/api` marks deprecated RPCs with `option deprecated = true`, but the generator doesn't read protos, and the flag doesn't say what replaces the method. For each deprecated RPC with a row in `sdk_protos_map.csv`, add `static/include/<app|components|services|robot>/apis/overrides/protos/<resource>.<ProtoName>.deprecated.md` naming the replacement. The generator renders it as a "Deprecated" alert above the method's description, and uses its first sentence, after **Deprecated.**, as the summary-table description. Name the replacement from source (the owning server's deprecation comments or error messages), not inference, and don't claim a removal date or plan unless the owning team has said so publicly. To list deprecated RPCs:

```bash
git clone --depth 1 https://github.com/viamrobotics/api /tmp/api
grep -rn -B2 "^ option deprecated = true;" /tmp/api/proto | grep " rpc "
```

The pattern relies on the api repo's indentation. `grep -rn "deprecated = true" /tmp/api/proto` is the broader fallback, and also lists deprecated messages and fields.
- **Regenerating one resource by hand can silently drop content.** Check the diff size after every manual run. Two known causes:
- For any app resource (`data`, `dataset`, `billing`, and so on), include `app` in the resource list (for example, `python3 .github/workflows/update_sdk_methods.py python,go,flutter,typescript app,data`). The Go parser only scrapes app-client methods when `app` is requested (`parse_go.py`), so a data-only run drops every Go tab.
- If an SDK docs site is unreachable, the script logs a `URLError`, writes the files without that SDK's tabs, and still exits 0. Discard the output and rerun.
- **Not every scraped SDK method needs a row.** Deprecated/orphaned services aren't necessarily excluded—`slam` is orphaned from navigation but still fully generated. `navigation` (restored as a deprecated orphan page in #5191) is the current exception: it has zero rows in `sdk_protos_map.csv` and isn't registered in the script's resource map, so its generated page is missing methods (for example, `GetStatus`) that the SDKs do implement—deliberately, to avoid actively maintaining a discontinued service's coverage. If another orphaned service shows up excluded like this, add it to this list rather than assuming a fresh investigation is needed.

## MCP server tool table
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/services/frame-system/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ The frame system uses the supplemental transform to determine where the arm shou

### Transform usage

- You can pass a detected object's frame information to the `supplemental_transforms` parameter in your calls to Viam's motion service's [`GetPose`](/reference/apis/services/motion/#getpose) method.
- You can pass a detected object's frame information to the `supplemental_transforms` parameter in your calls to the machine client's [`GetPose`](/reference/apis/robot/#getpose) method.
- Functions of some services and components also take in a `WorldState` parameter, which includes a `transforms` property.
- [`TransformPose`](/reference/apis/robot/#transformpose) has the option to take in these additional transforms.

Expand Down
10 changes: 5 additions & 5 deletions static/include/app/apis/generated/data-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
| ----------- | ----------- |
| [`GetLatestTabularData`](/reference/apis/data-client/#getlatesttabulardata) | Gets the most recent tabular data captured from the specified data source, as long as it was synced within the last year. |
| [`ExportTabularData`](/reference/apis/data-client/#exporttabulardata) | Obtain unified tabular data and metadata from the specified data source. |
| [`TabularDataByFilter`](/reference/apis/data-client/#tabulardatabyfilter) | Retrieve optionally filtered tabular data from Viam. |
| [`TabularDataByFilter`](/reference/apis/data-client/#tabulardatabyfilter) | **Deprecated.** Use `TabularDataByMQL` or `TabularDataBySQL` to query tabular data, or `ExportTabularData` to stream all data from one data source. |
| [`TabularDataBySQL`](/reference/apis/data-client/#tabulardatabysql) | Obtain unified tabular data and metadata, queried with SQL. Make sure your API key has permissions at the organization level in order to use this. |
| [`TabularDataByMQL`](/reference/apis/data-client/#tabulardatabymql) | Obtain unified tabular data and metadata, queried with MQL. |
| [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) | Retrieve optionally filtered binary data from Viam. |
Expand All @@ -13,10 +13,10 @@
| [`DeleteBinaryDataByIDs`](/reference/apis/data-client/#deletebinarydatabyids) | Filter and delete binary data by ids. |
| [`AddTagsToBinaryDataByIDs`](/reference/apis/data-client/#addtagstobinarydatabyids) | Add tags to binary data by ids. |
| [`RemoveTagsFromBinaryDataByIDs`](/reference/apis/data-client/#removetagsfrombinarydatabyids) | Remove tags from binary by ids. |
| [`TagsByFilter`](/reference/apis/data-client/#tagsbyfilter) | Get a list of tags using a filter. |
| [`TagsByFilter`](/reference/apis/data-client/#tagsbyfilter) | **Deprecated.** Collect tags from binary data with `BinaryDataByFilter`, and from tabular data with `TabularDataByMQL`. |
| [`AddBoundingBoxToImageByID`](/reference/apis/data-client/#addboundingboxtoimagebyid) | Add a bounding box to an image specified by its BinaryID. |
| [`RemoveBoundingBoxFromImageByID`](/reference/apis/data-client/#removeboundingboxfromimagebyid) | Removes a bounding box from an image specified by its BinaryID. |
| [`BoundingBoxLabelsByFilter`](/reference/apis/data-client/#boundingboxlabelsbyfilter) | Get a list of bounding box labels using a Filter. |
| [`BoundingBoxLabelsByFilter`](/reference/apis/data-client/#boundingboxlabelsbyfilter) | **Deprecated.** Use `BinaryDataByFilter` instead, and collect the unique `label` values from each result's `metadata.annotations.bboxes`. |
| [`GetDatabaseConnection`](/reference/apis/data-client/#getdatabaseconnection) | Get a connection to access a MongoDB Atlas Data federation instance. |
| [`ConfigureDatabaseUser`](/reference/apis/data-client/#configuredatabaseuser) | Configure a database user for the Viam organization’s MongoDB Atlas Data Federation instance. |
| [`AddBinaryDataToDatasetByIDs`](/reference/apis/data-client/#addbinarydatatodatasetbyids) | Add the `BinaryData` to the provided dataset. |
Expand All @@ -27,12 +27,12 @@
| [`DeleteDataPipeline`](/reference/apis/data-client/#deletedatapipeline) | Delete a data pipeline, its execution history, and all of its output data. |
| [`ListDataPipelineRuns`](/reference/apis/data-client/#listdatapipelineruns) | Get information about individual executions of a data pipeline. |
| [`RenameDataPipeline`](/reference/apis/data-client/#renamedatapipeline) | Rename a data pipeline. |
| [`AddTagsToBinaryDataByFilter`](/reference/apis/data-client/#addtagstobinarydatabyfilter) | Add tags to binary data by filter. |
| [`AddTagsToBinaryDataByFilter`](/reference/apis/data-client/#addtagstobinarydatabyfilter) | **Deprecated.** Use `AddTagsToBinaryDataByIDs` instead. |
| [`CreateBinaryDataSignedURL`](/reference/apis/data-client/#createbinarydatasignedurl) | Create a signed URL for accessing binary data without authentication. The URL expires after the specified duration. |
| [`CreateIndex`](/reference/apis/data-client/#createindex) | Create a custom index on your data to speed up queries. You specify the organization, the collection type (tabular or binary), and the fields to index. |
| [`DeleteIndex`](/reference/apis/data-client/#deleteindex) | Delete a custom index from your data. |
| [`ListIndexes`](/reference/apis/data-client/#listindexes) | List all custom indexes for an organization. |
| [`RemoveTagsFromBinaryDataByFilter`](/reference/apis/data-client/#removetagsfrombinarydatabyfilter) | Remove tags from binary data by filter. |
| [`RemoveTagsFromBinaryDataByFilter`](/reference/apis/data-client/#removetagsfrombinarydatabyfilter) | **Deprecated.** Use `RemoveTagsFromBinaryDataByIDs` instead. |
| [`UpdateBoundingBox`](/reference/apis/data-client/#updateboundingbox) | Update an existing bounding box on an image. You can change the label, position, or dimensions of the bounding box. |
| [`CreateSequence`](/reference/apis/data-client/#createsequence) | Create a sequence: a saved time window of one machine part's captured data, with tags. You provide the part ID, the resources to include, and the start and end times. |
| [`GetSequence`](/reference/apis/data-client/#getsequence) | Get a sequence by its ID. |
Expand Down
37 changes: 37 additions & 0 deletions static/include/app/apis/generated/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ For more information, see the [Flutter SDK Docs](https://flutter.viam.dev/viam_s

### TabularDataByFilter

{{% alert title="Deprecated" color="caution" %}}

Use [`TabularDataByMQL`](/reference/apis/data-client/#tabulardatabymql) or [`TabularDataBySQL`](/reference/apis/data-client/#tabulardatabysql) to query tabular data, or [`ExportTabularData`](/reference/apis/data-client/#exporttabulardata) to stream all data from one data source.

{{% /alert %}}

Retrieve optionally filtered tabular data from [Viam](https://app.viam.com).
You can also find your tabular data under the **Sensors** subtab of the [**Data** tab](https://app.viam.com/data).
{{< tabs >}}
Expand Down Expand Up @@ -1600,6 +1606,15 @@ For more information, see the [Flutter SDK Docs](https://flutter.viam.dev/viam_s

### TagsByFilter

{{% alert title="Deprecated" color="caution" %}}

Collect tags from binary data with [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter), and from tabular data with [`TabularDataByMQL`](/reference/apis/data-client/#tabulardatabymql).
`TagsByFilter` returns the unique tags from both.
For binary data, read each result's `metadata.capture_metadata.tags`.
For tabular data, query the `tags` field of the [`readings` table](/data/schema/).

{{% /alert %}}

Get a list of tags using a filter.

{{< tabs >}}
Expand Down Expand Up @@ -1941,6 +1956,12 @@ For more information, see the [Flutter SDK Docs](https://flutter.viam.dev/viam_s

### BoundingBoxLabelsByFilter

{{% alert title="Deprecated" color="caution" %}}

Use [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) instead, and collect the unique `label` values from each result's `metadata.annotations.bboxes`.

{{% /alert %}}

Get a list of bounding box labels using a Filter.

{{< tabs >}}
Expand Down Expand Up @@ -2873,6 +2894,14 @@ For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/a

### AddTagsToBinaryDataByFilter

{{% alert title="Deprecated" color="caution" %}}

Use [`AddTagsToBinaryDataByIDs`](/reference/apis/data-client/#addtagstobinarydatabyids) instead.
Calls to `AddTagsToBinaryDataByFilter` return an unimplemented error.
To tag the data that matches a filter, get its binary data IDs from [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) first.

{{% /alert %}}

Add tags to binary data by filter.

{{< tabs >}}
Expand Down Expand Up @@ -3007,6 +3036,14 @@ For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/

### RemoveTagsFromBinaryDataByFilter

{{% alert title="Deprecated" color="caution" %}}

Use [`RemoveTagsFromBinaryDataByIDs`](/reference/apis/data-client/#removetagsfrombinarydatabyids) instead.
Calls to `RemoveTagsFromBinaryDataByFilter` return an unimplemented error.
To remove tags from the data that matches a filter, get its binary data IDs from [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) first.

{{% /alert %}}

Remove tags from binary data by filter.

{{< tabs >}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use [`AddTagsToBinaryDataByIDs`](/reference/apis/data-client/#addtagstobinarydatabyids) instead.
Calls to `AddTagsToBinaryDataByFilter` return an unimplemented error.
To tag the data that matches a filter, get its binary data IDs from [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) first.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use [`BinaryDataByFilter`](/reference/apis/data-client/#binarydatabyfilter) instead, and collect the unique `label` values from each result's `metadata.annotations.bboxes`.
Loading
Loading