Skip to content

Commit c4d4b8d

Browse files
Add schema_features property to parsers for version detection (#2929)
* Add schema_features property to parsers for version detection * Add version-specific schema processing using schema_features (#2934) * Add --jsonschema-version and --openapi-version CLI options * Add --schema-version and --schema-version-mode CLI options * Regenerate CLI docs * Add version-specific schema processing using schema_features * Implement flag-based behavior control for schema version * Add comprehensive version-specific feature checks with exclusive_as_number flag * Replace getattr with direct config access for schema_version_mode * docs: update llms.txt files Generated by GitHub Actions * docs: update CLI reference documentation and prompt data 🤖 Generated by GitHub Actions * Add SchemaFeaturesT generic type parameter to Parser * Fix test snapshot: add exclusive_as_number field * Refactor: genericize _create_default_config using _get_config_class * Add parameterized e2e tests for --schema-version and --schema-version-mode * docs: update CLI reference documentation and prompt data 🤖 Generated by GitHub Actions * docs: update llms.txt files Generated by GitHub Actions * Refactor: use _config_class_name class variable instead of method override * docs: update CLI reference documentation and prompt data 🤖 Generated by GitHub Actions * docs: update llms.txt files Generated by GitHub Actions * Add Schema Version Support to docs navigation * docs: update llms.txt files Generated by GitHub Actions * Docs: add detailed unsupported features tables * docs: update llms.txt files Generated by GitHub Actions * Docs: add version info to unsupported features tables * docs: update llms.txt files Generated by GitHub Actions * Add e2e tests for schema version error handling and strict mode warnings --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent d4adf40 commit c4d4b8d

26 files changed

+2071
-111
lines changed

docs/cli-reference/base-options.md

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
| [`--input-model`](#input-model) | Import a Python type or dict schema from a module. |
1111
| [`--input-model-ref-strategy`](#input-model-ref-strategy) | Strategy for referenced types when using --input-model. |
1212
| [`--output`](#output) | Specify the destination path for generated Python code. |
13+
| [`--schema-version`](#schema-version) | Schema version to use for parsing. |
14+
| [`--schema-version-mode`](#schema-version-mode) | Schema version validation mode. |
1315
| [`--url`](#url) | Fetch schema from URL with custom HTTP headers. |
1416

1517
---
@@ -326,6 +328,290 @@ is written to stdout.
326328

327329
---
328330

331+
## `--schema-version` {#schema-version}
332+
333+
Schema version to use for parsing.
334+
335+
The `--schema-version` option specifies the schema version to use instead of auto-detection.
336+
Valid values depend on input type: JsonSchema (draft-04, draft-06, draft-07, 2019-09, 2020-12)
337+
or OpenAPI (3.0, 3.1). Default is 'auto' (detected from $schema or openapi field).
338+
339+
!!! tip "Usage"
340+
341+
```bash
342+
datamodel-codegen --input schema.json --schema-version draft-07 # (1)!
343+
```
344+
345+
1. :material-arrow-left: `--schema-version` - the option documented here
346+
347+
??? example "Examples"
348+
349+
=== "OpenAPI"
350+
351+
**Input Schema:**
352+
353+
```yaml
354+
openapi: "3.0.0"
355+
info:
356+
version: 1.0.0
357+
title: Swagger Petstore
358+
license:
359+
name: MIT
360+
servers:
361+
- url: http://petstore.swagger.io/v1
362+
paths:
363+
/pets:
364+
get:
365+
summary: List all pets
366+
operationId: listPets
367+
tags:
368+
- pets
369+
parameters:
370+
- name: limit
371+
in: query
372+
description: How many items to return at one time (max 100)
373+
required: false
374+
schema:
375+
type: integer
376+
format: int32
377+
responses:
378+
'200':
379+
description: A paged array of pets
380+
headers:
381+
x-next:
382+
description: A link to the next page of responses
383+
schema:
384+
type: string
385+
content:
386+
application/json:
387+
schema:
388+
$ref: "#/components/schemas/Pets"
389+
default:
390+
description: unexpected error
391+
content:
392+
application/json:
393+
schema:
394+
$ref: "#/components/schemas/Error"
395+
x-amazon-apigateway-integration:
396+
uri:
397+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
398+
passthroughBehavior: when_no_templates
399+
httpMethod: POST
400+
type: aws_proxy
401+
post:
402+
summary: Create a pet
403+
operationId: createPets
404+
tags:
405+
- pets
406+
responses:
407+
'201':
408+
description: Null response
409+
default:
410+
description: unexpected error
411+
content:
412+
application/json:
413+
schema:
414+
$ref: "#/components/schemas/Error"
415+
x-amazon-apigateway-integration:
416+
uri:
417+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
418+
passthroughBehavior: when_no_templates
419+
httpMethod: POST
420+
type: aws_proxy
421+
/pets/{petId}:
422+
get:
423+
summary: Info for a specific pet
424+
operationId: showPetById
425+
tags:
426+
- pets
427+
parameters:
428+
- name: petId
429+
in: path
430+
required: true
431+
description: The id of the pet to retrieve
432+
schema:
433+
type: string
434+
responses:
435+
'200':
436+
description: Expected response to a valid request
437+
content:
438+
application/json:
439+
schema:
440+
$ref: "#/components/schemas/Pets"
441+
default:
442+
description: unexpected error
443+
content:
444+
application/json:
445+
schema:
446+
$ref: "#/components/schemas/Error"
447+
x-amazon-apigateway-integration:
448+
uri:
449+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
450+
passthroughBehavior: when_no_templates
451+
httpMethod: POST
452+
type: aws_proxy
453+
components:
454+
schemas:
455+
Pet:
456+
required:
457+
- id
458+
- name
459+
properties:
460+
id:
461+
type: integer
462+
format: int64
463+
default: 1
464+
name:
465+
type: string
466+
tag:
467+
type: string
468+
Pets:
469+
type: array
470+
items:
471+
$ref: "#/components/schemas/Pet"
472+
Users:
473+
type: array
474+
items:
475+
required:
476+
- id
477+
- name
478+
properties:
479+
id:
480+
type: integer
481+
format: int64
482+
name:
483+
type: string
484+
tag:
485+
type: string
486+
Id:
487+
type: string
488+
Rules:
489+
type: array
490+
items:
491+
type: string
492+
Error:
493+
description: error result
494+
required:
495+
- code
496+
- message
497+
properties:
498+
code:
499+
type: integer
500+
format: int32
501+
message:
502+
type: string
503+
apis:
504+
type: array
505+
items:
506+
type: object
507+
properties:
508+
apiKey:
509+
type: string
510+
description: To be used as a dataset parameter value
511+
apiVersionNumber:
512+
type: string
513+
description: To be used as a version parameter value
514+
apiUrl:
515+
type: string
516+
format: uri
517+
description: "The URL describing the dataset's fields"
518+
apiDocumentationUrl:
519+
type: string
520+
format: uri
521+
description: A URL to the API console for each API
522+
Event:
523+
type: object
524+
description: Event object
525+
properties:
526+
name:
527+
type: string
528+
Result:
529+
type: object
530+
properties:
531+
event:
532+
$ref: '#/components/schemas/Event'
533+
```
534+
535+
**Output:**
536+
537+
> **Error:** File not found: openapi/api.py
538+
539+
=== "JSON Schema"
540+
541+
**Input Schema:**
542+
543+
```json
544+
{
545+
"$schema": "http://json-schema.org/draft-07/schema",
546+
"type": "object",
547+
"properties": {"s": {"type": ["string"]}},
548+
"required": ["s"]
549+
}
550+
```
551+
552+
**Output:**
553+
554+
```python
555+
# generated by datamodel-codegen:
556+
# filename: simple_string.json
557+
558+
from __future__ import annotations
559+
560+
from pydantic import BaseModel
561+
562+
563+
class Model(BaseModel):
564+
s: str
565+
```
566+
567+
---
568+
569+
## `--schema-version-mode` {#schema-version-mode}
570+
571+
Schema version validation mode.
572+
573+
The `--schema-version-mode` option controls how schema version validation is performed.
574+
'lenient' (default): accept all features regardless of version.
575+
'strict': warn on features outside the declared/detected version.
576+
577+
!!! tip "Usage"
578+
579+
```bash
580+
datamodel-codegen --input schema.json --schema-version-mode lenient # (1)!
581+
```
582+
583+
1. :material-arrow-left: `--schema-version-mode` - the option documented here
584+
585+
??? example "Examples"
586+
587+
**Input Schema:**
588+
589+
```json
590+
{
591+
"$schema": "http://json-schema.org/draft-07/schema",
592+
"type": "object",
593+
"properties": {"s": {"type": ["string"]}},
594+
"required": ["s"]
595+
}
596+
```
597+
598+
**Output:**
599+
600+
```python
601+
# generated by datamodel-codegen:
602+
# filename: simple_string.json
603+
604+
from __future__ import annotations
605+
606+
from pydantic import BaseModel
607+
608+
609+
class Model(BaseModel):
610+
s: str
611+
```
612+
613+
---
614+
329615
## `--url` {#url}
330616

331617
Fetch schema from URL with custom HTTP headers.

docs/cli-reference/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This documentation is auto-generated from test cases.
88

99
| Category | Options | Description |
1010
|----------|---------|-------------|
11-
| 📁 [Base Options](base-options.md) | 7 | Input/output configuration |
11+
| 📁 [Base Options](base-options.md) | 9 | Input/output configuration |
1212
| 🔧 [Typing Customization](typing-customization.md) | 27 | Type annotation and import behavior |
1313
| 🏷️ [Field Customization](field-customization.md) | 24 | Field naming and docstring behavior |
1414
| 🏗️ [Model Customization](model-customization.md) | 39 | Model generation behavior |
@@ -161,6 +161,8 @@ This documentation is auto-generated from test cases.
161161

162162
### S {#s}
163163

164+
- [`--schema-version`](base-options.md#schema-version)
165+
- [`--schema-version-mode`](base-options.md#schema-version-mode)
164166
- [`--set-default-enum-member`](field-customization.md#set-default-enum-member)
165167
- [`--shared-module-name`](general-options.md#shared-module-name)
166168
- [`--skip-root-model`](model-customization.md#skip-root-model)

docs/cli-reference/quick-reference.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ datamodel-codegen [OPTIONS]
2222
| [`--input-model`](base-options.md#input-model) | Import a Python type or dict schema from a module. |
2323
| [`--input-model-ref-strategy`](base-options.md#input-model-ref-strategy) | Strategy for referenced types when using --input-model. |
2424
| [`--output`](base-options.md#output) | Specify the destination path for generated Python code. |
25+
| [`--schema-version`](base-options.md#schema-version) | Schema version to use for parsing. |
26+
| [`--schema-version-mode`](base-options.md#schema-version-mode) | Schema version validation mode. |
2527
| [`--url`](base-options.md#url) | Fetch schema from URL with custom HTTP headers. |
2628

2729
### 🔧 Typing Customization
@@ -299,6 +301,8 @@ All options sorted alphabetically:
299301
- [`--remove-special-field-name-prefix`](field-customization.md#remove-special-field-name-prefix) - Remove the special prefix from field names.
300302
- [`--reuse-model`](model-customization.md#reuse-model) - Reuse identical model definitions instead of generating dupl...
301303
- [`--reuse-scope`](model-customization.md#reuse-scope) - Scope for model reuse detection (root or tree).
304+
- [`--schema-version`](base-options.md#schema-version) - Schema version to use for parsing.
305+
- [`--schema-version-mode`](base-options.md#schema-version-mode) - Schema version validation mode.
302306
- [`--set-default-enum-member`](field-customization.md#set-default-enum-member) - Set the first enum member as the default value for enum fiel...
303307
- [`--shared-module-name`](general-options.md#shared-module-name) - Customize the name of the shared module for deduplicated mod...
304308
- [`--skip-root-model`](model-customization.md#skip-root-model) - Skip generation of root model when schema contains nested de...

0 commit comments

Comments
 (0)