add example code generator
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
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
|
||||||
+5
-1
@@ -1,8 +1,12 @@
|
|||||||
# .venv/bin/asyncapi-python-codegen asyncapi.yaml out --force
|
# .venv/bin/asyncapi-python-codegen asyncapi.yaml out --force-write
|
||||||
# kouknout na FastStream
|
# kouknout na FastStream
|
||||||
# https://nats.io/blog/nats-supported-by-faststream/#writing-app-code
|
# https://nats.io/blog/nats-supported-by-faststream/#writing-app-code
|
||||||
# https://github.com/asyncapi/python-paho-template
|
# 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
|
||||||
|
# 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
|
asyncapi: 3.0.0
|
||||||
info:
|
info:
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
'generate:before': ({ asyncapi, templateParams = {} }) => {
|
||||||
|
// Modify the AsyncAPI document before generation
|
||||||
|
if (templateParams.version) {
|
||||||
|
asyncapi._json.info.version = templateParams.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "python-async-template",
|
||||||
|
"generator": {},
|
||||||
|
"dependencies": {
|
||||||
|
"@asyncapi/generator-react-sdk": "^1.1.0",
|
||||||
|
"@asyncapi/modelina": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "python-mqtt-client-template",
|
"name": "python-mqtt-client-template",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "A template that generates a Python FastStream NATS client.",
|
"description": "A template that generates a Python MQTT client using MQTT.",
|
||||||
"generator": {
|
"generator": {
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v3",
|
||||||
"generator": ">=2.0.0 <4.0.0",
|
"generator": ">=2.0.0 <4.0.0",
|
||||||
"supportedProtocols": ["faststream", "nats"]
|
"supportedProtocols": ["mqtt"]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@asyncapi/generator-react-sdk": "^0.2.25"
|
"@asyncapi/generator-react-sdk": "^0.2.25"
|
||||||
|
|||||||
@@ -1,7 +1,31 @@
|
|||||||
//1
|
// //1
|
||||||
import { File } from '@asyncapi/generator-react-sdk'
|
// import { File } from '@asyncapi/generator-react-sdk'
|
||||||
//2
|
// //2
|
||||||
|
// export default function ({ asyncapi }) {
|
||||||
|
// //3
|
||||||
|
// return <File name="client.py">{asyncapi.info().title()}</File>
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
|
||||||
export default function ({ asyncapi }) {
|
export default function ({ asyncapi }) {
|
||||||
//3
|
return (
|
||||||
return <File name="client.py">{asyncapi.info().title()}</File>
|
<File name="client.py">
|
||||||
|
{`import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
mqttBroker = "test.mosquitto.org"
|
||||||
|
|
||||||
|
class TemperatureServiceClient:
|
||||||
|
def __init__(self):
|
||||||
|
self.client = mqtt.Client()
|
||||||
|
self.client.connect(mqttBroker)
|
||||||
|
|
||||||
|
|
||||||
|
def sendTemperatureChange(self, id):
|
||||||
|
topic = "temperature/changed"
|
||||||
|
self.client.publish(topic, id)`}
|
||||||
|
</File>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// //1
|
||||||
|
// import { File } from '@asyncapi/generator-react-sdk'
|
||||||
|
// //2
|
||||||
|
// export default function ({ asyncapi }) {
|
||||||
|
// //3
|
||||||
|
// return <File name="client.py">{asyncapi.info().title()}</File>
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import { File } from '@asyncapi/generator-react-sdk';
|
||||||
|
|
||||||
|
export default function ({ asyncapi, params }) {
|
||||||
|
const channels = Object.keys(asyncapi.components());
|
||||||
|
|
||||||
|
let content = ''
|
||||||
|
for (const channel of channels) {
|
||||||
|
content += `# channel: ${channel}\n`
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<File name="client2.py"># {asyncapi.info().title()}
|
||||||
|
{`\n`}
|
||||||
|
# {asyncapi.info().description()}
|
||||||
|
{`\n`}
|
||||||
|
{channels.map((ch) => `# channel: ${ch}\n`)}
|
||||||
|
{content}
|
||||||
|
</File>
|
||||||
|
)
|
||||||
|
}
|
||||||
+24
-33
@@ -1,44 +1,35 @@
|
|||||||
# .venv/bin/asyncapi-python-codegen asyncapi.yaml out --force
|
|
||||||
# asyncapi generate fromTemplate ./test/fixtures/asyncapi.yaml ./ -o ./out/project
|
|
||||||
# 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
|
|
||||||
|
|
||||||
asyncapi: 3.0.0
|
asyncapi: 3.0.0
|
||||||
|
|
||||||
info:
|
info:
|
||||||
title: Temperature Service
|
title: Temperature Service
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
description: This service is in charge of processing all the events related to temperature.
|
description: Temperature sensor publishing readings
|
||||||
|
|
||||||
servers:
|
servers:
|
||||||
dev:
|
production:
|
||||||
host: test.mosquitto.org #in case you're using local mosquitto instance, change this value to localhost.
|
host: localhost:4222
|
||||||
protocol: mqtt
|
protocol: nats
|
||||||
|
|
||||||
channels:
|
channels:
|
||||||
temperatureChanged:
|
temperature/read:
|
||||||
address: temperature/changed
|
address: temperature/read
|
||||||
messages:
|
messages:
|
||||||
temperatureChange:
|
TemperatureMessage:
|
||||||
description: Message that is being sent when the temperature in the bedroom changes.
|
$ref: '#/components/messages/TemperatureMessage'
|
||||||
payload:
|
|
||||||
$ref: '#/components/schemas/temperatureId'
|
|
||||||
description: Updates the bedroom temperature in the database when the temperatures drops or goes up.
|
|
||||||
|
|
||||||
operations:
|
operations:
|
||||||
temperatureChange:
|
receiveTemperature:
|
||||||
action: receive
|
action: receive
|
||||||
summary: Message sent to the broker when the temperature is changed.
|
|
||||||
channel:
|
channel:
|
||||||
$ref: '#/channels/temperatureChanged'
|
$ref: '#/channels/temperature/read'
|
||||||
|
description: Receive temperature readings
|
||||||
components:
|
components:
|
||||||
schemas:
|
messages:
|
||||||
temperatureId:
|
TemperatureMessage:
|
||||||
type: object
|
name: TemperatureMessage
|
||||||
additionalProperties: false
|
title: Temperature Message
|
||||||
properties:
|
payload:
|
||||||
temperatureId:
|
type: object
|
||||||
type: string
|
properties:
|
||||||
|
value:
|
||||||
|
type: number
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
sensor_id:
|
||||||
|
type: string
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# .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'
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# 1
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
# 2
|
||||||
|
mqttBroker = "test.mosquitto.org"
|
||||||
|
|
||||||
|
class TemperatureServiceClient:
|
||||||
|
def __init__(self):
|
||||||
|
# 3
|
||||||
|
self.client = mqtt.Client()
|
||||||
|
# 4
|
||||||
|
self.client.connect(mqttBroker)
|
||||||
|
|
||||||
|
|
||||||
|
def sendTemperatureChange(self, id):
|
||||||
|
# 5
|
||||||
|
topic = "temperature/changed"
|
||||||
|
# 6
|
||||||
|
self.client.publish(topic, id)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
from client import TemperatureServiceClient
|
||||||
|
from random import randrange
|
||||||
|
import time
|
||||||
|
|
||||||
|
client = TemperatureServiceClient()
|
||||||
|
|
||||||
|
id_length = 8
|
||||||
|
min_value = 10**(id_length-1) # Minimum value with 8 digits (e.g., 10000000)
|
||||||
|
max_value = 10**id_length - 1 # Maximum value with 8 digits (e.g., 99999999)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
randomId = randrange(min_value, max_value + 1)
|
||||||
|
client.sendTemperatureChange(randomId)
|
||||||
|
print("New temperature detected " + str(randomId) + " sent to temperature/changed")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "datamodel-code-generator"
|
name = "datamodel-code-generator"
|
||||||
version = "0.57.0"
|
version = "0.59.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "argcomplete" },
|
{ name = "argcomplete" },
|
||||||
@@ -237,9 +237,9 @@ dependencies = [
|
|||||||
{ name = "pydantic" },
|
{ name = "pydantic" },
|
||||||
{ name = "pyyaml" },
|
{ name = "pyyaml" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/5d/44/87d5980f813a1e323c5d726b3ac5fec8c915ce8a77fcdceaf9c00457dbae/datamodel_code_generator-0.57.0.tar.gz", hash = "sha256:0eda778ea06eaa476e542a5f1fe1d14cc3bbf686edb33a0ad6151c7d19089906", size = 932941 }
|
sdist = { url = "https://files.pythonhosted.org/packages/8d/50/21488efdb515afc04039e19d876ee668d85a5c9590a3a4bb25b27f2b99c0/datamodel_code_generator-0.59.0.tar.gz", hash = "sha256:054e4d5568c27db5a993f6b3e1d34af53bd1f6d1b6c18b7166908b0f3dc04bd4", size = 1098070 }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/c5/c1/4fb9a44bb4a305b860c5a5b1866dcccfac3b76f5f170a9e68fc7733e16d2/datamodel_code_generator-0.57.0-py3-none-any.whl", hash = "sha256:d26bf5defe5154493d0aa5a822b7725332b9e9dd2abccc2f8856052286aa83b5", size = 259343 },
|
{ url = "https://files.pythonhosted.org/packages/f6/ef/8e2479e3ba432bb3333d0f01d6bdc520cc7f765ccbfac134b015d806bc2b/datamodel_code_generator-0.59.0-py3-none-any.whl", hash = "sha256:c8c119ab618d24a619d635fef7aa9c96b69e069a4d287c9adfc148ae28368a69", size = 316232 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.optional-dependencies]
|
[package.optional-dependencies]
|
||||||
@@ -448,11 +448,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "more-itertools"
|
name = "more-itertools"
|
||||||
version = "11.0.2"
|
version = "11.1.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/f7/139d22fef48ac78127d18e01d80cf1be40236ae489769d17f35c3d425293/more_itertools-11.0.2.tar.gz", hash = "sha256:392a9e1e362cbc106a2457d37cabf9b36e5e12efd4ebff1654630e76597df804", size = 144659 }
|
sdist = { url = "https://files.pythonhosted.org/packages/de/1d/f4da6f02cdffe04d6362210b807146a26044c88d839208aec273bb0d9184/more_itertools-11.1.0.tar.gz", hash = "sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d", size = 145772 }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl", hash = "sha256:6e35b35f818b01f691643c6c611bc0902f2e92b46c18fffa77ae1e7c46e912e4", size = 71939 },
|
{ url = "https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl", hash = "sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192", size = 72226 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -522,11 +522,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platformdirs"
|
name = "platformdirs"
|
||||||
version = "4.9.6"
|
version = "4.10.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400 }
|
sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224 }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348 },
|
{ url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -771,17 +771,17 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typer"
|
name = "typer"
|
||||||
version = "0.25.1"
|
version = "0.26.4"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-doc" },
|
{ name = "annotated-doc" },
|
||||||
{ name = "click" },
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
{ name = "rich" },
|
{ name = "rich" },
|
||||||
{ name = "shellingham" },
|
{ name = "shellingham" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276 }
|
sdist = { url = "https://files.pythonhosted.org/packages/8e/d3/90c1ee19209cb59f6ad185883fd4ccfcf72f8f0bfd549d5a8b70474611d0/typer-0.26.4.tar.gz", hash = "sha256:25b128964de66c5ea36d5ac82adc579e5e113509b17469edf9f5a4a1864ff2a9", size = 201191 }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409 },
|
{ url = "https://files.pythonhosted.org/packages/f0/6d/5a525c69df4a90892135e5d490b00e9e46402491f3416d4395fcb0d0201e/typer-0.26.4-py3-none-any.whl", hash = "sha256:11bfd7b43557137e373c2b10f6967a555f9678a61ed72c808968b011d95534d6", size = 122436 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
Reference in New Issue
Block a user