@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.
Files changed (26) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/docs/configuration-file.md +1 -1
  3. package/docs/template.md +1 -1
  4. package/lib/templates/bakedInTemplates/core-template-client-kafka-java-quarkus/package.json +1 -1
  5. package/lib/templates/bakedInTemplates/core-template-client-websocket-dart/package.json +2 -2
  6. package/lib/templates/bakedInTemplates/core-template-client-websocket-java-quarkus/package.json +2 -2
  7. package/lib/templates/bakedInTemplates/core-template-client-websocket-javascript/package.json +2 -2
  8. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/README.md +66 -0
  9. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ClientClass.js +8 -2
  10. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ClientClass.js.map +1 -1
  11. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/Constructor.js +6 -2
  12. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/Constructor.js.map +1 -1
  13. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ReceiveOperationsDiscriminators.js +29 -0
  14. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/ReceiveOperationsDiscriminators.js.map +1 -0
  15. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/RegisterReceiveOperations.js +66 -0
  16. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/components/RegisterReceiveOperations.js.map +1 -0
  17. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/client.py.js +83 -4
  18. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/__transpiled/template/client.py.js.map +1 -1
  19. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/ClientClass.js +5 -1
  20. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/Constructor.js +4 -3
  21. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/ReceiveOperationsDiscriminators.js +28 -0
  22. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/components/RegisterReceiveOperations.js +65 -0
  23. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/example-slack-with-routing.py +41 -0
  24. package/lib/templates/bakedInTemplates/core-template-client-websocket-python/package.json +2 -2
  25. package/lib/templates/config/loader.js +1 -1
  26. 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](#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.1",
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.1",
16
- "@asyncapi/generator-components": "0.4.1"
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",
@@ -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.1",
22
- "@asyncapi/generator-components": "0.4.1",
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": {
@@ -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.1",
14
+ "@asyncapi/generator-helpers": "1.1.0",
15
15
  "@asyncapi/generator-react-sdk": "*",
16
- "@asyncapi/generator-components": "0.4.1",
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(generatorComponents.SendOperations, {
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":";;;;;;;;;;;;;;;;AAQO,SAASA,WAAWA,CAAC;EAAEC,QAAQ;AAAEC,EAAAA,MAAAA;AAAO,CAAC,EAAE;AAChD,EAAA,MAAMC,MAAM,GAAGC,0BAAS,CAACH,QAAQ,CAACI,OAAO,EAAE,EAAEH,MAAM,CAACC,MAAM,CAAC,CAAA;AAC3D,EAAA,MAAMG,KAAK,GAAGC,yBAAQ,CAACN,QAAQ,CAAC,CAAA;EAChC,MAAMO,WAAW,GAAGC,+BAAc,CAACR,QAAQ,CAACS,QAAQ,EAAE,CAAC,CAAA;AACvD,EAAA,MAAMC,UAAU,GAAGC,8BAAa,CAACX,QAAQ,EAAEC,MAAM,CAACW,kBAAkB,EAAEX,MAAM,CAACY,gBAAgB,CAAC,CAAA;AAC9F,EAAA,MAAMC,SAAS,GAAGC,6BAAY,CAACb,MAAM,CAAC,CAAA;AACtC,EAAA,MAAMc,UAAU,GAAGhB,QAAQ,CAACgB,UAAU,EAAE,CAAA;AACxC,EAAA,MAAMC,cAAc,GAAGD,UAAU,CAACE,YAAY,EAAE,CAAA;EAChD,oBACEC,eAAA,CAACC,sBAAI,EAAA;IAAAC,QAAA,EAAA,cACHC,cAAA,CAACF,sBAAI,EAAA;AAACG,MAAAA,QAAQ,EAAE,CAAE;MAAAF,QAAA,EACf,SAASX,UAAU,CAAA,CAAA,CAAA;AAAG,KACnB,CAAC,eACPY,cAAA,CAACE,uBAAW,EAAA;AAACV,MAAAA,SAAS,EAAEA,SAAU;AAACW,MAAAA,KAAK,EAAElB,WAAAA;AAAY,KAAE,CAAC,eACzDe,cAAA,CAACI,2BAAO,EAAA;AAACC,MAAAA,QAAQ,EAAC,QAAQ;AAACtB,MAAAA,KAAK,EAAEA,KAAAA;AAAM,KAAE,CAAC,eAC3CiB,cAAA,CAACM,0CAAsB,EAAA;AACrBD,MAAAA,QAAQ,EAAC,QAAQ;AACjBE,MAAAA,UAAU,EAAC,0BAA0B;AACrCC,MAAAA,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,CAAE;AAClCC,MAAAA,gBAAgB,EAAC,+DAAA;AAAyD,KAC3E,CAAC,eACFT,cAAA,CAACU,wCAAoB,EAAA;AACnBL,MAAAA,QAAQ,EAAC,QAAQ;AACjBE,MAAAA,UAAU,EAAC,wBAAwB;AACnCC,MAAAA,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,CAAE;AAClCC,MAAAA,gBAAgB,EAAC,oDAAA;KAClB,CAAC,eACFT,cAAA,CAACW,mDAAyB,IAAE,CAAC,eAC7BX,cAAA,CAACY,iCAAa,EAAA;AACZP,MAAAA,QAAQ,EAAC,QAAQ;AACjBE,MAAAA,UAAU,EAAC,gBAAgB;AAC3BC,MAAAA,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,CAAE;AAClCC,MAAAA,gBAAgB,EAAC,4EAAA;KAClB,CAAC,eACFT,cAAA,CAACa,uBAAW,IAAE,CAAC,eACfb,cAAA,CAACc,kCAAc,EAAA;AACbT,MAAAA,QAAQ,EAAC,QAAQ;AACjBV,MAAAA,cAAc,EAAEA,cAAe;AAC/BP,MAAAA,UAAU,EAAEA,UAAAA;AAAW,KACxB,CAAC,eACFY,cAAA,CAACe,SAAI,EAAA;AAACpB,MAAAA,cAAc,EAAEA,cAAAA;AAAe,KAAE,CAAC,eACxCK,cAAA,CAACgB,mCAAe,EAAA;AACdX,MAAAA,QAAQ,EAAC,QAAQ;MACjBG,YAAY,EAAE,CAAC,MAAM,CAAE;AACvBC,MAAAA,gBAAgB,EAAC,qDAAA;AAA+C,KACjE,CAAC,CAAA;AAAA,GACE,CAAC,CAAA;AAEX;;;;"}
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 \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}"],"names":["Constructor","serverUrl","query","queryParamsArray","Array","from","entries","_jsxs","_Fragment","children","_jsx","InitSignature","queryParams","Text","indent","QueryParamsArgumentsDocs","QueryParamsVariables","language","newLines"],"mappings":";;;;;;;;;;;AAKO,SAASA,WAAWA,CAAC;EAAEC,SAAS;AAAEC,EAAAA,KAAAA;AAAK,CAAC,EAAE;AAC/C,EAAA,MAAMC,gBAAgB,GAAGD,KAAK,IAAIE,KAAK,CAACC,IAAI,CAACH,KAAK,CAACI,OAAO,EAAE,CAAC,CAAA;EAE7D,oBACEC,eAAA,CAAAC,mBAAA,EAAA;IAAAC,QAAA,EAAA,cACEC,cAAA,CAACC,2BAAa,EAAA;AAACC,MAAAA,WAAW,EAAET,gBAAiB;AAACF,MAAAA,SAAS,EAAEA,SAAAA;AAAU,KAAE,CAAC,eACtES,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;AACA,MAAA,EAASP,KAAK,GAAG,aAAa,GAAG,EAAE,CAAA,CAAA;AAAE,KAEzB,CAAC,eACPQ,cAAA,CAACM,wCAAoB,EAAA;AACnBC,MAAAA,QAAQ,EAAC,QAAQ;AACjBL,MAAAA,WAAW,EAAET,gBAAAA;AAAiB,KAC/B,CAAC,eACFO,cAAA,CAACG,sBAAI,EAAA;AAACK,MAAAA,QAAQ,EAAE,CAAE;AAAAT,MAAAA,QAAA,EACf,CAAA;AACT,QAAA,EAAUP,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;;;;"}
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(generatorComponents.SendOperations, {
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.1",
16
- "@asyncapi/generator-components": "0.4.1"
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 => parameters[key].default);
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, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asyncapi/generator",
3
- "version": "3.0.1",
3
+ "version": "3.1.1",
4
4
  "description": "The AsyncAPI generator. It can generate documentation, code, anything!",
5
5
  "main": "./lib/generator.js",
6
6
  "engines": {