@asyncapi/generator 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -0
- package/docs/configuration-file.md +1 -1
- package/docs/template.md +1 -1
- package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/package.json +1 -1
- package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/package.json +2 -2
- package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/package.json +2 -2
- package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/package.json +2 -2
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/README.md +66 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ClientClass.js +8 -2
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ClientClass.js.map +1 -1
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/Constructor.js +6 -2
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/Constructor.js.map +1 -1
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ReceiveOperationsDiscriminators.js +29 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ReceiveOperationsDiscriminators.js.map +1 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/RegisterReceiveOperations.js +66 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/RegisterReceiveOperations.js.map +1 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/client.py.js +83 -4
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/client.py.js.map +1 -1
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/ClientClass.js +5 -1
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/Constructor.js +4 -3
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/ReceiveOperationsDiscriminators.js +28 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/RegisterReceiveOperations.js +65 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/example-slack-with-routing.py +41 -0
- package/lib/templates/bakedInTemplates/core-template-client-websocket-python/package.json +2 -2
- package/lib/templates/config/loader.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,77 @@
|
|
|
1
1
|
# @asyncapi/generator
|
|
2
2
|
|
|
3
|
+
## 3.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2bfad27: Fix generator handling of template parameters with `false` default values, ensuring defaults are correctly injected and conditional generation works as expected.
|
|
8
|
+
|
|
9
|
+
## 3.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 11a1b8d: - **Updated Component**: `OnMessage` (Python) - Added discriminator-based routing logic that automatically dispatches messages to operation-specific handlers before falling back to generic handlers
|
|
14
|
+
|
|
15
|
+
- **New Helpers**:
|
|
16
|
+
- `getMessageDiscriminatorData` - Extracts discriminator key and value from individual messages
|
|
17
|
+
- `getMessageDiscriminatorsFromOperations` - Collects all discriminator metadata from receive operations
|
|
18
|
+
- Enhanced Python webSocket client generation with **automatic operation-based message routing**:
|
|
19
|
+
|
|
20
|
+
## How python routing works
|
|
21
|
+
|
|
22
|
+
- Generated WebSocket clients now automatically route incoming messages to operation-specific handlers based on message discriminators. Users can register handlers for specific message types without manually parsing or filtering messages.
|
|
23
|
+
- When a message arrives, the client checks it against registered discriminators (e.g., `type: "hello"`, `type: "events_api"`)
|
|
24
|
+
- If a match is found, the message is routed to the specific operation handler (e.g., `onHelloMessage`, `onEvent`)
|
|
25
|
+
- If no match is found, the message falls back to generic message handlers
|
|
26
|
+
- This enables clean separation of message handling logic based on message types
|
|
27
|
+
|
|
28
|
+
> `discriminator` is a `string` field that you can add to any AsyncAPI Schema. This also means that it is limited to AsyncAPI Schema only, and it won't work with other schema formats, like for example, Avro.
|
|
29
|
+
|
|
30
|
+
The implementation automatically derives discriminator information from your AsyncAPI document:
|
|
31
|
+
|
|
32
|
+
- Discriminator `key` is extracted from the `discriminator` field in your AsyncAPI spec
|
|
33
|
+
- Discriminator `value` is extracted from the `const` property defined in message schemas
|
|
34
|
+
|
|
35
|
+
Example AsyncAPI Schema with `discriminator` and `const`:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
schemas:
|
|
39
|
+
hello:
|
|
40
|
+
type: object
|
|
41
|
+
discriminator: type # you specify name of property
|
|
42
|
+
properties:
|
|
43
|
+
type:
|
|
44
|
+
type: string
|
|
45
|
+
const: hello # you specify the value of the discriminator property that is used for routing
|
|
46
|
+
description: A hello string confirming WebSocket connection
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Fallback
|
|
50
|
+
|
|
51
|
+
When defaults aren't available in the AsyncAPI document, users must provide **both** `discriminator_key` and `discriminator_value` when registering handlers. Providing only one parameter is not supported - you must provide either both or neither.
|
|
52
|
+
|
|
53
|
+
> **Why this limitation exists**: When a receive operation has multiple messages sharing the same discriminator key (e.g., all use `"type"` field), we need the specific value (e.g., `"hello"`, `"disconnect"`) to distinguish between them. Without both pieces of information, the routing becomes ambiguous.
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# Default case - discriminator info auto-derived from AsyncAPI doc
|
|
59
|
+
client.register_on_hello_message_handler(my_handler)
|
|
60
|
+
|
|
61
|
+
# Custom case - must provide both key AND value
|
|
62
|
+
client.register_on_hello_message_handler(
|
|
63
|
+
my_handler,
|
|
64
|
+
discriminator_key="message_type",
|
|
65
|
+
discriminator_value="custom_hello"
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Patch Changes
|
|
70
|
+
|
|
71
|
+
- Updated dependencies [11a1b8d]
|
|
72
|
+
- @asyncapi/generator-components@0.5.0
|
|
73
|
+
- @asyncapi/generator-helpers@1.1.0
|
|
74
|
+
|
|
3
75
|
## 3.0.1
|
|
4
76
|
|
|
5
77
|
### Patch Changes
|
|
@@ -159,7 +159,7 @@ The `generator` property from `package.json` file must contain a JSON object and
|
|
|
159
159
|
| `conditionalFiles[filePath].validation` | Object | The `validation` is a JSON Schema Draft 07 object. This JSON Schema definition will be applied to the JSON value resulting from the `subject` query. If validation doesn't have errors, the condition is met, and therefore the given file will be rendered. Otherwise, the file is ignored. Check [JSON Schema Validation](https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.6) for a list of all possible validation keywords. **Note: It is deprecated and will be removed with future releases. Use `conditionalGeneration` instead.** |
|
|
160
160
|
| `conditionalGeneration` | Object[String, `{ subject?: String, parameter?: String, validation: Object }`] | An object containing all the file paths or directory names that should be conditionally rendered. Each key represents a file path or directory name and each value must be an object with the keys `subject`, `parameter` and `validation`. You can use either subject or parameter according to the use case. The path should be relative to the `template` directory inside the template. **Note: conditionalGeneration and conditionalFile are mutually exclusive, which means both cannot be configured at the same time in the template**. |
|
|
161
161
|
| `conditionalGeneration[filePath/directoryName].subject` | String | The `subject` is a [JMESPath](http://jmespath.org/) query to grab the value you want to apply the condition to. It queries an object with the whole AsyncAPI document and, when specified, the given server. The object looks like this: `{ asyncapi: { ... }, server: { ... } }`. If the template supports the `server` parameter, you can access server details like, for example, protocol this way: `server.protocol`. During validation with `conditionalGeneration`, only the server that the template user selected is available in the specification file. For more information about the `server` parameter [read about special parameters](#special-parameters). |
|
|
162
|
-
| `conditionalGeneration[filePath/directoryName].parameter` | String | The `parameter` is the name of a custom template parameter passed through `templateParams` that controls whether a specific file or folder should be included in the generated output. You must define a `validation` rule using a JSON Schema fragment to apply the condition. For example, if you define `"parameter": "includeDocs"` with `"validation": { "const": true }`, the corresponding folder (e.g., `docs/`) will only be generated when the user passes `{ includeDocs: true }`. If `includeDocs` is `false`, it will be skipped. |
|
|
162
|
+
| `conditionalGeneration[filePath/directoryName].parameter` | String | The `parameter` is the name of a custom template parameter passed through `templateParams` that controls whether a specific file or folder should be included in the generated output. You must define a `validation` rule using a JSON Schema fragment to apply the condition. For example, if you define `"parameter": "includeDocs"` with `"validation": { "const": true }`, the corresponding folder (e.g., `docs/`) will only be generated when the user passes `{ includeDocs: true }`. If `includeDocs` is `false`, it will be skipped. When you rely on a parameter here, make sure its default value declared in the `parameters` section uses the same data type your validation expects; mismatched types lead to failing conditions even when the defaults should allow generation. |
|
|
163
163
|
| `conditionalGeneration[filePath/directoryName].validation` | Object (JSON Schema fragment) | The validation defines the condition under which the file or directory will be generated. It must be a valid JSON Schema fragment that validates the value of the parameter. For example, if you want to include a folder only when includeDocs is true, use "validation": `{ "const": true }`. You can also use more complex validation logic, like "enum": ["yes", "true"] or "type": "string" with a "pattern" constraint. If the parameter fails validation, the file or folder will not be included in the generated output. This allows for powerful and flexible control over template generation based on user input. |
|
|
164
164
|
| `nonRenderableFiles` | [String] | A list of file paths or [globs](https://en.wikipedia.org/wiki/Glob_(programming)) that must be copied "as-is" to the target directory, i.e., without performing any rendering process. This is useful when you want to copy binary files. |
|
|
165
165
|
| `generator` | [String] | A string representing the generator version-range the template is compatible with. This value must follow the [semver](https://nodejs.dev/learn/semantic-versioning-using-npm) syntax. E.g., `>=1.0.0`, `>=1.0.0 <=2.0.0`, `~1.0.0`, `^1.0.0`, `1.0.0`, etc. [Read more about semver](https://docs.npmjs.com/about-semantic-versioning). |
|
package/docs/template.md
CHANGED
|
@@ -29,7 +29,7 @@ Baked-in templates benefit from:
|
|
|
29
29
|
|
|
30
30
|
In contrast, **standalone templates** (described below) are maintained as independent Node.js packages, may live in separate repositories, and can be managed or installed separately from the core generator.
|
|
31
31
|
|
|
32
|
-
Learn more from document [Baked-in Templates](
|
|
32
|
+
Learn more from document [Baked-in Templates](baked-in-templates).
|
|
33
33
|
|
|
34
34
|
### Standalone templates
|
|
35
35
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"lint:fix": "eslint --fix --max-warnings 0 --config ../../../../../../.eslintrc --ignore-path ../../../../../../.eslintignore ."
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@asyncapi/generator-helpers": "1.0
|
|
21
|
+
"@asyncapi/generator-helpers": "1.1.0",
|
|
22
22
|
"@asyncapi/generator-react-sdk": "^1.1.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@asyncapi/generator-react-sdk": "*",
|
|
15
|
-
"@asyncapi/generator-helpers": "1.0
|
|
16
|
-
"@asyncapi/generator-components": "0.
|
|
15
|
+
"@asyncapi/generator-helpers": "1.1.0",
|
|
16
|
+
"@asyncapi/generator-components": "0.5.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@asyncapi/parser": "^3.4.0",
|
package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/package.json
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"lint:fix": "eslint --fix --max-warnings 0 --config ../../../../../../.eslintrc --ignore-path ../../../../../../.eslintignore ."
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@asyncapi/generator-helpers": "1.0
|
|
22
|
-
"@asyncapi/generator-components": "0.
|
|
21
|
+
"@asyncapi/generator-helpers": "1.1.0",
|
|
22
|
+
"@asyncapi/generator-components": "0.5.0",
|
|
23
23
|
"@asyncapi/generator-react-sdk": "^1.1.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/package.json
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"author": "Lukasz Gornicki <lpgornicki@gmail.com>",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@asyncapi/generator-helpers": "1.0
|
|
14
|
+
"@asyncapi/generator-helpers": "1.1.0",
|
|
15
15
|
"@asyncapi/generator-react-sdk": "*",
|
|
16
|
-
"@asyncapi/generator-components": "0.
|
|
16
|
+
"@asyncapi/generator-components": "0.5.0",
|
|
17
17
|
"@asyncapi/keeper": "0.5.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
@@ -66,3 +66,69 @@ You can use our AsyncAPI's credentials to access different set of events produce
|
|
|
66
66
|
{"type":"hello","num_connections":1,"debug_info":{"host":"applink-3","build_number":118,"approximate_connection_time":18060},"connection_info":{"app_id":"A08NKKBFGBD"}}
|
|
67
67
|
```
|
|
68
68
|
If you did not receive it, you probably connect with wrong credentials. Remember that generated `ticket` can be used only once to establish a websocket connection.
|
|
69
|
+
|
|
70
|
+
## Client for Slack with Auto-Routing
|
|
71
|
+
|
|
72
|
+
To run the Slack Client example with auto-routing, first follow the "Client for Slack" setup above (generate credentials and install dependencies), then:
|
|
73
|
+
- Use `example-slack-with-routing.py` instead of `example-slack.py`.
|
|
74
|
+
- This example demonstrates auto-routing of messages to registered handlers for different event types (hello, event, disconnect, and unrecognized messages). The client automatically dispatches incoming messages based on their type without manual parsing.
|
|
75
|
+
|
|
76
|
+
1. Start the example that uses generated client with auto-routing. Examine events, and modify example as you want:
|
|
77
|
+
|
|
78
|
+
Linux/MacOs
|
|
79
|
+
```bash
|
|
80
|
+
TICKET=6b150bb1-82b4-457f-a09d-6ff0af1fd2d1 APP_ID=00dfdcccb53a2645dd3f1773fcb10fa7b0a598cf333a990a9db12375ef1865dd python example-slack-with-routing.py
|
|
81
|
+
```
|
|
82
|
+
Windows
|
|
83
|
+
```powershell
|
|
84
|
+
$env:TICKET="dcaa9dc7-b728-40dd-ac40-16dd5f2f8710"; $env:APP_ID="00dfdcccb53a2645dd3f1773fcb10fa7b0a598cf333a990a9db12375ef1865dd"; python example-slack-with-routing.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
1. By default, `discriminator_key` is derived from the discriminator field, and `discriminator_value` from the corresponding `const` in the AsyncAPI document. For non-default cases, users must provide both `discriminator_key` and `discriminator_value` explicitly in register_handlers. Partial inputs are not supported to avoid ambiguity in message routing.
|
|
88
|
+
|
|
89
|
+
### How Routing Works
|
|
90
|
+
|
|
91
|
+
- Generated WebSocket clients now automatically route incoming messages to operation-specific handlers based on message discriminators. Users can register handlers for specific message types without manually parsing or filtering messages.
|
|
92
|
+
- When a message arrives, the client checks it against registered discriminators (e.g., `type: "hello"`, `type: "events_api"`)
|
|
93
|
+
- If a match is found, the message is routed to the specific operation handler (e.g., `onHelloMessage`, `onEvent`)
|
|
94
|
+
- If no match is found, the message falls back to generic message handlers
|
|
95
|
+
- This enables clean separation of message handling logic based on message types
|
|
96
|
+
|
|
97
|
+
> `discriminator` is a `string` field that you can add to any AsyncAPI Schema. This also means that it is limited to AsyncAPI Schema only, and it won't work with other schema formats, like for example, Avro.
|
|
98
|
+
|
|
99
|
+
The implementation automatically derives discriminator information from your AsyncAPI document:
|
|
100
|
+
- Discriminator `key` is extracted from the `discriminator` field in your AsyncAPI spec
|
|
101
|
+
- Discriminator `value` is extracted from the `const` property defined in message schemas
|
|
102
|
+
|
|
103
|
+
Example AsyncAPI Schema with `discriminator` and `const`:
|
|
104
|
+
```yaml
|
|
105
|
+
schemas:
|
|
106
|
+
hello:
|
|
107
|
+
type: object
|
|
108
|
+
discriminator: type # you specify name of property
|
|
109
|
+
properties:
|
|
110
|
+
type:
|
|
111
|
+
type: string
|
|
112
|
+
const: hello # you specify the value of the discriminator property that is used for routing
|
|
113
|
+
description: A hello string confirming WebSocket connection
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Fallback
|
|
117
|
+
|
|
118
|
+
When defaults aren't available in the AsyncAPI document, users must provide **both** `discriminator_key` and `discriminator_value` when registering handlers. Providing only one parameter is not supported - you must provide either both or neither.
|
|
119
|
+
|
|
120
|
+
> **Why this limitation exists**: When a receive operation has multiple messages sharing the same discriminator key (e.g., all use `"type"` field), we need the specific value (e.g., `"hello"`, `"disconnect"`) to distinguish between them. Without both pieces of information, the routing becomes ambiguous.
|
|
121
|
+
|
|
122
|
+
Example:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# Default case - discriminator info auto-derived from AsyncAPI doc
|
|
126
|
+
client.register_on_hello_message_handler(my_handler)
|
|
127
|
+
|
|
128
|
+
# Custom case - must provide both key AND value
|
|
129
|
+
client.register_on_hello_message_handler(
|
|
130
|
+
my_handler,
|
|
131
|
+
discriminator_key="message_type",
|
|
132
|
+
discriminator_value="custom_hello"
|
|
133
|
+
)
|
|
134
|
+
```
|
|
@@ -10,9 +10,11 @@ var Constructor = require('./Constructor.js');
|
|
|
10
10
|
var generatorComponents = require('@asyncapi/generator-components');
|
|
11
11
|
var RegisterOutgoingProcessor = require('./RegisterOutgoingProcessor.js');
|
|
12
12
|
var HandleError = require('./HandleError.js');
|
|
13
|
+
var RegisterReceiveOperations = require('./RegisterReceiveOperations.js');
|
|
13
14
|
var jsxRuntime = require('/home/runner/work/generator/generator/node_modules/react/cjs/react-jsx-runtime.production.min.js');
|
|
14
15
|
require('./QueryParamsArgumentsDocs.js');
|
|
15
16
|
require('./InitSignature.js');
|
|
17
|
+
require('./ReceiveOperationsDiscriminators.js');
|
|
16
18
|
|
|
17
19
|
function ClientClass({
|
|
18
20
|
asyncapi,
|
|
@@ -25,13 +27,15 @@ function ClientClass({
|
|
|
25
27
|
const serverUrl = generatorHelpers.getServerUrl(server);
|
|
26
28
|
const operations = asyncapi.operations();
|
|
27
29
|
const sendOperations = operations.filterBySend();
|
|
30
|
+
const receiveOperations = operations.filterByReceive();
|
|
28
31
|
return /*#__PURE__*/jsxRuntime.jsxs(generatorReactSdk.Text, {
|
|
29
32
|
children: [/*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
30
33
|
newLines: 2,
|
|
31
34
|
children: `class ${clientName}:`
|
|
32
35
|
}), /*#__PURE__*/jsxRuntime.jsx(Constructor.Constructor, {
|
|
33
36
|
serverUrl: serverUrl,
|
|
34
|
-
query: queryParams
|
|
37
|
+
query: queryParams,
|
|
38
|
+
receiveOperations: receiveOperations
|
|
35
39
|
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.Connect, {
|
|
36
40
|
language: "python",
|
|
37
41
|
title: title
|
|
@@ -50,7 +54,9 @@ function ClientClass({
|
|
|
50
54
|
methodName: "handle_message",
|
|
51
55
|
methodParams: ['self', 'message'],
|
|
52
56
|
preExecutionCode: "\"\"\"Pass the incoming message to all registered message handlers. \"\"\""
|
|
53
|
-
}), /*#__PURE__*/jsxRuntime.jsx(HandleError.HandleError, {}), /*#__PURE__*/jsxRuntime.jsx(
|
|
57
|
+
}), /*#__PURE__*/jsxRuntime.jsx(HandleError.HandleError, {}), /*#__PURE__*/jsxRuntime.jsx(RegisterReceiveOperations.RegisterReceiveOperations, {
|
|
58
|
+
receiveOperations: receiveOperations
|
|
59
|
+
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.SendOperations, {
|
|
54
60
|
language: "python",
|
|
55
61
|
sendOperations: sendOperations,
|
|
56
62
|
clientName: clientName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientClass.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/ClientClass.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName, getServerUrl, getServer, getQueryParams, getTitle } from '@asyncapi/generator-helpers';\nimport { Send } from './Send';\nimport { Constructor } from './Constructor';\nimport { CloseConnection, RegisterMessageHandler, RegisterErrorHandler, SendOperations, Connect, HandleMessage } from '@asyncapi/generator-components';\nimport { RegisterOutgoingProcessor } from './RegisterOutgoingProcessor';\nimport { HandleError } from './HandleError';\n\nexport function ClientClass({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const title = getTitle(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);\n const serverUrl = getServerUrl(server);\n const operations = asyncapi.operations();\n const sendOperations = operations.filterBySend();\n return (\n <Text>\n <Text newLines={2}>\n {`class ${clientName}:`}\n </Text>\n <Constructor serverUrl={serverUrl} query={queryParams} />\n <Connect language=\"python\" title={title} />\n <RegisterMessageHandler\n language=\"python\"\n methodName='register_message_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process incoming messages.\"\"\"'\n />\n <RegisterErrorHandler\n language=\"python\"\n methodName='register_error_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process errors.\"\"\"'\n />\n <RegisterOutgoingProcessor />\n <HandleMessage\n language=\"python\"\n methodName='handle_message'\n methodParams={['self', 'message']}\n preExecutionCode='\"\"\"Pass the incoming message to all registered message handlers. \"\"\"'\n />\n <HandleError />\n <SendOperations \n language=\"python\"\n sendOperations={sendOperations} \n clientName={clientName} \n />\n <Send sendOperations={sendOperations} />\n <CloseConnection \n language=\"python\" \n methodParams={['self']}\n preExecutionCode='\"\"\"Cleanly close the WebSocket connection.\"\"\"'\n />\n </Text>\n );\n}\n"],"names":["ClientClass","asyncapi","params","server","getServer","servers","title","getTitle","queryParams","getQueryParams","channels","clientName","getClientName","appendClientSuffix","customClientName","serverUrl","getServerUrl","operations","sendOperations","filterBySend","_jsxs","Text","children","_jsx","newLines","Constructor","query","Connect","language","RegisterMessageHandler","methodName","methodParams","preExecutionCode","RegisterErrorHandler","RegisterOutgoingProcessor","HandleMessage","HandleError","SendOperations","Send","CloseConnection"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClientClass.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/ClientClass.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName, getServerUrl, getServer, getQueryParams, getTitle } from '@asyncapi/generator-helpers';\nimport { Send } from './Send';\nimport { Constructor } from './Constructor';\nimport { CloseConnection, RegisterMessageHandler, RegisterErrorHandler, SendOperations, Connect, HandleMessage } from '@asyncapi/generator-components';\nimport { RegisterOutgoingProcessor } from './RegisterOutgoingProcessor';\nimport { HandleError } from './HandleError';\nimport { RegisterReceiveOperations } from './RegisterReceiveOperations';\n\nexport function ClientClass({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const title = getTitle(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);\n const serverUrl = getServerUrl(server);\n const operations = asyncapi.operations();\n const sendOperations = operations.filterBySend();\n const receiveOperations = operations.filterByReceive();\n\n return (\n <Text>\n <Text newLines={2}>\n {`class ${clientName}:`}\n </Text>\n <Constructor serverUrl={serverUrl} query={queryParams} receiveOperations={receiveOperations} />\n <Connect language=\"python\" title={title} />\n <RegisterMessageHandler\n language=\"python\"\n methodName='register_message_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process incoming messages.\"\"\"'\n />\n <RegisterErrorHandler\n language=\"python\"\n methodName='register_error_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process errors.\"\"\"'\n />\n <RegisterOutgoingProcessor />\n <HandleMessage\n language=\"python\"\n methodName='handle_message'\n methodParams={['self', 'message']}\n preExecutionCode='\"\"\"Pass the incoming message to all registered message handlers. \"\"\"'\n />\n <HandleError />\n <RegisterReceiveOperations receiveOperations={receiveOperations} />\n <SendOperations \n language=\"python\"\n sendOperations={sendOperations} \n clientName={clientName} \n />\n <Send sendOperations={sendOperations} />\n <CloseConnection \n language=\"python\" \n methodParams={['self']}\n preExecutionCode='\"\"\"Cleanly close the WebSocket connection.\"\"\"'\n />\n </Text>\n );\n}\n"],"names":["ClientClass","asyncapi","params","server","getServer","servers","title","getTitle","queryParams","getQueryParams","channels","clientName","getClientName","appendClientSuffix","customClientName","serverUrl","getServerUrl","operations","sendOperations","filterBySend","receiveOperations","filterByReceive","_jsxs","Text","children","_jsx","newLines","Constructor","query","Connect","language","RegisterMessageHandler","methodName","methodParams","preExecutionCode","RegisterErrorHandler","RegisterOutgoingProcessor","HandleMessage","HandleError","RegisterReceiveOperations","SendOperations","Send","CloseConnection"],"mappings":"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"}
|
|
@@ -7,11 +7,14 @@ var generatorReactSdk = require('@asyncapi/generator-react-sdk');
|
|
|
7
7
|
var generatorComponents = require('@asyncapi/generator-components');
|
|
8
8
|
var QueryParamsArgumentsDocs = require('./QueryParamsArgumentsDocs.js');
|
|
9
9
|
var InitSignature = require('./InitSignature.js');
|
|
10
|
+
var ReceiveOperationsDiscriminators = require('./ReceiveOperationsDiscriminators.js');
|
|
10
11
|
var jsxRuntime = require('/home/runner/work/generator/generator/node_modules/react/cjs/react-jsx-runtime.production.min.js');
|
|
12
|
+
require('@asyncapi/generator-helpers');
|
|
11
13
|
|
|
12
14
|
function Constructor({
|
|
13
15
|
serverUrl,
|
|
14
|
-
query
|
|
16
|
+
query,
|
|
17
|
+
receiveOperations
|
|
15
18
|
}) {
|
|
16
19
|
const queryParamsArray = query && Array.from(query.entries());
|
|
17
20
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
@@ -38,8 +41,9 @@ function Constructor({
|
|
|
38
41
|
self.error_handlers = [] # Callables for errors
|
|
39
42
|
self.outgoing_processors = [] # Callables to process outgoing messages
|
|
40
43
|
self._stop_event = threading.Event()
|
|
41
|
-
|
|
42
44
|
${query ? 'params = {}' : ''}`
|
|
45
|
+
}), /*#__PURE__*/jsxRuntime.jsx(ReceiveOperationsDiscriminators.ReceiveOperationsDiscriminators, {
|
|
46
|
+
receiveOperations: receiveOperations
|
|
43
47
|
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.QueryParamsVariables, {
|
|
44
48
|
language: "python",
|
|
45
49
|
queryParams: queryParamsArray
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constructor.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/Constructor.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { QueryParamsVariables } from '@asyncapi/generator-components';\nimport { QueryParamsArgumentsDocs } from './QueryParamsArgumentsDocs';\nimport { InitSignature } from './InitSignature';\n\nexport function Constructor({ serverUrl, query}) {\n const queryParamsArray = query && Array.from(query.entries());\n
|
|
1
|
+
{"version":3,"file":"Constructor.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/Constructor.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { QueryParamsVariables } from '@asyncapi/generator-components';\nimport { QueryParamsArgumentsDocs } from './QueryParamsArgumentsDocs';\nimport { InitSignature } from './InitSignature';\nimport { ReceiveOperationsDiscriminators } from './ReceiveOperationsDiscriminators';\n\nexport function Constructor({ serverUrl, query, receiveOperations }) {\n const queryParamsArray = query && Array.from(query.entries());\n\n return (\n <>\n <InitSignature queryParams={queryParamsArray} serverUrl={serverUrl} />\n <Text indent={2}>\n {`\n \"\"\"\n Constructor to initialize the WebSocket client.\n\n Args:\n url (str, optional): The WebSocket server URL. Use it if the server URL is \n different from the default one taken from the AsyncAPI document.`}\n </Text>\n <QueryParamsArgumentsDocs queryParams={queryParamsArray} />\n <Text indent={2}>\n {`\n \"\"\"\n self.ws_app = None # Instance of WebSocketApp\n self.message_handlers = [] # Callables for incoming messages\n self.error_handlers = [] # Callables for errors\n self.outgoing_processors = [] # Callables to process outgoing messages\n self._stop_event = threading.Event()\n ${ query ? 'params = {}' : ''}`\n }\n </Text>\n <ReceiveOperationsDiscriminators receiveOperations={receiveOperations} />\n <QueryParamsVariables\n language=\"python\"\n queryParams={queryParamsArray} \n />\n <Text newLines={2}>\n {`\n ${query ? 'qs = urlencode(params) if params else \"\"' : ''}\n ${query ? 'self.url = f\"{url}{f\\'?{qs}\\' if qs else \\'\\'}\"' : 'self.url = url'}`}\n </Text>\n </>\n );\n}"],"names":["Constructor","serverUrl","query","receiveOperations","queryParamsArray","Array","from","entries","_jsxs","_Fragment","children","_jsx","InitSignature","queryParams","Text","indent","QueryParamsArgumentsDocs","ReceiveOperationsDiscriminators","QueryParamsVariables","language","newLines"],"mappings":";;;;;;;;;;;;;AAMO,SAASA,WAAWA,CAAC;EAAEC,SAAS;EAAEC,KAAK;AAAEC,EAAAA,iBAAAA;AAAkB,CAAC,EAAE;AACnE,EAAA,MAAMC,gBAAgB,GAAGF,KAAK,IAAIG,KAAK,CAACC,IAAI,CAACJ,KAAK,CAACK,OAAO,EAAE,CAAC,CAAA;EAE7D,oBACEC,eAAA,CAAAC,mBAAA,EAAA;IAAAC,QAAA,EAAA,cACEC,cAAA,CAACC,2BAAa,EAAA;AAACC,MAAAA,WAAW,EAAET,gBAAiB;AAACH,MAAAA,SAAS,EAAEA,SAAAA;AAAU,KAAE,CAAC,eACtEU,cAAA,CAACG,sBAAI,EAAA;AAACC,MAAAA,MAAM,EAAE,CAAE;AAAAL,MAAAA,QAAA,EACb,CAAA;AACT;AACA;AACA;AACA;AACA;AACA,0EAAA,CAAA;AAA2E,KAC/D,CAAC,eACPC,cAAA,CAACK,iDAAwB,EAAA;AAACH,MAAAA,WAAW,EAAET,gBAAAA;AAAiB,KAAE,CAAC,eAC3DO,cAAA,CAACG,sBAAI,EAAA;AAACC,MAAAA,MAAM,EAAE,CAAE;AAAAL,MAAAA,QAAA,EACb,CAAA;AACT;AACA;AACA;AACA;AACA;AACA;AACA,MAAA,EAASR,KAAK,GAAG,aAAa,GAAG,EAAE,CAAA,CAAA;AAAE,KAEzB,CAAC,eACPS,cAAA,CAACM,+DAA+B,EAAA;AAACd,MAAAA,iBAAiB,EAAEA,iBAAAA;AAAkB,KAAE,CAAC,eACzEQ,cAAA,CAACO,wCAAoB,EAAA;AACnBC,MAAAA,QAAQ,EAAC,QAAQ;AACjBN,MAAAA,WAAW,EAAET,gBAAAA;AAAiB,KAC/B,CAAC,eACFO,cAAA,CAACG,sBAAI,EAAA;AAACM,MAAAA,QAAQ,EAAE,CAAE;AAAAV,MAAAA,QAAA,EACf,CAAA;AACT,QAAA,EAAUR,KAAK,GAAG,0CAA0C,GAAG,EAAE,CAAA;AACjE,QAAA,EAAUA,KAAK,GAAG,iDAAiD,GAAG,gBAAgB,CAAA,CAAA;AAAE,KAC5E,CAAC,CAAA;AAAA,GACP,CAAC,CAAA;AAEP;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('source-map-support/register');
|
|
6
|
+
var generatorReactSdk = require('@asyncapi/generator-react-sdk');
|
|
7
|
+
var generatorHelpers = require('@asyncapi/generator-helpers');
|
|
8
|
+
var jsxRuntime = require('/home/runner/work/generator/generator/node_modules/react/cjs/react-jsx-runtime.production.min.js');
|
|
9
|
+
|
|
10
|
+
function ReceiveOperationsDiscriminators({
|
|
11
|
+
receiveOperations
|
|
12
|
+
}) {
|
|
13
|
+
const hasOperations = Array.isArray(receiveOperations) && receiveOperations.length > 0;
|
|
14
|
+
if (!hasOperations) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const operationDiscriminators = generatorHelpers.getMessageDiscriminatorsFromOperations(receiveOperations);
|
|
18
|
+
const serializedDiscriminators = JSON.stringify(operationDiscriminators);
|
|
19
|
+
return /*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
20
|
+
indent: 2,
|
|
21
|
+
newLines: 2,
|
|
22
|
+
children: `
|
|
23
|
+
self.receive_operation_handlers = {}
|
|
24
|
+
self.receive_operation_discriminators = ${serializedDiscriminators}`
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports.ReceiveOperationsDiscriminators = ReceiveOperationsDiscriminators;
|
|
29
|
+
//# sourceMappingURL=ReceiveOperationsDiscriminators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReceiveOperationsDiscriminators.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/ReceiveOperationsDiscriminators.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { getMessageDiscriminatorsFromOperations } from '@asyncapi/generator-helpers';\n\n/**\n * Component that generates initialization code for receive operation discriminators.\n * \n * @param {Object} props - Component properties\n * @param {Array<Object>} [props.receiveOperations] - Receive operations from AsyncAPI document\n * @returns {React.Element|null} Rendered initialization code or null.\n */\nexport function ReceiveOperationsDiscriminators({ receiveOperations }) {\n const hasOperations = Array.isArray(receiveOperations) && receiveOperations.length > 0;\n if (!hasOperations) {\n return null;\n }\n\n const operationDiscriminators = getMessageDiscriminatorsFromOperations(receiveOperations);\n const serializedDiscriminators = JSON.stringify(operationDiscriminators);\n\n return (\n <Text indent={2} newLines={2}>\n {`\n self.receive_operation_handlers = {}\n self.receive_operation_discriminators = ${serializedDiscriminators}`\n }\n </Text>\n );\n}\n"],"names":["ReceiveOperationsDiscriminators","receiveOperations","hasOperations","Array","isArray","length","operationDiscriminators","getMessageDiscriminatorsFromOperations","serializedDiscriminators","JSON","stringify","_jsx","Text","indent","newLines","children"],"mappings":";;;;;;;;;AAUO,SAASA,+BAA+BA,CAAC;AAAEC,EAAAA,iBAAAA;AAAkB,CAAC,EAAE;AACrE,EAAA,MAAMC,aAAa,GAAGC,KAAK,CAACC,OAAO,CAACH,iBAAiB,CAAC,IAAIA,iBAAiB,CAACI,MAAM,GAAG,CAAC,CAAA;EACtF,IAAI,CAACH,aAAa,EAAE;AAClB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AAEA,EAAA,MAAMI,uBAAuB,GAAGC,uDAAsC,CAACN,iBAAiB,CAAC,CAAA;AACzF,EAAA,MAAMO,wBAAwB,GAAGC,IAAI,CAACC,SAAS,CAACJ,uBAAuB,CAAC,CAAA;EAExE,oBACEK,cAAA,CAACC,sBAAI,EAAA;AAACC,IAAAA,MAAM,EAAE,CAAE;AAACC,IAAAA,QAAQ,EAAE,CAAE;AAAAC,IAAAA,QAAA,EAC1B,CAAA;AACP;AACA,8CAAA,EAAgDP,wBAAwB,CAAA,CAAA;AAAE,GAEhE,CAAC,CAAA;AAEX;;;;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('source-map-support/register');
|
|
6
|
+
var generatorReactSdk = require('@asyncapi/generator-react-sdk');
|
|
7
|
+
var generatorHelpers = require('@asyncapi/generator-helpers');
|
|
8
|
+
var jsxRuntime = require('/home/runner/work/generator/generator/node_modules/react/cjs/react-jsx-runtime.production.min.js');
|
|
9
|
+
|
|
10
|
+
function RegisterReceiveOperations({
|
|
11
|
+
receiveOperations
|
|
12
|
+
}) {
|
|
13
|
+
if (!receiveOperations || receiveOperations.length === 0) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return receiveOperations.map(operation => {
|
|
17
|
+
const operationId = operation.id();
|
|
18
|
+
const methodName = `register_${generatorHelpers.toSnakeCase(operationId)}_handler`;
|
|
19
|
+
return /*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
20
|
+
indent: 2,
|
|
21
|
+
newLines: 2,
|
|
22
|
+
children: `def ${methodName}(self, handler, discriminator_key=None, discriminator_value=None):
|
|
23
|
+
"""
|
|
24
|
+
Register a handler for ${operationId} operation.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
handler (callable): Handler function that receives raw_message as argument
|
|
28
|
+
discriminator_key (str): Message field to use for routing (e.g., 'type', 'event_type')
|
|
29
|
+
discriminator_value (str): Expected value for routing (e.g., 'hello', 'user_joined')
|
|
30
|
+
"""
|
|
31
|
+
if not callable(handler):
|
|
32
|
+
print("Handler must be callable")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
# Validate that either both discriminator_key and discriminator_value are provided or neither
|
|
36
|
+
if (discriminator_key is not None and discriminator_value is None) or (discriminator_key is None and discriminator_value is not None):
|
|
37
|
+
print("Error: Both discriminator_key and discriminator_value must be provided together")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# Register handler
|
|
41
|
+
self.receive_operation_handlers["${operationId}"] = handler
|
|
42
|
+
|
|
43
|
+
# Add discriminator entry to the list if both key and value are provided
|
|
44
|
+
if discriminator_key is not None and discriminator_value is not None:
|
|
45
|
+
discriminator_entry = {
|
|
46
|
+
"key": discriminator_key,
|
|
47
|
+
"value": discriminator_value,
|
|
48
|
+
"operation_id": "${operationId}"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Check if this discriminator already exists
|
|
52
|
+
exists = any(
|
|
53
|
+
d.get("key") == discriminator_key and
|
|
54
|
+
d.get("value") == discriminator_value and
|
|
55
|
+
d.get("operation_id") == "${operationId}"
|
|
56
|
+
for d in self.receive_operation_discriminators
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if not exists:
|
|
60
|
+
self.receive_operation_discriminators.append(discriminator_entry)`
|
|
61
|
+
}, operationId);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.RegisterReceiveOperations = RegisterReceiveOperations;
|
|
66
|
+
//# sourceMappingURL=RegisterReceiveOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RegisterReceiveOperations.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/RegisterReceiveOperations.js"],"sourcesContent":["import { Text } from '@asyncapi/generator-react-sdk';\nimport { toSnakeCase } from '@asyncapi/generator-helpers';\n\n/**\n * Component for rendering receive operation handler registration methods\n * Generates one specific method per operation for better DX\n * \n* @param {Object} props - Component props\n* @param {Array} props.receiveOperations - Array of receive operations from AsyncAPI document\n* @returns {Array<React.Element>|null} Array of Text components containing Python handler registration methods, or null if no operations\n */\nexport function RegisterReceiveOperations({ receiveOperations }) {\n if (!receiveOperations || receiveOperations.length === 0) {\n return null;\n }\n\n return receiveOperations.map((operation) => {\n const operationId = operation.id();\n const methodName = `register_${toSnakeCase(operationId)}_handler`;\n\n return (\n <Text indent={2} newLines={2} key={operationId}>\n {`def ${methodName}(self, handler, discriminator_key=None, discriminator_value=None):\n \"\"\"\n Register a handler for ${operationId} operation.\n\n Args:\n handler (callable): Handler function that receives raw_message as argument\n discriminator_key (str): Message field to use for routing (e.g., 'type', 'event_type')\n discriminator_value (str): Expected value for routing (e.g., 'hello', 'user_joined')\n \"\"\"\n if not callable(handler):\n print(\"Handler must be callable\")\n return\n\n # Validate that either both discriminator_key and discriminator_value are provided or neither\n if (discriminator_key is not None and discriminator_value is None) or (discriminator_key is None and discriminator_value is not None):\n print(\"Error: Both discriminator_key and discriminator_value must be provided together\")\n return\n\n # Register handler\n self.receive_operation_handlers[\"${operationId}\"] = handler\n\n # Add discriminator entry to the list if both key and value are provided\n if discriminator_key is not None and discriminator_value is not None:\n discriminator_entry = {\n \"key\": discriminator_key,\n \"value\": discriminator_value,\n \"operation_id\": \"${operationId}\"\n }\n \n # Check if this discriminator already exists\n exists = any(\n d.get(\"key\") == discriminator_key and \n d.get(\"value\") == discriminator_value and \n d.get(\"operation_id\") == \"${operationId}\" \n for d in self.receive_operation_discriminators\n )\n\n if not exists:\n self.receive_operation_discriminators.append(discriminator_entry)`}\n </Text>\n );\n });\n}"],"names":["RegisterReceiveOperations","receiveOperations","length","map","operation","operationId","id","methodName","toSnakeCase","_jsx","Text","indent","newLines","children"],"mappings":";;;;;;;;;AAWO,SAASA,yBAAyBA,CAAC;AAAEC,EAAAA,iBAAAA;AAAkB,CAAC,EAAE;EAC/D,IAAI,CAACA,iBAAiB,IAAIA,iBAAiB,CAACC,MAAM,KAAK,CAAC,EAAE;AACxD,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AAEA,EAAA,OAAOD,iBAAiB,CAACE,GAAG,CAAEC,SAAS,IAAK;AAC1C,IAAA,MAAMC,WAAW,GAAGD,SAAS,CAACE,EAAE,EAAE,CAAA;AAClC,IAAA,MAAMC,UAAU,GAAG,CAAA,SAAA,EAAYC,4BAAW,CAACH,WAAW,CAAC,CAAU,QAAA,CAAA,CAAA;IAEjE,oBACEI,cAAA,CAACC,sBAAI,EAAA;AAACC,MAAAA,MAAM,EAAE,CAAE;AAACC,MAAAA,QAAQ,EAAE,CAAE;MAAAC,QAAA,EAC1B,OAAON,UAAU,CAAA;AAC1B;AACA,2BAAA,EAA6BF,WAAW,CAAA;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAA,EAAuCA,WAAW,CAAA;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,6BAAA,EAA+BA,WAAW,CAAA;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,sCAAA,EAAwCA,WAAW,CAAA;AACnD;AACA;AACA;AACA;AACA,2EAAA,CAAA;AAA4E,KAAA,EAvCnCA,WAwC7B,CAAC,CAAA;AAEX,GAAC,CAAC,CAAA;AACJ;;;;"}
|
|
@@ -92,9 +92,28 @@ function InitSignature({
|
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
function ReceiveOperationsDiscriminators({
|
|
96
|
+
receiveOperations
|
|
97
|
+
}) {
|
|
98
|
+
const hasOperations = Array.isArray(receiveOperations) && receiveOperations.length > 0;
|
|
99
|
+
if (!hasOperations) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const operationDiscriminators = generatorHelpers.getMessageDiscriminatorsFromOperations(receiveOperations);
|
|
103
|
+
const serializedDiscriminators = JSON.stringify(operationDiscriminators);
|
|
104
|
+
return /*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
105
|
+
indent: 2,
|
|
106
|
+
newLines: 2,
|
|
107
|
+
children: `
|
|
108
|
+
self.receive_operation_handlers = {}
|
|
109
|
+
self.receive_operation_discriminators = ${serializedDiscriminators}`
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
95
113
|
function Constructor({
|
|
96
114
|
serverUrl,
|
|
97
|
-
query
|
|
115
|
+
query,
|
|
116
|
+
receiveOperations
|
|
98
117
|
}) {
|
|
99
118
|
const queryParamsArray = query && Array.from(query.entries());
|
|
100
119
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
@@ -121,8 +140,9 @@ function Constructor({
|
|
|
121
140
|
self.error_handlers = [] # Callables for errors
|
|
122
141
|
self.outgoing_processors = [] # Callables to process outgoing messages
|
|
123
142
|
self._stop_event = threading.Event()
|
|
124
|
-
|
|
125
143
|
${query ? 'params = {}' : ''}`
|
|
144
|
+
}), /*#__PURE__*/jsxRuntime.jsx(ReceiveOperationsDiscriminators, {
|
|
145
|
+
receiveOperations: receiveOperations
|
|
126
146
|
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.QueryParamsVariables, {
|
|
127
147
|
language: "python",
|
|
128
148
|
queryParams: queryParamsArray
|
|
@@ -166,6 +186,61 @@ function HandleError() {
|
|
|
166
186
|
});
|
|
167
187
|
}
|
|
168
188
|
|
|
189
|
+
function RegisterReceiveOperations({
|
|
190
|
+
receiveOperations
|
|
191
|
+
}) {
|
|
192
|
+
if (!receiveOperations || receiveOperations.length === 0) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return receiveOperations.map(operation => {
|
|
196
|
+
const operationId = operation.id();
|
|
197
|
+
const methodName = `register_${generatorHelpers.toSnakeCase(operationId)}_handler`;
|
|
198
|
+
return /*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
199
|
+
indent: 2,
|
|
200
|
+
newLines: 2,
|
|
201
|
+
children: `def ${methodName}(self, handler, discriminator_key=None, discriminator_value=None):
|
|
202
|
+
"""
|
|
203
|
+
Register a handler for ${operationId} operation.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
handler (callable): Handler function that receives raw_message as argument
|
|
207
|
+
discriminator_key (str): Message field to use for routing (e.g., 'type', 'event_type')
|
|
208
|
+
discriminator_value (str): Expected value for routing (e.g., 'hello', 'user_joined')
|
|
209
|
+
"""
|
|
210
|
+
if not callable(handler):
|
|
211
|
+
print("Handler must be callable")
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
# Validate that either both discriminator_key and discriminator_value are provided or neither
|
|
215
|
+
if (discriminator_key is not None and discriminator_value is None) or (discriminator_key is None and discriminator_value is not None):
|
|
216
|
+
print("Error: Both discriminator_key and discriminator_value must be provided together")
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
# Register handler
|
|
220
|
+
self.receive_operation_handlers["${operationId}"] = handler
|
|
221
|
+
|
|
222
|
+
# Add discriminator entry to the list if both key and value are provided
|
|
223
|
+
if discriminator_key is not None and discriminator_value is not None:
|
|
224
|
+
discriminator_entry = {
|
|
225
|
+
"key": discriminator_key,
|
|
226
|
+
"value": discriminator_value,
|
|
227
|
+
"operation_id": "${operationId}"
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
# Check if this discriminator already exists
|
|
231
|
+
exists = any(
|
|
232
|
+
d.get("key") == discriminator_key and
|
|
233
|
+
d.get("value") == discriminator_value and
|
|
234
|
+
d.get("operation_id") == "${operationId}"
|
|
235
|
+
for d in self.receive_operation_discriminators
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
if not exists:
|
|
239
|
+
self.receive_operation_discriminators.append(discriminator_entry)`
|
|
240
|
+
}, operationId);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
169
244
|
function ClientClass({
|
|
170
245
|
asyncapi,
|
|
171
246
|
params
|
|
@@ -177,13 +252,15 @@ function ClientClass({
|
|
|
177
252
|
const serverUrl = generatorHelpers.getServerUrl(server);
|
|
178
253
|
const operations = asyncapi.operations();
|
|
179
254
|
const sendOperations = operations.filterBySend();
|
|
255
|
+
const receiveOperations = operations.filterByReceive();
|
|
180
256
|
return /*#__PURE__*/jsxRuntime.jsxs(generatorReactSdk.Text, {
|
|
181
257
|
children: [/*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.Text, {
|
|
182
258
|
newLines: 2,
|
|
183
259
|
children: `class ${clientName}:`
|
|
184
260
|
}), /*#__PURE__*/jsxRuntime.jsx(Constructor, {
|
|
185
261
|
serverUrl: serverUrl,
|
|
186
|
-
query: queryParams
|
|
262
|
+
query: queryParams,
|
|
263
|
+
receiveOperations: receiveOperations
|
|
187
264
|
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.Connect, {
|
|
188
265
|
language: "python",
|
|
189
266
|
title: title
|
|
@@ -202,7 +279,9 @@ function ClientClass({
|
|
|
202
279
|
methodName: "handle_message",
|
|
203
280
|
methodParams: ['self', 'message'],
|
|
204
281
|
preExecutionCode: "\"\"\"Pass the incoming message to all registered message handlers. \"\"\""
|
|
205
|
-
}), /*#__PURE__*/jsxRuntime.jsx(HandleError, {}), /*#__PURE__*/jsxRuntime.jsx(
|
|
282
|
+
}), /*#__PURE__*/jsxRuntime.jsx(HandleError, {}), /*#__PURE__*/jsxRuntime.jsx(RegisterReceiveOperations, {
|
|
283
|
+
receiveOperations: receiveOperations
|
|
284
|
+
}), /*#__PURE__*/jsxRuntime.jsx(generatorComponents.SendOperations, {
|
|
206
285
|
language: "python",
|
|
207
286
|
sendOperations: sendOperations,
|
|
208
287
|
clientName: clientName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.py.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/Requires.js","../../../../../../../../packages/templates/clients/websocket/python/components/Send.js","../../../../../../../../packages/templates/clients/websocket/python/components/QueryParamsArgumentsDocs.js","../../../../../../../../packages/templates/clients/websocket/python/components/InitSignature.js","../../../../../../../../packages/templates/clients/websocket/python/components/Constructor.js","../../../../../../../../packages/templates/clients/websocket/python/components/RegisterOutgoingProcessor.js","../../../../../../../../packages/templates/clients/websocket/python/components/HandleError.js","../../../../../../../../packages/templates/clients/websocket/python/components/ClientClass.js","../../../../../../../../packages/templates/clients/websocket/python/template/client.py.js"],"sourcesContent":["import { DependencyProvider } from '@asyncapi/generator-components';\n\nexport function Requires({ query }) {\n const additionalDependencies = [];\n if (query) {\n additionalDependencies.push('import os');\n additionalDependencies.push('from urllib.parse import urlencode');\n }\n return (\n <DependencyProvider\n language=\"python\"\n additionalDependencies={additionalDependencies}\n />\n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function Send({ sendOperations }) {\n if (!sendOperations || sendOperations.length === 0) {\n return null;\n }\n\n return (\n <Text newLines={2} indent={2}>\n {\n `\n@staticmethod\nasync def _send(message, socket):\n \"\"\"\n Internal helper to handle the actual sending logic.\n\n Args:\n message (dict or str): The message to send.\n socket (websockets.WebSocketCommonProtocol): The WebSocket to send through.\n\n Notes:\n If message is a dictionary, it will be automatically converted to JSON.\n \"\"\"\n try:\n if isinstance(message, dict):\n message = json.dumps(message)\n await socket.send(message)\n except Exception as e:\n print(\"Error sending:\", e)`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function QueryParamsArgumentsDocs({ queryParams }) {\n if (!queryParams) {\n return null;\n }\n\n return queryParams.map((param) => {\n const paramName = param[0];\n const firstLine = `${paramName} (str, optional):`;\n const secondLine = `If provided (or if ${paramName.toUpperCase()} environment variable is set), added as ?${paramName}=… to URL`;\n return (\n <Text indent={1}>\n {firstLine}\n {secondLine}\n </Text>\n );\n });\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function InitSignature({ queryParams, serverUrl }) {\n if (!queryParams) {\n return (\n <Text indent={2} newLines={2}>\n {`def __init__(self, url: str = \"${serverUrl}\"):`}\n </Text>\n );\n }\n \n const queryParamsArguments = queryParams?.map((param) => {\n const paramName = param[0];\n const paramDefaultValue = param[1];\n const defaultValue = paramDefaultValue ? `\"${paramDefaultValue}\"` : 'None';\n return `${paramName}: str = ${defaultValue}`;\n }).join(', ');\n \n return (\n <Text indent={2} newLines={2}>\n {`def __init__(self, url: str = \"${serverUrl}\", ${queryParamsArguments}):`}\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\nimport { QueryParamsVariables } from '@asyncapi/generator-components';\nimport { QueryParamsArgumentsDocs } from './QueryParamsArgumentsDocs';\nimport { InitSignature } from './InitSignature';\n\nexport function Constructor({ serverUrl, query}) {\n const queryParamsArray = query && Array.from(query.entries());\n \n return (\n <>\n <InitSignature queryParams={queryParamsArray} serverUrl={serverUrl} />\n <Text indent={2}>\n {`\n \"\"\"\n Constructor to initialize the WebSocket client.\n\n Args:\n url (str, optional): The WebSocket server URL. Use it if the server URL is \n different from the default one taken from the AsyncAPI document.`}\n </Text>\n <QueryParamsArgumentsDocs queryParams={queryParamsArray} />\n <Text indent={2}>\n {`\n \"\"\"\n self.ws_app = None # Instance of WebSocketApp\n self.message_handlers = [] # Callables for incoming messages\n self.error_handlers = [] # Callables for errors\n self.outgoing_processors = [] # Callables to process outgoing messages\n self._stop_event = threading.Event()\n \n ${ query ? 'params = {}' : ''}`\n }\n </Text>\n <QueryParamsVariables\n language=\"python\"\n queryParams={queryParamsArray} \n />\n <Text newLines={2}>\n {`\n ${query ? 'qs = urlencode(params) if params else \"\"' : ''}\n ${query ? 'self.url = f\"{url}{f\\'?{qs}\\' if qs else \\'\\'}\"' : 'self.url = url'}`}\n </Text>\n </>\n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function RegisterOutgoingProcessor() {\n return (\n <Text newLines={2} indent={2}>\n {\n `def register_outgoing_processor(self, processor):\n \"\"\"\n Register a callable that processes outgoing messages automatically.\n These processors run in sequence before each message is sent.\n \"\"\"\n if callable(processor):\n self.outgoing_processors.append(processor)\n else:\n print(\"Outgoing processor must be callable\")`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function HandleError() {\n return (\n <Text newLines={2} indent={2}>\n {\n `def handle_error(self, error):\n \"\"\"Pass the error to all registered error handlers. Generic log message is printed if no handlers are registered.\"\"\"\n if len(self.error_handlers) == 0:\n print(\"\\\\033[91mError occurred:\\\\033[0m\", error)\n else:\n # Call custom error handlers\n for handler in self.error_handlers:\n handler(error)`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName, getServerUrl, getServer, getQueryParams, getTitle } from '@asyncapi/generator-helpers';\nimport { Send } from './Send';\nimport { Constructor } from './Constructor';\nimport { CloseConnection, RegisterMessageHandler, RegisterErrorHandler, SendOperations, Connect, HandleMessage } from '@asyncapi/generator-components';\nimport { RegisterOutgoingProcessor } from './RegisterOutgoingProcessor';\nimport { HandleError } from './HandleError';\n\nexport function ClientClass({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const title = getTitle(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);\n const serverUrl = getServerUrl(server);\n const operations = asyncapi.operations();\n const sendOperations = operations.filterBySend();\n return (\n <Text>\n <Text newLines={2}>\n {`class ${clientName}:`}\n </Text>\n <Constructor serverUrl={serverUrl} query={queryParams} />\n <Connect language=\"python\" title={title} />\n <RegisterMessageHandler\n language=\"python\"\n methodName='register_message_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process incoming messages.\"\"\"'\n />\n <RegisterErrorHandler\n language=\"python\"\n methodName='register_error_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process errors.\"\"\"'\n />\n <RegisterOutgoingProcessor />\n <HandleMessage\n language=\"python\"\n methodName='handle_message'\n methodParams={['self', 'message']}\n preExecutionCode='\"\"\"Pass the incoming message to all registered message handlers. \"\"\"'\n />\n <HandleError />\n <SendOperations \n language=\"python\"\n sendOperations={sendOperations} \n clientName={clientName} \n />\n <Send sendOperations={sendOperations} />\n <CloseConnection \n language=\"python\" \n methodParams={['self']}\n preExecutionCode='\"\"\"Cleanly close the WebSocket connection.\"\"\"'\n />\n </Text>\n );\n}\n","import { File } from '@asyncapi/generator-react-sdk';\nimport { getServer, getQueryParams, getInfo } from '@asyncapi/generator-helpers';\nimport { FileHeaderInfo } from '@asyncapi/generator-components';\nimport { Requires } from '../components/Requires';\nimport { ClientClass } from '../components/ClientClass';\n\nexport default function ({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const info = getInfo(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n return (\n // The clientFileName default values can be found and modified under the .ageneratorrc\n <File name={params.clientFileName}>\n <FileHeaderInfo\n info={info}\n server={server}\n language=\"python\"\n />\n <Requires query={queryParams} />\n <ClientClass asyncapi={asyncapi} params={params} />\n </File>\n );\n}\n"],"names":["Requires","query","additionalDependencies","push","_jsx","DependencyProvider","language","Send","sendOperations","length","Text","newLines","indent","children","QueryParamsArgumentsDocs","queryParams","map","param","paramName","firstLine","secondLine","toUpperCase","_jsxs","InitSignature","serverUrl","queryParamsArguments","paramDefaultValue","defaultValue","join","Constructor","queryParamsArray","Array","from","entries","_Fragment","QueryParamsVariables","RegisterOutgoingProcessor","HandleError","ClientClass","asyncapi","params","server","getServer","servers","title","getTitle","getQueryParams","channels","clientName","getClientName","appendClientSuffix","customClientName","getServerUrl","operations","filterBySend","Connect","RegisterMessageHandler","methodName","methodParams","preExecutionCode","RegisterErrorHandler","HandleMessage","SendOperations","CloseConnection","info","getInfo","File","name","clientFileName","FileHeaderInfo"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.py.js","sources":["../../../../../../../../packages/templates/clients/websocket/python/components/Requires.js","../../../../../../../../packages/templates/clients/websocket/python/components/Send.js","../../../../../../../../packages/templates/clients/websocket/python/components/QueryParamsArgumentsDocs.js","../../../../../../../../packages/templates/clients/websocket/python/components/InitSignature.js","../../../../../../../../packages/templates/clients/websocket/python/components/ReceiveOperationsDiscriminators.js","../../../../../../../../packages/templates/clients/websocket/python/components/Constructor.js","../../../../../../../../packages/templates/clients/websocket/python/components/RegisterOutgoingProcessor.js","../../../../../../../../packages/templates/clients/websocket/python/components/HandleError.js","../../../../../../../../packages/templates/clients/websocket/python/components/RegisterReceiveOperations.js","../../../../../../../../packages/templates/clients/websocket/python/components/ClientClass.js","../../../../../../../../packages/templates/clients/websocket/python/template/client.py.js"],"sourcesContent":["import { DependencyProvider } from '@asyncapi/generator-components';\n\nexport function Requires({ query }) {\n const additionalDependencies = [];\n if (query) {\n additionalDependencies.push('import os');\n additionalDependencies.push('from urllib.parse import urlencode');\n }\n return (\n <DependencyProvider\n language=\"python\"\n additionalDependencies={additionalDependencies}\n />\n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function Send({ sendOperations }) {\n if (!sendOperations || sendOperations.length === 0) {\n return null;\n }\n\n return (\n <Text newLines={2} indent={2}>\n {\n `\n@staticmethod\nasync def _send(message, socket):\n \"\"\"\n Internal helper to handle the actual sending logic.\n\n Args:\n message (dict or str): The message to send.\n socket (websockets.WebSocketCommonProtocol): The WebSocket to send through.\n\n Notes:\n If message is a dictionary, it will be automatically converted to JSON.\n \"\"\"\n try:\n if isinstance(message, dict):\n message = json.dumps(message)\n await socket.send(message)\n except Exception as e:\n print(\"Error sending:\", e)`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function QueryParamsArgumentsDocs({ queryParams }) {\n if (!queryParams) {\n return null;\n }\n\n return queryParams.map((param) => {\n const paramName = param[0];\n const firstLine = `${paramName} (str, optional):`;\n const secondLine = `If provided (or if ${paramName.toUpperCase()} environment variable is set), added as ?${paramName}=… to URL`;\n return (\n <Text indent={1}>\n {firstLine}\n {secondLine}\n </Text>\n );\n });\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function InitSignature({ queryParams, serverUrl }) {\n if (!queryParams) {\n return (\n <Text indent={2} newLines={2}>\n {`def __init__(self, url: str = \"${serverUrl}\"):`}\n </Text>\n );\n }\n \n const queryParamsArguments = queryParams?.map((param) => {\n const paramName = param[0];\n const paramDefaultValue = param[1];\n const defaultValue = paramDefaultValue ? `\"${paramDefaultValue}\"` : 'None';\n return `${paramName}: str = ${defaultValue}`;\n }).join(', ');\n \n return (\n <Text indent={2} newLines={2}>\n {`def __init__(self, url: str = \"${serverUrl}\", ${queryParamsArguments}):`}\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\nimport { getMessageDiscriminatorsFromOperations } from '@asyncapi/generator-helpers';\n\n/**\n * Component that generates initialization code for receive operation discriminators.\n * \n * @param {Object} props - Component properties\n * @param {Array<Object>} [props.receiveOperations] - Receive operations from AsyncAPI document\n * @returns {React.Element|null} Rendered initialization code or null.\n */\nexport function ReceiveOperationsDiscriminators({ receiveOperations }) {\n const hasOperations = Array.isArray(receiveOperations) && receiveOperations.length > 0;\n if (!hasOperations) {\n return null;\n }\n\n const operationDiscriminators = getMessageDiscriminatorsFromOperations(receiveOperations);\n const serializedDiscriminators = JSON.stringify(operationDiscriminators);\n\n return (\n <Text indent={2} newLines={2}>\n {`\n self.receive_operation_handlers = {}\n self.receive_operation_discriminators = ${serializedDiscriminators}`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\nimport { QueryParamsVariables } from '@asyncapi/generator-components';\nimport { QueryParamsArgumentsDocs } from './QueryParamsArgumentsDocs';\nimport { InitSignature } from './InitSignature';\nimport { ReceiveOperationsDiscriminators } from './ReceiveOperationsDiscriminators';\n\nexport function Constructor({ serverUrl, query, receiveOperations }) {\n const queryParamsArray = query && Array.from(query.entries());\n\n return (\n <>\n <InitSignature queryParams={queryParamsArray} serverUrl={serverUrl} />\n <Text indent={2}>\n {`\n \"\"\"\n Constructor to initialize the WebSocket client.\n\n Args:\n url (str, optional): The WebSocket server URL. Use it if the server URL is \n different from the default one taken from the AsyncAPI document.`}\n </Text>\n <QueryParamsArgumentsDocs queryParams={queryParamsArray} />\n <Text indent={2}>\n {`\n \"\"\"\n self.ws_app = None # Instance of WebSocketApp\n self.message_handlers = [] # Callables for incoming messages\n self.error_handlers = [] # Callables for errors\n self.outgoing_processors = [] # Callables to process outgoing messages\n self._stop_event = threading.Event()\n ${ query ? 'params = {}' : ''}`\n }\n </Text>\n <ReceiveOperationsDiscriminators receiveOperations={receiveOperations} />\n <QueryParamsVariables\n language=\"python\"\n queryParams={queryParamsArray} \n />\n <Text newLines={2}>\n {`\n ${query ? 'qs = urlencode(params) if params else \"\"' : ''}\n ${query ? 'self.url = f\"{url}{f\\'?{qs}\\' if qs else \\'\\'}\"' : 'self.url = url'}`}\n </Text>\n </>\n );\n}","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function RegisterOutgoingProcessor() {\n return (\n <Text newLines={2} indent={2}>\n {\n `def register_outgoing_processor(self, processor):\n \"\"\"\n Register a callable that processes outgoing messages automatically.\n These processors run in sequence before each message is sent.\n \"\"\"\n if callable(processor):\n self.outgoing_processors.append(processor)\n else:\n print(\"Outgoing processor must be callable\")`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\n\nexport function HandleError() {\n return (\n <Text newLines={2} indent={2}>\n {\n `def handle_error(self, error):\n \"\"\"Pass the error to all registered error handlers. Generic log message is printed if no handlers are registered.\"\"\"\n if len(self.error_handlers) == 0:\n print(\"\\\\033[91mError occurred:\\\\033[0m\", error)\n else:\n # Call custom error handlers\n for handler in self.error_handlers:\n handler(error)`\n }\n </Text>\n );\n}\n","import { Text } from '@asyncapi/generator-react-sdk';\nimport { toSnakeCase } from '@asyncapi/generator-helpers';\n\n/**\n * Component for rendering receive operation handler registration methods\n * Generates one specific method per operation for better DX\n * \n* @param {Object} props - Component props\n* @param {Array} props.receiveOperations - Array of receive operations from AsyncAPI document\n* @returns {Array<React.Element>|null} Array of Text components containing Python handler registration methods, or null if no operations\n */\nexport function RegisterReceiveOperations({ receiveOperations }) {\n if (!receiveOperations || receiveOperations.length === 0) {\n return null;\n }\n\n return receiveOperations.map((operation) => {\n const operationId = operation.id();\n const methodName = `register_${toSnakeCase(operationId)}_handler`;\n\n return (\n <Text indent={2} newLines={2} key={operationId}>\n {`def ${methodName}(self, handler, discriminator_key=None, discriminator_value=None):\n \"\"\"\n Register a handler for ${operationId} operation.\n\n Args:\n handler (callable): Handler function that receives raw_message as argument\n discriminator_key (str): Message field to use for routing (e.g., 'type', 'event_type')\n discriminator_value (str): Expected value for routing (e.g., 'hello', 'user_joined')\n \"\"\"\n if not callable(handler):\n print(\"Handler must be callable\")\n return\n\n # Validate that either both discriminator_key and discriminator_value are provided or neither\n if (discriminator_key is not None and discriminator_value is None) or (discriminator_key is None and discriminator_value is not None):\n print(\"Error: Both discriminator_key and discriminator_value must be provided together\")\n return\n\n # Register handler\n self.receive_operation_handlers[\"${operationId}\"] = handler\n\n # Add discriminator entry to the list if both key and value are provided\n if discriminator_key is not None and discriminator_value is not None:\n discriminator_entry = {\n \"key\": discriminator_key,\n \"value\": discriminator_value,\n \"operation_id\": \"${operationId}\"\n }\n \n # Check if this discriminator already exists\n exists = any(\n d.get(\"key\") == discriminator_key and \n d.get(\"value\") == discriminator_value and \n d.get(\"operation_id\") == \"${operationId}\" \n for d in self.receive_operation_discriminators\n )\n\n if not exists:\n self.receive_operation_discriminators.append(discriminator_entry)`}\n </Text>\n );\n });\n}","import { Text } from '@asyncapi/generator-react-sdk';\nimport { getClientName, getServerUrl, getServer, getQueryParams, getTitle } from '@asyncapi/generator-helpers';\nimport { Send } from './Send';\nimport { Constructor } from './Constructor';\nimport { CloseConnection, RegisterMessageHandler, RegisterErrorHandler, SendOperations, Connect, HandleMessage } from '@asyncapi/generator-components';\nimport { RegisterOutgoingProcessor } from './RegisterOutgoingProcessor';\nimport { HandleError } from './HandleError';\nimport { RegisterReceiveOperations } from './RegisterReceiveOperations';\n\nexport function ClientClass({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const title = getTitle(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);\n const serverUrl = getServerUrl(server);\n const operations = asyncapi.operations();\n const sendOperations = operations.filterBySend();\n const receiveOperations = operations.filterByReceive();\n\n return (\n <Text>\n <Text newLines={2}>\n {`class ${clientName}:`}\n </Text>\n <Constructor serverUrl={serverUrl} query={queryParams} receiveOperations={receiveOperations} />\n <Connect language=\"python\" title={title} />\n <RegisterMessageHandler\n language=\"python\"\n methodName='register_message_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process incoming messages.\"\"\"'\n />\n <RegisterErrorHandler\n language=\"python\"\n methodName='register_error_handler'\n methodParams={['self', 'handler']}\n preExecutionCode='\"\"\"Register a callable to process errors.\"\"\"'\n />\n <RegisterOutgoingProcessor />\n <HandleMessage\n language=\"python\"\n methodName='handle_message'\n methodParams={['self', 'message']}\n preExecutionCode='\"\"\"Pass the incoming message to all registered message handlers. \"\"\"'\n />\n <HandleError />\n <RegisterReceiveOperations receiveOperations={receiveOperations} />\n <SendOperations \n language=\"python\"\n sendOperations={sendOperations} \n clientName={clientName} \n />\n <Send sendOperations={sendOperations} />\n <CloseConnection \n language=\"python\" \n methodParams={['self']}\n preExecutionCode='\"\"\"Cleanly close the WebSocket connection.\"\"\"'\n />\n </Text>\n );\n}\n","import { File } from '@asyncapi/generator-react-sdk';\nimport { getServer, getQueryParams, getInfo } from '@asyncapi/generator-helpers';\nimport { FileHeaderInfo } from '@asyncapi/generator-components';\nimport { Requires } from '../components/Requires';\nimport { ClientClass } from '../components/ClientClass';\n\nexport default function ({ asyncapi, params }) {\n const server = getServer(asyncapi.servers(), params.server);\n const info = getInfo(asyncapi);\n const queryParams = getQueryParams(asyncapi.channels());\n return (\n // The clientFileName default values can be found and modified under the .ageneratorrc\n <File name={params.clientFileName}>\n <FileHeaderInfo\n info={info}\n server={server}\n language=\"python\"\n />\n <Requires query={queryParams} />\n <ClientClass asyncapi={asyncapi} params={params} />\n </File>\n );\n}\n"],"names":["Requires","query","additionalDependencies","push","_jsx","DependencyProvider","language","Send","sendOperations","length","Text","newLines","indent","children","QueryParamsArgumentsDocs","queryParams","map","param","paramName","firstLine","secondLine","toUpperCase","_jsxs","InitSignature","serverUrl","queryParamsArguments","paramDefaultValue","defaultValue","join","ReceiveOperationsDiscriminators","receiveOperations","hasOperations","Array","isArray","operationDiscriminators","getMessageDiscriminatorsFromOperations","serializedDiscriminators","JSON","stringify","Constructor","queryParamsArray","from","entries","_Fragment","QueryParamsVariables","RegisterOutgoingProcessor","HandleError","RegisterReceiveOperations","operation","operationId","id","methodName","toSnakeCase","ClientClass","asyncapi","params","server","getServer","servers","title","getTitle","getQueryParams","channels","clientName","getClientName","appendClientSuffix","customClientName","getServerUrl","operations","filterBySend","filterByReceive","Connect","RegisterMessageHandler","methodParams","preExecutionCode","RegisterErrorHandler","HandleMessage","SendOperations","CloseConnection","info","getInfo","File","name","clientFileName","FileHeaderInfo"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { Constructor } from './Constructor';
|
|
|
5
5
|
import { CloseConnection, RegisterMessageHandler, RegisterErrorHandler, SendOperations, Connect, HandleMessage } from '@asyncapi/generator-components';
|
|
6
6
|
import { RegisterOutgoingProcessor } from './RegisterOutgoingProcessor';
|
|
7
7
|
import { HandleError } from './HandleError';
|
|
8
|
+
import { RegisterReceiveOperations } from './RegisterReceiveOperations';
|
|
8
9
|
|
|
9
10
|
export function ClientClass({ asyncapi, params }) {
|
|
10
11
|
const server = getServer(asyncapi.servers(), params.server);
|
|
@@ -14,12 +15,14 @@ export function ClientClass({ asyncapi, params }) {
|
|
|
14
15
|
const serverUrl = getServerUrl(server);
|
|
15
16
|
const operations = asyncapi.operations();
|
|
16
17
|
const sendOperations = operations.filterBySend();
|
|
18
|
+
const receiveOperations = operations.filterByReceive();
|
|
19
|
+
|
|
17
20
|
return (
|
|
18
21
|
<Text>
|
|
19
22
|
<Text newLines={2}>
|
|
20
23
|
{`class ${clientName}:`}
|
|
21
24
|
</Text>
|
|
22
|
-
<Constructor serverUrl={serverUrl} query={queryParams} />
|
|
25
|
+
<Constructor serverUrl={serverUrl} query={queryParams} receiveOperations={receiveOperations} />
|
|
23
26
|
<Connect language="python" title={title} />
|
|
24
27
|
<RegisterMessageHandler
|
|
25
28
|
language="python"
|
|
@@ -41,6 +44,7 @@ export function ClientClass({ asyncapi, params }) {
|
|
|
41
44
|
preExecutionCode='"""Pass the incoming message to all registered message handlers. """'
|
|
42
45
|
/>
|
|
43
46
|
<HandleError />
|
|
47
|
+
<RegisterReceiveOperations receiveOperations={receiveOperations} />
|
|
44
48
|
<SendOperations
|
|
45
49
|
language="python"
|
|
46
50
|
sendOperations={sendOperations}
|
|
@@ -2,10 +2,11 @@ import { Text } from '@asyncapi/generator-react-sdk';
|
|
|
2
2
|
import { QueryParamsVariables } from '@asyncapi/generator-components';
|
|
3
3
|
import { QueryParamsArgumentsDocs } from './QueryParamsArgumentsDocs';
|
|
4
4
|
import { InitSignature } from './InitSignature';
|
|
5
|
+
import { ReceiveOperationsDiscriminators } from './ReceiveOperationsDiscriminators';
|
|
5
6
|
|
|
6
|
-
export function Constructor({ serverUrl, query}) {
|
|
7
|
+
export function Constructor({ serverUrl, query, receiveOperations }) {
|
|
7
8
|
const queryParamsArray = query && Array.from(query.entries());
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
return (
|
|
10
11
|
<>
|
|
11
12
|
<InitSignature queryParams={queryParamsArray} serverUrl={serverUrl} />
|
|
@@ -27,10 +28,10 @@ export function Constructor({ serverUrl, query}) {
|
|
|
27
28
|
self.error_handlers = [] # Callables for errors
|
|
28
29
|
self.outgoing_processors = [] # Callables to process outgoing messages
|
|
29
30
|
self._stop_event = threading.Event()
|
|
30
|
-
|
|
31
31
|
${ query ? 'params = {}' : ''}`
|
|
32
32
|
}
|
|
33
33
|
</Text>
|
|
34
|
+
<ReceiveOperationsDiscriminators receiveOperations={receiveOperations} />
|
|
34
35
|
<QueryParamsVariables
|
|
35
36
|
language="python"
|
|
36
37
|
queryParams={queryParamsArray}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Text } from '@asyncapi/generator-react-sdk';
|
|
2
|
+
import { getMessageDiscriminatorsFromOperations } from '@asyncapi/generator-helpers';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component that generates initialization code for receive operation discriminators.
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} props - Component properties
|
|
8
|
+
* @param {Array<Object>} [props.receiveOperations] - Receive operations from AsyncAPI document
|
|
9
|
+
* @returns {React.Element|null} Rendered initialization code or null.
|
|
10
|
+
*/
|
|
11
|
+
export function ReceiveOperationsDiscriminators({ receiveOperations }) {
|
|
12
|
+
const hasOperations = Array.isArray(receiveOperations) && receiveOperations.length > 0;
|
|
13
|
+
if (!hasOperations) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const operationDiscriminators = getMessageDiscriminatorsFromOperations(receiveOperations);
|
|
18
|
+
const serializedDiscriminators = JSON.stringify(operationDiscriminators);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Text indent={2} newLines={2}>
|
|
22
|
+
{`
|
|
23
|
+
self.receive_operation_handlers = {}
|
|
24
|
+
self.receive_operation_discriminators = ${serializedDiscriminators}`
|
|
25
|
+
}
|
|
26
|
+
</Text>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Text } from '@asyncapi/generator-react-sdk';
|
|
2
|
+
import { toSnakeCase } from '@asyncapi/generator-helpers';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component for rendering receive operation handler registration methods
|
|
6
|
+
* Generates one specific method per operation for better DX
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} props - Component props
|
|
9
|
+
* @param {Array} props.receiveOperations - Array of receive operations from AsyncAPI document
|
|
10
|
+
* @returns {Array<React.Element>|null} Array of Text components containing Python handler registration methods, or null if no operations
|
|
11
|
+
*/
|
|
12
|
+
export function RegisterReceiveOperations({ receiveOperations }) {
|
|
13
|
+
if (!receiveOperations || receiveOperations.length === 0) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return receiveOperations.map((operation) => {
|
|
18
|
+
const operationId = operation.id();
|
|
19
|
+
const methodName = `register_${toSnakeCase(operationId)}_handler`;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Text indent={2} newLines={2} key={operationId}>
|
|
23
|
+
{`def ${methodName}(self, handler, discriminator_key=None, discriminator_value=None):
|
|
24
|
+
"""
|
|
25
|
+
Register a handler for ${operationId} operation.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
handler (callable): Handler function that receives raw_message as argument
|
|
29
|
+
discriminator_key (str): Message field to use for routing (e.g., 'type', 'event_type')
|
|
30
|
+
discriminator_value (str): Expected value for routing (e.g., 'hello', 'user_joined')
|
|
31
|
+
"""
|
|
32
|
+
if not callable(handler):
|
|
33
|
+
print("Handler must be callable")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
# Validate that either both discriminator_key and discriminator_value are provided or neither
|
|
37
|
+
if (discriminator_key is not None and discriminator_value is None) or (discriminator_key is None and discriminator_value is not None):
|
|
38
|
+
print("Error: Both discriminator_key and discriminator_value must be provided together")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# Register handler
|
|
42
|
+
self.receive_operation_handlers["${operationId}"] = handler
|
|
43
|
+
|
|
44
|
+
# Add discriminator entry to the list if both key and value are provided
|
|
45
|
+
if discriminator_key is not None and discriminator_value is not None:
|
|
46
|
+
discriminator_entry = {
|
|
47
|
+
"key": discriminator_key,
|
|
48
|
+
"value": discriminator_value,
|
|
49
|
+
"operation_id": "${operationId}"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Check if this discriminator already exists
|
|
53
|
+
exists = any(
|
|
54
|
+
d.get("key") == discriminator_key and
|
|
55
|
+
d.get("value") == discriminator_value and
|
|
56
|
+
d.get("operation_id") == "${operationId}"
|
|
57
|
+
for d in self.receive_operation_discriminators
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
if not exists:
|
|
61
|
+
self.receive_operation_discriminators.append(discriminator_entry)`}
|
|
62
|
+
</Text>
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), 'test'))
|
|
6
|
+
|
|
7
|
+
from temp.snapshotTestResult.client_slack.client import SlackWebsocketAPIClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def handle_hello_message(message):
|
|
11
|
+
print(f"[WebSocket][HELLO] Received hello message: {message}")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def handle_event_message(message):
|
|
15
|
+
print(f"[WebSocket][EVENT] Received event message: {message}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def handle_disconnect_message(message):
|
|
19
|
+
print(f"[WebSocket][DISCONNECT] Received disconnect message: {message}")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def handle_unrecognized_message(raw_message):
|
|
23
|
+
print(f"[WebSocket][UNRECOGNIZED] Received unrecognized message: {raw_message}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main():
|
|
27
|
+
client = SlackWebsocketAPIClient()
|
|
28
|
+
|
|
29
|
+
client.register_on_hello_message_handler(handle_hello_message)
|
|
30
|
+
|
|
31
|
+
client.register_on_event_handler(handle_event_message)
|
|
32
|
+
|
|
33
|
+
client.register_on_disconnect_message_handler(handle_disconnect_message)
|
|
34
|
+
|
|
35
|
+
client.connect()
|
|
36
|
+
|
|
37
|
+
# Keep program alive for a while to allow message processing
|
|
38
|
+
time.sleep(1000)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
main()
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@asyncapi/generator-react-sdk": "*",
|
|
15
|
-
"@asyncapi/generator-helpers": "1.0
|
|
16
|
-
"@asyncapi/generator-components": "0.
|
|
15
|
+
"@asyncapi/generator-helpers": "1.1.0",
|
|
16
|
+
"@asyncapi/generator-components": "0.5.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@asyncapi/parser": "^3.4.0",
|
|
@@ -46,7 +46,7 @@ async function loadTemplateConfig(templateDir, templateParams) {
|
|
|
46
46
|
*/
|
|
47
47
|
function loadDefaultValues(templateConfig, templateParams) {
|
|
48
48
|
const parameters = templateConfig.parameters;
|
|
49
|
-
const defaultValues = Object.keys(parameters || {}).filter(key =>
|
|
49
|
+
const defaultValues = Object.keys(parameters || {}).filter(key => Object.hasOwn(parameters[key], "default"));
|
|
50
50
|
|
|
51
51
|
defaultValues.filter(dv => !Object.prototype.hasOwnProperty.call(templateParams, dv)).forEach(dv =>
|
|
52
52
|
Object.defineProperty(templateParams, dv, {
|