diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md
index 88a67f8f50c..0617bd2453d 100644
--- a/DEVELOPER_GUIDE.md
+++ b/DEVELOPER_GUIDE.md
@@ -8,7 +8,8 @@
- [Query parameters](#query-parameters)
- [Path parameters](#path-parameters)
- [Endpoints](#endpoints)
-
+ - [Example_Code](#example_code)
+
## Introduction
The `.md` documents in this repository are rendered into HTML pages using [Jekyll](https://jekyllrb.com/). These HTML pages are hosted on [opensearch.org](https://docs.opensearch.org/latest/).
@@ -88,6 +89,65 @@ All spec insert components accept the following arguments:
- `component` (String; required): The name of the component to render, such as `query_parameters`, `path_parameters`, or `endpoints`.
- `omit_header` (Boolean; Default is `false`): If set to `true`, the markdown header of the component will not be rendered.
+### Example_Code
+
+- `api` should not be placed for the `component: example_code` tag. `rest` is mapped to the correct API by regex mapping.
+- `rest` (String; required): The HTTP request line (`HTTP method` + `endpoint path`) that is regex mapped to the `opensearch-openapi.yaml`.
+
+The following tags are included to help with additional needs:
+
+- `body` (String; optional): The request body for the API call, using YAML `|` to preserve newlines and indentation.
+- `include_client_setup:` (Boolean; Default is `false`): If set to `true`, the client setup for the language will be rendered.
+- `skip` (Boolean; Default is `false`): If set to `true`, the language conversions will not render/re-render. Use for manual conversions.
+
+To insert multi-language support for the `cat.allocation` API, use the following snippet:
+
+```markdown
+
+
+```
+
+To insert multi-language support for the `index` API with a request body, use the following snippet. The `|` is needed for multiline support for the body:
+
+```markdown
+
+
+```
+
+To insert multi-language support for the `index` API and include the client setup for each language, use the following snippet:
+
+```markdown
+
+
+```
+
+To insert multi-language support for the `index` API but need to manually set the multi-language example for the `index` API, use the following snippet:
+
+```markdown
+
+
+```
+
### Endpoints
To insert endpoints for the `search` API, use the following snippet:
diff --git a/_api-reference/cat/cat-aliases.md b/_api-reference/cat/cat-aliases.md
index 0e758f2d673..ac2f63088f6 100644
--- a/_api-reference/cat/cat-aliases.md
+++ b/_api-reference/cat/cat-aliases.md
@@ -37,7 +37,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-allocation.md b/_api-reference/cat/cat-allocation.md
index 4935c688a3d..54ca9ca2570 100644
--- a/_api-reference/cat/cat-allocation.md
+++ b/_api-reference/cat/cat-allocation.md
@@ -36,7 +36,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-cluster_manager.md b/_api-reference/cat/cat-cluster_manager.md
index 0a27ba1ccd5..4c7111f89c0 100644
--- a/_api-reference/cat/cat-cluster_manager.md
+++ b/_api-reference/cat/cat-cluster_manager.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-count.md b/_api-reference/cat/cat-count.md
index 7c4231a9587..6ec0879e6ea 100644
--- a/_api-reference/cat/cat-count.md
+++ b/_api-reference/cat/cat-count.md
@@ -36,7 +36,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-field-data.md b/_api-reference/cat/cat-field-data.md
index 62cf9712196..f409a0690ad 100644
--- a/_api-reference/cat/cat-field-data.md
+++ b/_api-reference/cat/cat-field-data.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-health.md b/_api-reference/cat/cat-health.md
index e0c913ef28f..d313c1f7f5f 100644
--- a/_api-reference/cat/cat-health.md
+++ b/_api-reference/cat/cat-health.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-indices.md b/_api-reference/cat/cat-indices.md
index 562d81f2f48..79e297f220d 100644
--- a/_api-reference/cat/cat-indices.md
+++ b/_api-reference/cat/cat-indices.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-nodeattrs.md b/_api-reference/cat/cat-nodeattrs.md
index 2d09bb0324b..b4bc9c45481 100644
--- a/_api-reference/cat/cat-nodeattrs.md
+++ b/_api-reference/cat/cat-nodeattrs.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-nodes.md b/_api-reference/cat/cat-nodes.md
index ec39ab8c521..a1f16e306d8 100644
--- a/_api-reference/cat/cat-nodes.md
+++ b/_api-reference/cat/cat-nodes.md
@@ -36,7 +36,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -47,7 +47,7 @@ The following table lists the available query parameters. All query parameters a
| `h` | List | A comma-separated list of column names to display. | N/A |
| `help` | Boolean | Returns help information. | `false` |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-pending-tasks.md b/_api-reference/cat/cat-pending-tasks.md
index 26028f61610..d60a1873299 100644
--- a/_api-reference/cat/cat-pending-tasks.md
+++ b/_api-reference/cat/cat-pending-tasks.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -44,7 +44,7 @@ The following table lists the available query parameters. All query parameters a
| `help` | Boolean | Returns help information. | `false` |
| `local` | Boolean | Returns local information but does not retrieve the state from the cluster manager node. | `false` |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-pit-segments.md b/_api-reference/cat/cat-pit-segments.md
index e105983c4e6..14cdc84abd6 100644
--- a/_api-reference/cat/cat-pit-segments.md
+++ b/_api-reference/cat/cat-pit-segments.md
@@ -41,7 +41,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-plugins.md b/_api-reference/cat/cat-plugins.md
index 65d68fe2e32..450b33ebd71 100644
--- a/_api-reference/cat/cat-plugins.md
+++ b/_api-reference/cat/cat-plugins.md
@@ -33,7 +33,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-recovery.md b/_api-reference/cat/cat-recovery.md
index 40e90566db6..cf076b79b8e 100644
--- a/_api-reference/cat/cat-recovery.md
+++ b/_api-reference/cat/cat-recovery.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -47,7 +47,7 @@ The following table lists the available query parameters. All query parameters a
| `help` | Boolean | Returns help information. | `false` |
| `index` | List | A comma-separated list of data streams, indexes, and aliases used to limit the request. Supports wildcards (`*`). To target all data streams and indexes, omit this parameter or use `*` or `_all`. | N/A |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-repositories.md b/_api-reference/cat/cat-repositories.md
index fe9c0895171..7d621897cbd 100644
--- a/_api-reference/cat/cat-repositories.md
+++ b/_api-reference/cat/cat-repositories.md
@@ -33,7 +33,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-segment-replication.md b/_api-reference/cat/cat-segment-replication.md
index 459e323370b..b2201fb5817 100644
--- a/_api-reference/cat/cat-segment-replication.md
+++ b/_api-reference/cat/cat-segment-replication.md
@@ -34,7 +34,7 @@ include_deprecated: false
-->
## Path parameters
-The following table lists the available path parameters. All path parameters are optional.
+The following table lists the available path parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
@@ -51,7 +51,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -69,7 +69,7 @@ The following table lists the available query parameters. All query parameters a
| `index` | List | A comma-separated list of data streams, indexes, and aliases used to limit the request. Supports wildcards (`*`). To target all data streams and indexes, omit this parameter or use `*` or `_all`. | N/A |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
| `shards` | List | A comma-separated list of shards to display. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `timeout` | String | The operation timeout. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-segments.md b/_api-reference/cat/cat-segments.md
index a1aad5954fe..cfb5ce7ba04 100644
--- a/_api-reference/cat/cat-segments.md
+++ b/_api-reference/cat/cat-segments.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-shards.md b/_api-reference/cat/cat-shards.md
index b90d82df3da..054f40a6db9 100644
--- a/_api-reference/cat/cat-shards.md
+++ b/_api-reference/cat/cat-shards.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -46,7 +46,7 @@ The following table lists the available query parameters. All query parameters a
| `help` | Boolean | Returns help information. | `false` |
| `local` | Boolean | Returns local information but does not retrieve the state from the cluster manager node. | `false` |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-snapshots.md b/_api-reference/cat/cat-snapshots.md
index 47e1ff22f2f..70c10adb96e 100644
--- a/_api-reference/cat/cat-snapshots.md
+++ b/_api-reference/cat/cat-snapshots.md
@@ -46,7 +46,7 @@ The following table lists the available query parameters.
| `help` | Boolean | Returns help information. | `false` |
| `ignore_unavailable` | Boolean | When `true`, the response does not include information from unavailable snapshots. | `false` |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-tasks.md b/_api-reference/cat/cat-tasks.md
index da267b71198..65e5975e148 100644
--- a/_api-reference/cat/cat-tasks.md
+++ b/_api-reference/cat/cat-tasks.md
@@ -33,7 +33,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
@@ -45,7 +45,7 @@ The following table lists the available query parameters. All query parameters a
| `nodes` | List | A comma-separated list of node IDs or names used to limit the returned information. Use `_local` to return information from the node to which you're connecting, specify a specific node from which to get information, or keep the parameter empty to get information from all nodes. | N/A |
| `parent_task_id` | String | The parent task identifier, which is used to limit the response. | N/A |
| `s` | List | A comma-separated list of column names or column aliases to sort by. | N/A |
-| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units]({{site.url}}{{site.baseurl}}/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
+| `time` | String | Specifies the time units, for example, `5d` or `7h`. For more information, see [Supported units](https://opensearch.org/docs/latest/api-reference/units/).
Valid values are: `nanos`, `micros`, `ms`, `s`, `m`, `h`, and `d`. | N/A |
| `v` | Boolean | Enables verbose mode, which displays column headers. | `false` |
diff --git a/_api-reference/cat/cat-templates.md b/_api-reference/cat/cat-templates.md
index 90d18384c82..183396d56d9 100644
--- a/_api-reference/cat/cat-templates.md
+++ b/_api-reference/cat/cat-templates.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/cat/cat-thread-pool.md b/_api-reference/cat/cat-thread-pool.md
index dec78c4b15b..f343cb621ea 100644
--- a/_api-reference/cat/cat-thread-pool.md
+++ b/_api-reference/cat/cat-thread-pool.md
@@ -35,7 +35,7 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/document-apis/mtermvectors.md b/_api-reference/document-apis/mtermvectors.md
index 36cdfabe476..ddf96b62461 100644
--- a/_api-reference/document-apis/mtermvectors.md
+++ b/_api-reference/document-apis/mtermvectors.md
@@ -28,7 +28,7 @@ component: path_parameters
-->
## Path parameters
-The following table lists the available path parameters. All path parameters are optional.
+The following table lists the available path parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
@@ -43,7 +43,7 @@ columns: Parameter, Data type, Description
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
diff --git a/_api-reference/security/authentication/auth-info.md b/_api-reference/security/authentication/auth-info.md
index bd1b05fac4c..9c043662f38 100644
--- a/_api-reference/security/authentication/auth-info.md
+++ b/_api-reference/security/authentication/auth-info.md
@@ -29,7 +29,7 @@ component: query_parameters
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
diff --git a/_api-reference/snapshots/clone-snapshot.md b/_api-reference/snapshots/clone-snapshot.md
index da026bcf95c..201f9b2a5d6 100644
--- a/_api-reference/snapshots/clone-snapshot.md
+++ b/_api-reference/snapshots/clone-snapshot.md
@@ -46,11 +46,11 @@ include_deprecated: false
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
-| `cluster_manager_timeout` | String | The amount of time to wait for a response from the cluster manager node. For more information about supported time units, see [Common parameters]({{site.url}}{{site.baseurl}}/api-reference/common-parameters/#time-units). |
+| `cluster_manager_timeout` | String | The amount of time to wait for a response from the cluster manager node. For more information about supported time units, see [Common parameters](https://opensearch.org/docs/latest/api-reference/common-parameters/#time-units). |
diff --git a/_api-reference/tasks/cancel-tasks.md b/_api-reference/tasks/cancel-tasks.md
index ebffd3dcde0..ad04f5d612c 100644
--- a/_api-reference/tasks/cancel-tasks.md
+++ b/_api-reference/tasks/cancel-tasks.md
@@ -29,7 +29,7 @@ component: path_parameters
-->
## Path parameters
-The following table lists the available path parameters. All path parameters are optional.
+The following table lists the available path parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
@@ -43,7 +43,7 @@ component: query_parameters
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description |
| :--- | :--- | :--- |
diff --git a/_api-reference/tasks/get-tasks.md b/_api-reference/tasks/get-tasks.md
index 416614b37ae..9e227adc03f 100644
--- a/_api-reference/tasks/get-tasks.md
+++ b/_api-reference/tasks/get-tasks.md
@@ -41,7 +41,7 @@ component: query_parameters
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/_api-reference/tasks/list-tasks.md b/_api-reference/tasks/list-tasks.md
index 396b3e60ce6..4cb9c2997b4 100644
--- a/_api-reference/tasks/list-tasks.md
+++ b/_api-reference/tasks/list-tasks.md
@@ -27,7 +27,7 @@ component: query_parameters
-->
## Query parameters
-The following table lists the available query parameters. All query parameters are optional.
+The following table lists the available query parameters.
| Parameter | Data type | Description | Default |
| :--- | :--- | :--- | :--- |
diff --git a/spec-insert/lib/api/action.rb b/spec-insert/lib/api/action.rb
index f0a8fdcf1df..b6a5b5f9661 100644
--- a/spec-insert/lib/api/action.rb
+++ b/spec-insert/lib/api/action.rb
@@ -103,6 +103,26 @@ def deprecated; @spec.deprecated; end
# @return [String] Deprecation message
def deprecation_message; @spec['x-deprecation-message']; end
+ def self.find_by_rest(rest_line)
+ method, raw_path = rest_line.strip.split(' ', 2)
+ return nil unless method && raw_path
+
+ # Remove query parameters
+ path = raw_path.split('?').first
+
+ all.find do |action|
+ action.operations.any? do |op|
+ op.http_verb.casecmp?(method) &&
+ path_template_matches?(op.url, path)
+ end
+ end
+ end
+
+ def self.path_template_matches?(template, actual)
+ # "/{index}/_doc/{id}" => "^/[^/]+/_doc/[^/]+$"
+ regex = Regexp.new("^" + template.gsub(/\{[^\/]+\}/, '[^/]+') + "$")
+ regex.match?(actual)
+ end
# @return [String] API reference
def api_reference; @operation.external_docs.url; end
end
diff --git a/spec-insert/lib/doc_processor.rb b/spec-insert/lib/doc_processor.rb
index 8140b85102b..0edab19525a 100644
--- a/spec-insert/lib/doc_processor.rb
+++ b/spec-insert/lib/doc_processor.rb
@@ -53,8 +53,9 @@ def find_insertions(lines)
start_indices.zip(end_indices).map do |start, finish|
args = InsertArguments.from_marker(lines[start..finish])
+ next nil if args.skip?
[start, finish, SpecInsert.new(args)]
- end
+ end.compact
end
# @param [Array] start_indices
diff --git a/spec-insert/lib/insert_arguments.rb b/spec-insert/lib/insert_arguments.rb
index aa05cc01df1..737a136df34 100644
--- a/spec-insert/lib/insert_arguments.rb
+++ b/spec-insert/lib/insert_arguments.rb
@@ -2,11 +2,13 @@
require_relative 'utils'
require_relative 'spec_insert_error'
-
+require 'json'
# Doc Insert Arguments
class InsertArguments
attr_reader :raw
+ Rest = Struct.new(:verb, :path, :query, :body, :raw_lines, keyword_init:true)
+
# @param [Hash] args raw arguments read from the doc insert marker
def initialize(args)
@raw = args.to_h.with_indifferent_access
@@ -15,17 +17,52 @@ def initialize(args)
# @param [Array] lines the lines between ""
# @return [InsertArguments]
def self.from_marker(lines)
+ # Extract lines between start and end marker
end_index = lines.each_with_index.find { |line, _index| line.match?(/^\s*-->/) }&.last&.- 1
- args = lines[1..end_index].filter { |line| line.include?(':') }.to_h do |line|
- key, value = line.split(':')
- [key.strip, value.strip]
+ args = {}
+ i = 1
+
+ while i <= end_index
+ line = lines[i]
+ next unless line.include?(':')
+
+ key, value = line.split(':', 2)
+ key = key.strip
+ value = value.strip
+
+ if value == '|'
+ # Multi-line block value
+ multiline_value = []
+ i += 1
+ while i <= end_index
+ line = lines[i]
+ break if line.match?(/^\s*\w+:/) # Stop at new top-level key
+ multiline_value << line.rstrip
+ i += 1
+ end
+ args[key] = multiline_value.join("\n")
+ next
+ else
+ args[key] = value
+ end
+ i += 1
end
+
new(args)
end
# @return [String]
def api
- @raw['api']
+ return @raw['api'] if @raw['api'].present?
+
+ if rest_line = rest&.raw_lines&.first
+ inferred_action = Api::Action.find_by_rest(rest_line)
+ raise SpecInsertError, "Could not infer API from rest line: #{rest_line}" unless inferred_action
+
+ return inferred_action.full_name
+ end
+
+ nil
end
# @return [String]
@@ -41,11 +78,19 @@ def columns
parse_array(@raw['columns']) || []
end
+ def skip?
+ parse_boolean(@raw['skip'], default: false)
+ end
+
# @return [Boolean]
def pretty
parse_boolean(@raw['pretty'], default: false)
end
+ def include_client_setup
+ parse_boolean(@raw['include_client_setup'], default: false)
+ end
+
# @return [Boolean]
def include_global
parse_boolean(@raw['include_global'], default: false)
@@ -61,6 +106,34 @@ def omit_header
parse_boolean(@raw['omit_header'], default: false)
end
+ # @return [Rest, nil]
+ def rest
+ lines = @raw['rest']&.split("\n")&.map(&:strip) || []
+ return nil if lines.empty?
+
+ verb, full_path = lines.first.to_s.split
+ path, query_string = full_path.to_s.split('?', 2)
+
+ query = (query_string || "").split('&').to_h do |pair|
+ k, v = pair.split('=', 2)
+ [k, v || "true"]
+ end
+
+ body = begin
+ JSON.parse(@raw['body']) if @raw['body']
+ rescue JSON::ParserError
+ @raw['body']
+ end
+
+ Rest.new(
+ verb: verb,
+ path: path,
+ query: query,
+ body: body,
+ raw_lines: lines
+ )
+ end
+
private
# @param [String] value comma-separated array
diff --git a/spec-insert/lib/jekyll-spec-insert.rb b/spec-insert/lib/jekyll-spec-insert.rb
index f474fdd1235..1ac8d4ea884 100644
--- a/spec-insert/lib/jekyll-spec-insert.rb
+++ b/spec-insert/lib/jekyll-spec-insert.rb
@@ -30,6 +30,7 @@ def self.process_file(file, fail_on_error: false)
raise e if fail_on_error
relative_path = Pathname(file).relative_path_from(Pathname.new(Dir.pwd))
Jekyll.logger.error "Error processing #{relative_path}: #{e.message}"
+ Jekyll.logger.error "Error backtrace: #{e.backtrace.join("\n")}"
end
def self.watch(fail_on_error: false)
@@ -43,4 +44,4 @@ def self.watch(fail_on_error: false)
trap('TERM') { exit }
sleep
end
-end
+end
\ No newline at end of file
diff --git a/spec-insert/lib/renderers/example_code.rb b/spec-insert/lib/renderers/example_code.rb
new file mode 100644
index 00000000000..301e2b76203
--- /dev/null
+++ b/spec-insert/lib/renderers/example_code.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'json'
+require_relative 'example_code_python'
+
+class ExampleCode < BaseMustacheRenderer
+ self.template_file = "#{__dir__}/templates/example_code.mustache"
+
+ def initialize(action, args)
+ super(action, args)
+ end
+
+ def rest_lines
+ @args.rest.raw_lines
+ end
+
+ def rest_code
+ base = rest_lines.join("\n")
+ body = @args.rest.body
+ if body
+ body.is_a?(String) ? base + "\n" + body : base + "\n" + JSON.pretty_generate(body)
+ else
+ base
+ end
+ end
+
+ def python_code
+ ExampleCodePython.new(@action, @args).render
+ end
+end
diff --git a/spec-insert/lib/renderers/example_code_python.rb b/spec-insert/lib/renderers/example_code_python.rb
new file mode 100644
index 00000000000..0e3028c7487
--- /dev/null
+++ b/spec-insert/lib/renderers/example_code_python.rb
@@ -0,0 +1,157 @@
+require 'json'
+
+class ExampleCodePython < BaseMustacheRenderer
+ self.template_file = "#{__dir__}/templates/example_code.python.mustache"
+
+ def initialize(action, args)
+ super(action, args)
+ end
+
+ def call_code
+ return "# Invalid action" unless @action&.full_name
+ client_setup = <<~PYTHON
+ from opensearchpy import OpenSearch
+
+ host = 'localhost'
+ port = 9200
+ auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
+ ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.
+
+ # Create the client with SSL/TLS enabled, but hostname verification disabled.
+ client = OpenSearch(
+ hosts = [{'host': host, 'port': port}],
+ http_compress = True, # enables gzip compression for request bodies
+ http_auth = auth,
+ use_ssl = True,
+ verify_certs = True,
+ ssl_assert_hostname = False,
+ ssl_show_warn = False,
+ ca_certs = ca_certs_path
+ )
+
+ PYTHON
+
+ parts = @action.full_name.split('.')
+ client_call = "client"
+
+ if parts.length == 2
+ namespace, method = parts
+ client_call += ".#{namespace}.#{method}"
+ else
+ namespace = parts[0]
+ client_call += ".#{namespace}"
+ end
+
+ args = []
+
+ rest = @args.rest
+ http_verb = rest.verb
+ full_path = [rest.path, rest.query&.map { |k,v| "#{k}=#{v}" }.join('&')].compact.join('?')
+ path_part, query_string = full_path.to_s.split('?', 2)
+ path_values = path_part.split('/').reject(&:empty?)
+
+ spec_path = match_spec_path(full_path)
+ spec_parts = spec_path.split('/').reject(&:empty?)
+
+ param_mapping = {}
+ spec_parts.each_with_index do |part, i|
+ if part =~ /\{(.+?)\}/ && path_values[i]
+ param_mapping[$1] = path_values[i]
+ end
+ end
+
+ @action.path_parameters.each do |param|
+ if param_mapping.key?(param.name)
+ args << "#{param.name} = \"#{param_mapping[param.name]}\""
+ end
+ end
+
+ if query_string
+ query_pairs = query_string.split('&').map { |s| s.split('=', 2) }
+ query_hash = query_pairs.map do |k, v|
+ "\"#{k}\": \"#{v}\""
+ end.join(', ')
+ args << "params = { #{query_hash} }" unless query_hash.empty?
+ end
+
+ body = rest.body
+ if expects_body?(http_verb)
+ if body
+ raw_body = @args.raw['body']
+ begin
+ parsed = JSON.parse(raw_body)
+ pretty = JSON.pretty_generate(parsed).gsub(/^/, ' ')
+ args << "body = #{pretty}"
+ rescue JSON::ParserError
+ if raw_body.include?("\n")
+ args << "body = '''\n#{raw_body.rstrip}\n'''"
+ else
+ args << "body = #{JSON.dump(raw_body)}"
+ end
+ end
+ else
+ args << 'body = { "Insert body here" }'
+ end
+ end
+
+ python_setup = if args.empty?
+ "response = #{client_call}()"
+ else
+ final_args = args.map { |line| " #{line}" }.join(",\n")
+ <<~PYTHON
+
+ response = #{client_call}(
+ #{final_args}
+ )
+ PYTHON
+ end
+ if @args.include_client_setup
+ client_setup + python_setup
+ else
+ python_setup
+ end
+ end
+
+ private
+
+ def expects_body?(verb)
+ verb = verb.downcase
+ @action.operations.any? do |op|
+ op.http_verb.to_s.downcase == verb &&
+ op.spec&.requestBody &&
+ op.spec.requestBody.respond_to?(:content)
+ end
+ end
+
+ def match_spec_path(full_path)
+ request_path = full_path.split('?').first
+ request_segments = request_path.split('/').reject(&:empty?)
+
+ best = ''
+ best_score = -1
+
+ @action.urls.each do |spec_path|
+ spec_segments = spec_path.split('/').reject(&:empty?)
+ next unless spec_segments.size == request_segments.size
+
+ score = 0
+ spec_segments.each_with_index do |seg, i|
+ if seg.start_with?('{')
+ score += 1
+ elsif seg == request_segments[i]
+ score += 2
+ else
+ score = -1
+ break
+ end
+ end
+
+ if score > best_score
+ best = spec_path
+ best_score = score
+ end
+ end
+
+ best
+ end
+end
diff --git a/spec-insert/lib/renderers/spec_insert.rb b/spec-insert/lib/renderers/spec_insert.rb
index 87289a9baf8..662da7fc1c9 100644
--- a/spec-insert/lib/renderers/spec_insert.rb
+++ b/spec-insert/lib/renderers/spec_insert.rb
@@ -7,6 +7,7 @@
require_relative 'path_parameters'
require_relative 'query_parameters'
require_relative 'body_parameters'
+require_relative 'example_code'
# Class to render spec insertions
class SpecInsert < BaseMustacheRenderer
@@ -16,18 +17,25 @@ class SpecInsert < BaseMustacheRenderer
def initialize(args)
action = Api::Action.by_full_name[args.api]
super(action, args)
- raise SpecInsertError, '`api` argument not specified.' unless @args.api
+ raise SpecInsertError, '`api` argument could not be resolved.' unless @action
raise SpecInsertError, "API Action '#{@args.api}' does not exist in the spec." unless @action
end
def arguments
- @args.raw.map { |key, value| { key:, value: } }
+ @args.raw.map do |key, value|
+ if value.is_a?(String) && value.include?("\n")
+ { key: key, value: "|\n" + value }
+ else
+ { key: key, value: value }
+ end
+ end
end
def api; @args.api end
def component; @args.component end
def content
+ return "" if @args.skip?
raise SpecInsertError, '`component` argument not specified.' unless @args.component
case @args.component.to_sym
when :query_parameters
@@ -40,8 +48,10 @@ def content
BodyParameters.new(@action, @args, is_request: true).render
when :response_body_parameters
BodyParameters.new(@action, @args, is_request: false).render
+ when :example_code
+ ExampleCode.new(@action, @args).render
else
- raise SpecInsertError, "Invalid component: #{@args.component}"
+ raise SpecInsertError, "Invalid component: #{@args.component}, from spec_insert.rb "
end
end
end
diff --git a/spec-insert/lib/renderers/templates/example_code.mustache b/spec-insert/lib/renderers/templates/example_code.mustache
new file mode 100644
index 00000000000..5076450346d
--- /dev/null
+++ b/spec-insert/lib/renderers/templates/example_code.mustache
@@ -0,0 +1,11 @@
+{% capture step1_rest %}
+{{{rest_code}}}
+{% endcapture %}
+
+{% capture step1_python %}
+{{{python_code}}}
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
\ No newline at end of file
diff --git a/spec-insert/lib/renderers/templates/example_code.python.mustache b/spec-insert/lib/renderers/templates/example_code.python.mustache
new file mode 100644
index 00000000000..afc70070b77
--- /dev/null
+++ b/spec-insert/lib/renderers/templates/example_code.python.mustache
@@ -0,0 +1,3 @@
+{{! example_code.python.mustache }}
+
+{{{call_code}}}
\ No newline at end of file
diff --git a/spec-insert/lib/utils.rb b/spec-insert/lib/utils.rb
index 22bd273db2b..8f53d71931f 100644
--- a/spec-insert/lib/utils.rb
+++ b/spec-insert/lib/utils.rb
@@ -13,7 +13,8 @@ module Utils
'query_parameters' => 'Query Parameters',
'path_parameters' => 'Path Parameters',
'request_body_parameters' => 'Request Body Parameters',
- 'response_body_parameters' => 'Response Body Parameters'
+ 'response_body_parameters' => 'Response Body Parameters',
+ 'example_code' => 'Example Code'
}.freeze
# @return [Array] list of markdown files to insert the spec components into
diff --git a/spec-insert/spec/_fixtures/expected_output/example_code.md b/spec-insert/spec/_fixtures/expected_output/example_code.md
new file mode 100644
index 00000000000..cce9be74519
--- /dev/null
+++ b/spec-insert/spec/_fixtures/expected_output/example_code.md
@@ -0,0 +1,229 @@
+
+{% capture step1_rest %}
+GET /_cat/health?pretty=true&human=false
+{% endcapture %}
+
+{% capture step1_python %}
+
+from opensearchpy import OpenSearch
+
+host = 'localhost'
+port = 9200
+auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
+ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.
+
+# Create the client with SSL/TLS enabled, but hostname verification disabled.
+client = OpenSearch(
+ hosts = [{'host': host, 'port': port}],
+ http_compress = True, # enables gzip compression for request bodies
+ http_auth = auth,
+ use_ssl = True,
+ verify_certs = True,
+ ssl_assert_hostname = False,
+ ssl_show_warn = False,
+ ca_certs = ca_certs_path
+)
+
+
+response = client.cat.health(
+ params = { "pretty": "true", "human": "false" }
+)
+
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
+
+
+
+{% capture step1_rest %}
+GET /{index}/_search?analyzer=standard&expand_wildcards=all
+{% endcapture %}
+
+{% capture step1_python %}
+
+
+response = client.search(
+ index = "{index}",
+ params = { "analyzer": "standard", "expand_wildcards": "all" }
+)
+
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
+
+
+
+
+
+
+{% capture step1_rest %}
+PUT /_settings?expand_wildcards=all&analyze_wildcard
+{
+ "index": {
+ "number_of_replicas": 2
+ }
+}
+{% endcapture %}
+
+{% capture step1_python %}
+
+
+response = client.indices.put_settings(
+ params = { "expand_wildcards": "all", "analyze_wildcard": "true" },
+ body = {
+ "index": {
+ "number_of_replicas": 2
+ }
+ }
+)
+
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
+
+
+
+{% capture step1_rest %}
+POST /_bulk?expand_wildcards=all
+{"index":{"_index":"test","_id":"1"}}
+{"field1":"value1"}
+{"delete":{"_index":"test","_id":"2"}}
+{% endcapture %}
+
+{% capture step1_python %}
+
+from opensearchpy import OpenSearch
+
+host = 'localhost'
+port = 9200
+auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
+ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.
+
+# Create the client with SSL/TLS enabled, but hostname verification disabled.
+client = OpenSearch(
+ hosts = [{'host': host, 'port': port}],
+ http_compress = True, # enables gzip compression for request bodies
+ http_auth = auth,
+ use_ssl = True,
+ verify_certs = True,
+ ssl_assert_hostname = False,
+ ssl_show_warn = False,
+ ca_certs = ca_certs_path
+)
+
+
+response = client.bulk(
+ params = { "expand_wildcards": "all" },
+ body = '''
+{"index":{"_index":"test","_id":"1"}}
+{"field1":"value1"}
+{"delete":{"_index":"test","_id":"2"}}
+'''
+)
+
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
+
+
+
+{% capture step1_rest %}
+POST /_bulk?expand_wildcards=all
+{ "delete": { "_index": "movies", "_id": "tt2229499" } }
+{ "index": { "_index": "movies", "_id": "tt1979320" } }
+{ "title": "Rush", "year": 2013 }
+{ "create": { "_index": "movies", "_id": "tt1392214" } }
+{ "title": "Prisoners", "year": 2013 }
+{ "update": { "_index": "movies", "_id": "tt0816711" } }
+{ "doc" : { "title": "World War Z" } }
+{% endcapture %}
+
+{% capture step1_python %}
+
+from opensearchpy import OpenSearch
+
+host = 'localhost'
+port = 9200
+auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
+ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.
+
+# Create the client with SSL/TLS enabled, but hostname verification disabled.
+client = OpenSearch(
+ hosts = [{'host': host, 'port': port}],
+ http_compress = True, # enables gzip compression for request bodies
+ http_auth = auth,
+ use_ssl = True,
+ verify_certs = True,
+ ssl_assert_hostname = False,
+ ssl_show_warn = False,
+ ca_certs = ca_certs_path
+)
+
+
+response = client.bulk(
+ params = { "expand_wildcards": "all" },
+ body = '''
+{ "delete": { "_index": "movies", "_id": "tt2229499" } }
+{ "index": { "_index": "movies", "_id": "tt1979320" } }
+{ "title": "Rush", "year": 2013 }
+{ "create": { "_index": "movies", "_id": "tt1392214" } }
+{ "title": "Prisoners", "year": 2013 }
+{ "update": { "_index": "movies", "_id": "tt0816711" } }
+{ "doc" : { "title": "World War Z" } }
+'''
+)
+
+{% endcapture %}
+
+{% include code-block.html
+ rest=step1_rest
+ python=step1_python %}
+
diff --git a/spec-insert/spec/_fixtures/input/example_code.md b/spec-insert/spec/_fixtures/input/example_code.md
new file mode 100644
index 00000000000..ad91834cd78
--- /dev/null
+++ b/spec-insert/spec/_fixtures/input/example_code.md
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spec-insert/spec/_fixtures/opensearch_spec.yaml b/spec-insert/spec/_fixtures/opensearch_spec.yaml
index b95265eb749..6acfa03404c 100644
--- a/spec-insert/spec/_fixtures/opensearch_spec.yaml
+++ b/spec-insert/spec/_fixtures/opensearch_spec.yaml
@@ -69,6 +69,8 @@ paths:
url: https://docs.opensearch.org/latest/api-reference/index-apis/update-settings/
requestBody:
$ref: '#/components/requestBodies/indices.put_settings'
+ parameters:
+ - $ref: '#/components/parameters/cat.health___query.expand_wildcard'
responses:
'200':
$ref: '#/components/responses/indices.put_settings___200'
@@ -81,6 +83,8 @@ paths:
description: Allows to perform multiple index/update/delete operations in a single request.
externalDocs:
url: https://docs.opensearch.org/latest/api-reference/document-apis/bulk/
+ parameters:
+ - $ref: '#/components/parameters/cat.health___query.expand_wildcard'
requestBody:
$ref: '#/components/requestBodies/bulk'
components:
diff --git a/spec-insert/spec/doc_processor_spec.rb b/spec-insert/spec/doc_processor_spec.rb
index 4f2c46b9e7d..c5f2a99d2fc 100644
--- a/spec-insert/spec/doc_processor_spec.rb
+++ b/spec-insert/spec/doc_processor_spec.rb
@@ -25,4 +25,8 @@ def test_file(file_name)
it 'inserts the body param tables correctly' do
test_file('body_params_tables')
end
+
+ it 'inserts translations correctly' do
+ test_file('example_code')
+ end
end