Repository: asyncapi/modelina (ts)

Issue:
Python Pydantic improvements
#### Reason/Context
##### Field.alias
It seems that for Pydantic `Field` typing use of `property.description` as an `alias` is incorrect, and `property.name` or some other field should be used instead. Current implementation:
```typescript
const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType<PythonOptions> = {
  property(params) {
    const type = params.property.required
      ? params.property.property.type
      : `Optional[${params.property.property.type}]`;
    const alias = params.property.property.originalInput['description']
      ? `alias='${params.property.property.originalInput['description']}'`
      : '';

    return `${params.property.propertyName}: ${type} = Field(${alias})`;
  }
};
```
Possible fix:
```typescript
    const alias = params.property.property.originalInput['name']
      ? `alias='${params.property.property.originalInput['name']}'`
      : '';
```
##### Field.description
Introduce support for setting a Field's `description` from `property.description`

##### Extra.forbid
For models declaring `additionalProperties` as false enable native validation:
```python
from pydantic import BaseModel, Extra


class Model(BaseModel, extra=Extra.forbid):
    a: str
```

#### Description
- Change from `description` to `name` when setting `Field.alias` will be a breaking change, but it's more of a misuse or a bug in the current state.


Pull request description:
fix: multi line descriptions for the pydantic preset in python
<!--   Thank you for your contribution. Before you submit the pull request:
1. Follow our contribution guidelines
2. Test your changes and attach their results to the pull request.
3. Update the relevant documentation.
-->

**Description**

- fixes multi-line descriptions for the Pydantic preset in Python

**Related issue(s)**
<!-- If you refer to a particular issue, provide its number, otherwise, remove this section.
For example, `Resolves #123`, `Fixes #43`, or `See also #33`. The `See also #33` option will not automatically close the issue after the PR merge. -->
Fixes #1058 

Patch:
diff --git a/examples/generate-python-pydantic-models/__snapshots__/index.spec.ts.snap b/examples/generate-python-pydantic-models/__snapshots__/index.spec.ts.snap
index 75df868f..39488f65 100644
--- a/examples/generate-python-pydantic-models/__snapshots__/index.spec.ts.snap
+++ b/examples/generate-python-pydantic-models/__snapshots__/index.spec.ts.snap
@@ -3,8 +3,8 @@
 exports[`Should be able to render python models and should log expected output to console: class-model 1`] = `
 Array [
   "class Root(BaseModel): 
-  optionalField: Optional[str] = Field(alias='this field is optional')
-  requiredField: str = Field(alias='this field is required')
+  optionalField: Optional[str] = Field(alias='''this field is optional''')
+  requiredField: str = Field(alias='''this field is required''')
   noDescription: Optional[str] = Field()
   options: Optional[Options] = Field()
 ",
diff --git a/src/generators/python/presets/Pydantic.ts b/src/generators/python/presets/Pydantic.ts
index 0b507855..7d787bb1 100644
--- a/src/generators/python/presets/Pydantic.ts
+++ b/src/generators/python/presets/Pydantic.ts
@@ -22,7 +22,7 @@ const PYTHON_PYDANTIC_CLASS_PRESET: ClassPresetType<PythonOptions> = {
       ? params.property.property.type
       : `Optional[${params.property.property.type}]`;
     const alias = params.property.property.originalInput['description']
-      ? `alias='${params.property.property.originalInput['description']}'`
+      ? `alias='''${params.property.property.originalInput['description']}'''`
       : '';
 
     return `${params.property.propertyName}: ${type} = Field(${alias})`;


Test patch:
diff --git a/test/generators/python/presets/Pydantic.spec.ts b/test/generators/python/presets/Pydantic.spec.ts
new file mode 100644
index 00000000..9801720c
--- /dev/null
+++ b/test/generators/python/presets/Pydantic.spec.ts
@@ -0,0 +1,34 @@
+import {
+  PythonGenerator,
+  PYTHON_PYDANTIC_PRESET
+} from '../../../../src/generators/python';
+
+describe('PYTHON_PYDANTIC_PRESET', () => {
+  let generator: PythonGenerator;
+
+  beforeEach(() => {
+    generator = new PythonGenerator({
+      presets: [PYTHON_PYDANTIC_PRESET]
+    });
+  });
+
+  test('should render pydantic for class', async () => {
+    const doc = {
+      title: 'Test',
+      type: 'object',
+      properties: {
+        prop: {
+          description: `test
+  multi
+  line
+  description`,
+          type: 'string'
+        }
+      }
+    };
+
+    const models = await generator.generate(doc);
+    expect(models).toHaveLength(1);
+    expect(models[0].result).toMatchSnapshot();
+  });
+});
diff --git a/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap
new file mode 100644
index 00000000..7745d870
--- /dev/null
+++ b/test/generators/python/presets/__snapshots__/Pydantic.spec.ts.snap
@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PYTHON_PYDANTIC_PRESET should render pydantic for class 1`] = `
+"class Test(BaseModel): 
+  prop: Optional[str] = Field(alias='''test
+    multi
+    line
+    description''')
+  additionalProperties: Optional[dict[Any, Any]] = Field()
+"
+`;