---
title: "Pydantic v2 Plugin"
description: "Generate Pydantic v2 models from OpenAPI with the Pydantic plugin for openapi-python. Fully compatible with validators, transformers, and all core features."
url: "https://heyapi.dev/docs/openapi/python/plugins/pydantic"
---

### About

[Section titled “About”](#about)

[Pydantic](https://pydantic.dev/docs/validation/latest/get-started/) is the most widely used data validation library for Python. Fast and extensible, Pydantic plays nicely with your linters/IDE/brain.

The Pydantic plugin for Hey API generates models from your OpenAPI spec, fully compatible with validators, transformers, and all core features.

## Features

[Section titled “Features”](#features)

* Pydantic v2 support
* seamless integration with `@hey-api/openapi-python` ecosystem
* Pydantic models for requests, responses, and reusable definitions
* minimal learning curve thanks to extending the underlying technology

## Installation

[Section titled “Installation”](#installation)

In your [configuration](https://heyapi.dev/docs/openapi/python/get-started), add `pydantic` to your plugins and you’ll be ready to generate Pydantic artifacts. 🎉

openapi-python.config.ts

```js
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  plugins: [
    // ...other plugins
    'pydantic',
  ],
};
```

### SDKs

[Section titled “SDKs”](#sdks)

Pydantic can validate or transform data directly in your SDK. Set `validator` or `transformer` to `true` on the SDK plugin to enable it.

* validator

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      'pydantic',
      {
        name: '@hey-api/sdk',
        validator: true,
      },
    ],
  };
  ```

* transformer

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      'pydantic',
      {
        name: '@hey-api/sdk',
        transformer: true,
      },
    ],
  };
  ```

The SDK page covers [validators](https://heyapi.dev/docs/openapi/python/plugins/sdk#validators) and [transformers](https://heyapi.dev/docs/openapi/python/plugins/sdk#transformers) in more detail.

## Output

[Section titled “Output”](#output)

The Pydantic plugin will generate the following artifacts, depending on the input specification.

## Requests

[Section titled “Requests”](#requests)

A Pydantic model is generated for every request layer of each endpoint.

* example

  pydantic.gen.ts

  ```ts
  const vDeletePetHeaders = v.object({
    api_key: v.optional(v.string()),
  });


  const vDeletePetPath = v.object({
    petId: v.number(),
  });


  const vDeletePetQuery = v.object({
    additionalMetadata: v.string(),
  });
  ```

* config

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'pydantic',
        requests: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options.

## Responses

[Section titled “Responses”](#responses)

A single Pydantic model is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated model is a union of all possible response shapes.

* example

  pydantic.gen.ts

  ```ts
  const vResponse = v.union([
    v.object({
      foo: v.optional(v.string()),
    }),
    v.object({
      bar: v.optional(v.number()),
    }),
  ]);
  ```

* config

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'pydantic',
        responses: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options.

## Definitions

[Section titled “Definitions”](#definitions)

A Pydantic model is generated for every reusable definition from your input.

* example

  pydantic.gen.ts

  ```ts
  const vFoo = v.pipe(v.number(), v.integer());


  const vBar = v.object({
    bar: v.optional(v.array(v.pipe(v.number(), v.integer()))),
  });
  ```

* config

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'pydantic',
        definitions: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options.

## Metadata

[Section titled “Metadata”](#metadata)

It’s often useful to associate a schema with some additional [metadata](https://pydantic-docs.helpmanual.io/usage/schema/#metadata) for documentation, code generation, AI structured outputs, form validation, and other purposes. You can set `metadata` to `true` to attach descriptions to schemas when available.

* example

  pydantic.gen.ts

  ```ts
  export const vFoo = v.pipe(
    v.string(),
    v.metadata({
      description: 'Additional metadata',
    }),
  );
  ```

* config

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'pydantic',
        metadata: true,
      },
    ],
  };
  ```

For more control over metadata, you can provide your own function. It receives the source `schema`, the target `node` object, and the `$` builder for populating metadata.

* example

  pydantic.gen.ts

  ```ts
  export const vFoo = v.pipe(
    v.string(),
    v.metadata({
      hasTitle: false,
      createdAt: 1735732800000,
    }),
  );
  ```

* config

  openapi-python.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'pydantic',
        metadata({ $, node, schema }) {
          node.prop('hasTitle', $.literal(Boolean(schema.title)));
          node.prop('createdAt', $.literal(Date.now()));
        },
      },
    ],
  };
  ```

## Resolvers

[Section titled “Resolvers”](#resolvers)

You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/python/plugins/concepts/resolvers).

## API

[Section titled “API”](#api)

You can view the complete list of options in the [UserConfig](https://github.com/hey-api/hey-api/blob/main/packages/openapi-python/src/plugins/pydantic/types.ts) interface.
