Skip to content

[WIP] Add OpenAPI v3.0/v3.1 parser #826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions chaotic-openapi/chaotic_openapi/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Any, Union, Dict
from openapi_python_client.parser.openapi import GeneratorData
from openapi_python_client.config import Config, ConfigFile, MetaType
from pathlib import Path

def parse(data_dict: Dict[str, Any], config: Config):
return GeneratorData.from_dict(data_dict, config=config)

def config():
return Config.from_sources(ConfigFile(), MetaType.NONE, Path("example.yaml"), 'utf-8', False, None)

from openapi_python_client import _get_document

conf = config()

# print(_get_document(source=conf.document_source, timeout=10))
print(parse(_get_document(source=conf.document_source, timeout=10), conf))
176 changes: 176 additions & 0 deletions chaotic-openapi/chaotic_openapi/example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
openapi: 3.0.3
info:
title: Key-Value Storage API
description: An API to manage a key-value store with CRUD operations and basic authentication.
version: 1.0.0
servers:
- url: https://api.kvstore.example.com/v1
description: Production server
- url: http://localhost:3000/v1
description: Development server
components:
securitySchemes:
BasicAuth:
type: http
scheme: basic
schemas:
KeyValuePair:
type: object
properties:
key:
type: string
description: Unique key for the item
value:
type: string
description: Value associated with the key
required:
- key
- value
ErrorResponse:
type: object
properties:
error:
type: string
description: Error message
paths:
/kv:
get:
summary: Get all key-value pairs
description: Retrieve all key-value pairs in the store.
security:
- BasicAuth: []
responses:
'200':
description: A list of key-value pairs
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/KeyValuePair'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
post:
summary: Create a new key-value pair
description: Add a new key-value pair to the store.
security:
- BasicAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/KeyValuePair'
responses:
'201':
description: Key-value pair created successfully
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/kv/{key}:
get:
summary: Get a key-value pair
description: Retrieve a value by its key.
security:
- BasicAuth: []
parameters:
- name: key
in: path
required: true
schema:
type: string
description: The key to retrieve
responses:
'200':
description: Key-value pair retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/KeyValuePair'
'404':
description: Key not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
put:
summary: Update a key-value pair
description: Update the value associated with a specific key.
security:
- BasicAuth: []
parameters:
- name: key
in: path
required: true
schema:
type: string
description: The key to update
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/KeyValuePair'
responses:
'200':
description: Key-value pair updated successfully
'404':
description: Key not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
delete:
summary: Delete a key-value pair
description: Remove a key-value pair from the store.
security:
- BasicAuth: []
parameters:
- name: key
in: path
required: true
schema:
type: string
description: The key to delete
responses:
'204':
description: Key-value pair deleted successfully
'404':
description: Key not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- BasicAuth: []
Empty file.
7 changes: 7 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel
from typing import Optional

class Contact(BaseModel):
name: Optional[str] = None
url: Optional[str] = None
email: Optional[str] = None
42 changes: 42 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import Dict, List, Optional, Union, Any
from pydantic import BaseModel, Field

class Schema(BaseModel):
type: Optional[str] = None
format: Optional[str] = None
items: Optional[Union[Dict, 'Schema']] = None
properties: Optional[Dict[str, Union[Dict, 'Schema']]] = None
required: Optional[List[str]] = None
description: Optional[str] = None
default: Optional[Any] = None
allOf: Optional[List[Union[Dict, 'Schema']]] = None
oneOf: Optional[List[Union[Dict, 'Schema']]] = None
anyOf: Optional[List[Union[Dict, 'Schema']]] = None
not_: Optional[Union[Dict, 'Schema']] = Field(None, alias="not")
additionalProperties: Optional[Union[bool, Dict, 'Schema']] = None
enum: Optional[List[Any]] = None
multipleOf: Optional[float] = None
maximum: Optional[float] = None
exclusiveMaximum: Optional[bool] = None
minimum: Optional[float] = None
exclusiveMinimum: Optional[bool] = None
maxLength: Optional[int] = None
minLength: Optional[int] = None
pattern: Optional[str] = None
maxItems: Optional[int] = None
minItems: Optional[int] = None
uniqueItems: Optional[bool] = None
maxProperties: Optional[int] = None
minProperties: Optional[int] = None
ref: Optional[str] = Field(None, alias="$ref")

Schema.model_rebuild()

class Definitions(BaseModel):
__root__: Dict[str, Schema]

def __getitem__(self, key):
return self.__root__[key]

def __iter__(self):
return iter(self.__root__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from typing import Optional
from pydantic import BaseModel

class ExternalDocs(BaseModel):
url: str
description: Optional[str] = None
13 changes: 13 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from pydantic import BaseModel
from typing import Optional

from contact import Contact
from license import License

class Info(BaseModel):
title: str
description: Optional[str] = None
termsOfService: Optional[str] = None
contact: Optional[Contact] = None
license: Optional[License] = None
version: str
6 changes: 6 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/license.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from pydantic import BaseModel
from typing import Optional

class License(BaseModel):
name: str
url: Optional[str] = None
33 changes: 33 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/parameters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import Dict, List, Optional, Union
from pydantic import BaseModel, Field

class ParameterBase(BaseModel):
name: str
in_: str = Field(..., alias="in")
description: Optional[str] = None
required: Optional[bool] = None

class BodyParameter(ParameterBase):
schema_: Dict = Field(..., alias="schema")

class NonBodyParameter(ParameterBase):
type: str
format: Optional[str] = None
items: Optional[Dict] = None
collectionFormat: Optional[str] = None
default: Optional[Union[str, int, float, bool, List]] = None
maximum: Optional[float] = None
exclusiveMaximum: Optional[bool] = None
minimum: Optional[float] = None
exclusiveMinimum: Optional[bool] = None
maxLength: Optional[int] = None
minLength: Optional[int] = None
pattern: Optional[str] = None
maxItems: Optional[int] = None
minItems: Optional[int] = None
uniqueItems: Optional[bool] = None
enum: Optional[List] = None
multipleOf: Optional[float] = None

Parameter = Union[BodyParameter, NonBodyParameter]
Parameters = Dict[str, Parameter]
8 changes: 8 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/path_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from pydantic import BaseModel
from typing import Optional, List, Dict, Any

class PathItem(BaseModel):
summary: Optional[str] = None
description: Optional[str] = None
parameters: Optional[List[Dict[str, Any]]] = None
responses: Dict[int, Any]
6 changes: 6 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from pydantic import RootModel
from typing import Optional, List, Dict, Any
from path_item import PathItem

class Paths(RootModel):
root: Dict[str, Dict[str, PathItem]]
17 changes: 17 additions & 0 deletions chaotic-openapi/chaotic_openapi/swagger-schema/responses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel

class Response(BaseModel):
description: str
schema: Optional[Dict] = None
headers: Optional[Dict[str, Dict]] = None
examples: Optional[Dict[str, Any]] = None

class Responses(BaseModel):
__root__: Dict[str, Response]

def __getitem__(self, key):
return self.__root__[key]

def __iter__(self):
return iter(self.__root__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Dict, List, Optional
from pydantic import BaseModel, Field

class SecurityScheme(BaseModel):
type: str
description: Optional[str] = None
name: Optional[str] = None
in_: Optional[str] = Field(None, alias="in")
flow: Optional[str] = None
authorizationUrl: Optional[str] = None
tokenUrl: Optional[str] = None
scopes: Optional[Dict[str, str]] = None

class SecurityDefinitions(BaseModel):
__root__: Dict[str, SecurityScheme]

def __getitem__(self, key):
return self.__root__[key]

def __iter__(self):
return iter(self.__root__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from typing import Dict, List
from pydantic import BaseModel

class SecurityRequirement(BaseModel):
__root__: Dict[str, List[str]]

def __getitem__(self, key):
return self.__root__[key]

def __iter__(self):
return iter(self.__root__)
Loading