add DTO object generator
This commit is contained in:
@@ -2,3 +2,4 @@
|
|||||||
https://www.asyncapi.com/docs/tools/generator/generator-template#overview-of-steps
|
https://www.asyncapi.com/docs/tools/generator/generator-template#overview-of-steps
|
||||||
|
|
||||||
asyncapi generate fromTemplate openapi_templete/test/fixtures/asyncapi_test.yaml ./openapi_templete -o ./generated-code --force-write
|
asyncapi generate fromTemplate openapi_templete/test/fixtures/asyncapi_test.yaml ./openapi_templete -o ./generated-code --force-write
|
||||||
|
asyncapi generate fromTemplate openapi_templete/test/fixtures/asyncapi_1.yaml ./openapi_templete -o ./generated-code --force-write
|
||||||
|
|||||||
+2
-2
@@ -62,8 +62,8 @@ components:
|
|||||||
name: mtr_request
|
name: mtr_request
|
||||||
payload:
|
payload:
|
||||||
type: object
|
type: object
|
||||||
# required:
|
required:
|
||||||
# - to_server
|
- to_server
|
||||||
$ref: '#/components/schemas/mtr_request_schema'
|
$ref: '#/components/schemas/mtr_request_schema'
|
||||||
mtr_uuid:
|
mtr_uuid:
|
||||||
payload:
|
payload:
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@your-org/asyncapi-python-template",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Custom Python async client generator for AsyncAPI",
|
|
||||||
"generator": {
|
|
||||||
"supportedProtocols": ["mqtt", "kafka", "nats"],
|
|
||||||
"parameters": {
|
|
||||||
"client_name": {
|
|
||||||
"description": "Name of the generated client class",
|
|
||||||
"default": "AsyncClient",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
"async_mode": {
|
|
||||||
"description": "Enable async/await support",
|
|
||||||
"default": true,
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@asyncapi/generator-react-sdk": "^1.1.0",
|
|
||||||
"@asyncapi/modelina": "^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
'generate:before': ({ asyncapi, templateParams = {} }) => {
|
|
||||||
// Modify the AsyncAPI document before generation
|
|
||||||
if (templateParams.version) {
|
|
||||||
asyncapi._json.info.version = templateParams.version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { File, Text } from "@asyncapi/generator-react-sdk";
|
|
||||||
import { PythonGenerator, FormatHelpers } from "@asyncapi/modelina";
|
|
||||||
|
|
||||||
export default async function({ asyncapi, params, originalAsyncAPI }) {
|
|
||||||
const files = [];
|
|
||||||
|
|
||||||
// Generate Python data models using Modelina
|
|
||||||
const pythonGenerator = new PythonGenerator();
|
|
||||||
const models = await pythonGenerator.generate(asyncapi);
|
|
||||||
|
|
||||||
// Create models.py file
|
|
||||||
const modelsContent = models.map(model =>
|
|
||||||
`# ${model.modelName}\n${model.result}\n`
|
|
||||||
).join('\n');
|
|
||||||
|
|
||||||
files.push(
|
|
||||||
<File name="models.py">
|
|
||||||
<Text>"""Auto-generated Python models from AsyncAPI spec."""</Text>
|
|
||||||
<Text>{modelsContent}</Text>
|
|
||||||
</File>
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate async client
|
|
||||||
files.push(
|
|
||||||
<File name="client.py">
|
|
||||||
<Text>{generateClientCode(asyncapi, params)}</Text>
|
|
||||||
</File>
|
|
||||||
);
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateClientCode(asyncapi, params) {
|
|
||||||
const clientName = params.client_name || "AsyncClient";
|
|
||||||
const servers = asyncapi.servers().all();
|
|
||||||
|
|
||||||
let code = `"""Auto-generated async client for ${asyncapi.info().title()}"""\n\n`;
|
|
||||||
code += `import asyncio\nimport aiohttp\n\n`;
|
|
||||||
code += `class ${clientName}:\n`;
|
|
||||||
code += ` """Async client for ${asyncapi.info().title()}"""\n\n`;
|
|
||||||
code += ` def __init__(self, host: str):\n`;
|
|
||||||
code += ` self.host = host\n`;
|
|
||||||
code += ` self.session = None\n\n`;
|
|
||||||
|
|
||||||
// Add methods for each channel/operation
|
|
||||||
asyncapi.channels().all().forEach(channel => {
|
|
||||||
const channelName = FormatHelpers.toCamelCase(channel.address() || channel.name());
|
|
||||||
code += ` async def ${channelName}_publish(self, payload):\n`;
|
|
||||||
code += ` """Publish to ${channel.name()}"""\n`;
|
|
||||||
code += ` if not self.session:\n`;
|
|
||||||
code += ` self.session = aiohttp.ClientSession()\n`;
|
|
||||||
code += ` # Implementation for ${channel.name()}\n\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "python-async-template",
|
|
||||||
"generator": {},
|
|
||||||
"dependencies": {
|
|
||||||
"@asyncapi/generator-react-sdk": "^1.1.0",
|
|
||||||
"@asyncapi/modelina": "^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-3130
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,8 @@
|
|||||||
"supportedProtocols": ["mqtt"]
|
"supportedProtocols": ["mqtt"]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@asyncapi/generator-react-sdk": "^0.2.25"
|
"@asyncapi/generator-react-sdk": "^1.1.2",
|
||||||
|
"@asyncapi/modelina": "^5.10.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"rimraf": "^5.0.0"
|
"rimraf": "^5.0.0"
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
// return <File name="client.py">{asyncapi.info().title()}</File>
|
// return <File name="client.py">{asyncapi.info().title()}</File>
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { File } from '@asyncapi/generator-react-sdk';
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
|
||||||
export default function ({ asyncapi }) {
|
export default function ({ asyncapi }) {
|
||||||
|
|||||||
@@ -9,21 +9,33 @@
|
|||||||
|
|
||||||
|
|
||||||
import { File } from '@asyncapi/generator-react-sdk';
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
import { PythonGenerator, FormatHelpers } from '@asyncapi/modelina';
|
||||||
|
|
||||||
export default function ({ asyncapi, params }) {
|
export default async function ({ asyncapi, params }) {
|
||||||
const channels = Object.keys(asyncapi.components());
|
const channels = Object.keys(asyncapi.components());
|
||||||
|
|
||||||
let content = ''
|
let content = ''
|
||||||
for (const channel of channels) {
|
for (const channel of channels) {
|
||||||
content += `# channel: ${channel}\n`
|
content += `# channel: ${channel}\n`
|
||||||
}
|
}
|
||||||
|
const pythonGenerator = new PythonGenerator();
|
||||||
|
const models = await pythonGenerator.generate(asyncapi);
|
||||||
|
const files = [];
|
||||||
|
for (const model of models) {
|
||||||
|
const modelFileName = `${FormatHelpers.toPascalCase(model.modelName)}.py`;
|
||||||
|
files.push(modelFileName);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<File name="client2.py"># {asyncapi.info().title()}
|
<File name="client2.py"># {asyncapi.info().title()}
|
||||||
{`\n`}
|
{`\n`}
|
||||||
# {asyncapi.info().description()}
|
# {asyncapi.info().description()}
|
||||||
{`\n`}
|
{`\n`}
|
||||||
{channels.map((ch) => `# channel: ${ch}\n`)}
|
# {channels.map((ch) => `# channel: ${ch}\n`)}
|
||||||
{content}
|
# {content}
|
||||||
|
# {'=========='}
|
||||||
|
# {files}
|
||||||
|
# {'=========='}
|
||||||
</File>
|
</File>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
import { PythonGenerator, FormatHelpers } from '@asyncapi/modelina';
|
||||||
|
|
||||||
|
export default async function schemaRender({ asyncapi }) {
|
||||||
|
const pythonGenerator = new PythonGenerator();
|
||||||
|
const models = await pythonGenerator.generate(asyncapi);
|
||||||
|
const files = [];
|
||||||
|
for (const model of models) {
|
||||||
|
files.push(model.model)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <File name="debug.py">{JSON.stringify(models, null, 2)}</File>
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// 1
|
||||||
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
// 2
|
||||||
|
import { PythonGenerator, FormatHelpers } from '@asyncapi/modelina';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef RenderArgument
|
||||||
|
* @type {object}
|
||||||
|
* @property {AsyncAPIDocument} asyncapi document object received from the generator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render all schema models
|
||||||
|
* @param {RenderArgument} param0
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
// 3
|
||||||
|
export default async function schemaRender({ asyncapi }) {
|
||||||
|
// 4
|
||||||
|
const pythonGenerator = new PythonGenerator();
|
||||||
|
// 5
|
||||||
|
const models = await pythonGenerator.generate(asyncapi);
|
||||||
|
// 6
|
||||||
|
const files = [];
|
||||||
|
// 7
|
||||||
|
for (const model of models) {
|
||||||
|
// 8
|
||||||
|
const modelFileName = `${FormatHelpers.toPascalCase(model.modelName)}.py`;
|
||||||
|
// 9
|
||||||
|
files.push(<File name={modelFileName}>{model.result}</File>);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
asyncapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: Order Service (NATS)
|
||||||
|
version: 1.0.0
|
||||||
|
description: Event-driven order service using NATS
|
||||||
|
|
||||||
|
servers:
|
||||||
|
nats:
|
||||||
|
host: nats://localhost:4222
|
||||||
|
protocol: nats
|
||||||
|
description: Local NATS server
|
||||||
|
|
||||||
|
channels:
|
||||||
|
order.created:
|
||||||
|
address: order.created
|
||||||
|
messages:
|
||||||
|
OrderCreated:
|
||||||
|
$ref: '#/components/messages/OrderCreated'
|
||||||
|
|
||||||
|
order.placed:
|
||||||
|
address: order.placed
|
||||||
|
messages:
|
||||||
|
OrderPlaced:
|
||||||
|
$ref: '#/components/messages/OrderPlaced'
|
||||||
|
|
||||||
|
operations:
|
||||||
|
onOrderCreated:
|
||||||
|
action: receive
|
||||||
|
channel:
|
||||||
|
$ref: '#/channels/order.created'
|
||||||
|
messages:
|
||||||
|
- $ref: '#/channels/order.created/messages/OrderCreated'
|
||||||
|
|
||||||
|
onOrderPlaced:
|
||||||
|
action: send
|
||||||
|
channel:
|
||||||
|
$ref: '#/channels/order.placed'
|
||||||
|
messages:
|
||||||
|
- $ref: '#/channels/order.placed/messages/OrderPlaced'
|
||||||
|
|
||||||
|
components:
|
||||||
|
messages:
|
||||||
|
OrderCreated:
|
||||||
|
name: OrderCreated
|
||||||
|
title: Order Created
|
||||||
|
summary: Event emitted when an order is created.
|
||||||
|
payload:
|
||||||
|
$ref: '#/components/schemas/OrderCreated'
|
||||||
|
|
||||||
|
OrderPlaced:
|
||||||
|
name: OrderPlaced
|
||||||
|
title: Order Placed
|
||||||
|
summary: Event emitted when an order is placed.
|
||||||
|
payload:
|
||||||
|
$ref: '#/components/schemas/OrderPlaced'
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
OrderCreated:
|
||||||
|
$id: OrderCreated
|
||||||
|
title: OrderCreated
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- orderId
|
||||||
|
- customerId
|
||||||
|
- createdAt
|
||||||
|
properties:
|
||||||
|
orderId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||||
|
customerId:
|
||||||
|
type: string
|
||||||
|
example: "cust-123"
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
example: "2025-06-03T12:00:00Z"
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- created
|
||||||
|
- pending
|
||||||
|
- confirmed
|
||||||
|
default: created
|
||||||
|
|
||||||
|
OrderPlaced:
|
||||||
|
$id: OrderPlaced
|
||||||
|
title: OrderPlaced
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- orderId
|
||||||
|
- customerId
|
||||||
|
- items
|
||||||
|
- placedAt
|
||||||
|
properties:
|
||||||
|
orderId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||||
|
customerId:
|
||||||
|
type: string
|
||||||
|
example: "cust-123"
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- productId
|
||||||
|
- quantity
|
||||||
|
properties:
|
||||||
|
productId:
|
||||||
|
type: string
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
minimum: 1
|
||||||
|
placedAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
example: "2025-06-03T12:05:00Z"
|
||||||
|
totalAmount:
|
||||||
|
type: number
|
||||||
|
format: double
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
# .venv/bin/asyncapi-python-codegen asyncapi.yaml out --force-write
|
|
||||||
# kouknout na FastStream
|
|
||||||
# https://nats.io/blog/nats-supported-by-faststream/#writing-app-code
|
|
||||||
# https://github.com/asyncapi/python-paho-template
|
|
||||||
# https://www.asyncapi.com/docs/tools/generator/generator-template
|
|
||||||
# https://www.asyncapi.com/docs/tools/generator/generator-template --force-write
|
|
||||||
# https://pypi.org/project/asyncapi-python/
|
|
||||||
# https://github.com/G-USI/asyncapi-python
|
|
||||||
|
|
||||||
|
|
||||||
asyncapi: 3.0.0
|
|
||||||
info:
|
|
||||||
title: Job Events
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
servers:
|
|
||||||
nats_localhost:
|
|
||||||
host: localhost:4222
|
|
||||||
protocol: nats
|
|
||||||
|
|
||||||
channels:
|
|
||||||
run_test:
|
|
||||||
address: mtr_test.run_test
|
|
||||||
messages:
|
|
||||||
run_test:
|
|
||||||
$ref: '#/components/messages/mtr_request'
|
|
||||||
return_uuid:
|
|
||||||
address: null
|
|
||||||
messages:
|
|
||||||
run_test:
|
|
||||||
$ref: '#/components/messages/mtr_uuid'
|
|
||||||
|
|
||||||
operations:
|
|
||||||
get_mtr_test:
|
|
||||||
action: send
|
|
||||||
channel:
|
|
||||||
$ref: '#/channels/run_test'
|
|
||||||
reply:
|
|
||||||
address:
|
|
||||||
location: "$message.header#/replayTo"
|
|
||||||
channel:
|
|
||||||
$ref: '#/channels/return_uuid'
|
|
||||||
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
mtr_request_schema:
|
|
||||||
payload:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
to_server:
|
|
||||||
type: string
|
|
||||||
mtr_sleep:
|
|
||||||
type: integer
|
|
||||||
mtr_uuid_schema:
|
|
||||||
payload:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uuid:
|
|
||||||
type: string
|
|
||||||
messages:
|
|
||||||
mtr_request:
|
|
||||||
name: mtr_request
|
|
||||||
payload:
|
|
||||||
type: object
|
|
||||||
# required:
|
|
||||||
# - to_server
|
|
||||||
$ref: '#/components/schemas/mtr_request_schema'
|
|
||||||
mtr_uuid:
|
|
||||||
payload:
|
|
||||||
$ref: '#/components/schemas/mtr_uuid_schema'
|
|
||||||
Reference in New Issue
Block a user