Skip to content

Commit

Permalink
Release 0.0.3 (#2)
Browse files Browse the repository at this point in the history
* fix manifest

* update readme

* new spec test and refactor

* Version bump
  • Loading branch information
avanov committed Dec 29, 2020
1 parent 4c7e26e commit ee83bd4
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 27 deletions.
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# https://docs.python.org/3/distutils/sourcedist.html#manifest
include README.rst CHANGES LICENSE
include README.rst CHANGELOG.rst LICENSE.txt
recursive-include requirements *.txt
recursive-include openapi_type
recursive-include openapi_type py.typed
Expand Down
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ Documentation is hosted on ReadTheDocs: https://openapi-type.readthedocs.io/en/d
Test framework
--------------

Run existing test suite with
The project uses `Nix <https://nixos.org/>`_ for bootstrapping its dev environment.

You can run existing test suite with

.. code:: bash
Expand Down
94 changes: 72 additions & 22 deletions openapi_type/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ class StringValue(NamedTuple):
enum: PVector[str] = pvector()
example: str = ''

Ref = NewType('Ref', str)

class RefValue(NamedTuple):
ref: str

class Reference(NamedTuple):
ref: Ref


class ObjectValue(NamedTuple):
Expand All @@ -41,7 +43,7 @@ class ArrayValue(NamedTuple):
items: 'SchemaValue' # type: ignore


SchemaValue = Union[StringValue, IntegerValue, RefValue, ObjectValue, ArrayValue] # type: ignore
SchemaValue = Union[StringValue, IntegerValue, Reference, ObjectValue, ArrayValue] # type: ignore


class ObjectSchema(NamedTuple):
Expand Down Expand Up @@ -73,16 +75,24 @@ class ProductSchemaType(NamedTuple):
all_of: Sequence['SchemaType'] # type: ignore


SchemaType = Union[ObjectSchema, ArraySchema, ResponseRef, ObjectRef, ProductSchemaType] # type: ignore
SchemaType = Union[ObjectSchema, ArraySchema, ResponseRef, Reference, ProductSchemaType] # type: ignore


class Components(NamedTuple):
schemas: Mapping[str, SchemaType]
links: Mapping[str, SchemaType] = pmap()


class ServerVar(NamedTuple):
default: str
enum: Sequence[str]
description: str = ''


class Server(NamedTuple):
url: str
description: str = ''
variables: Mapping[str, ServerVar] = pmap()


class InfoLicense(NamedTuple):
Expand Down Expand Up @@ -112,7 +122,7 @@ class SpecFormat(Enum):
V3_0_1 = '3.0.1'


class MethodParameter(NamedTuple):
class OperationParameter(NamedTuple):
name: str
in_: str
schema: SchemaValue
Expand All @@ -125,10 +135,13 @@ class MethodParameter(NamedTuple):
HeaderName = NewType('HeaderName', str)


class ResponseContentType(Enum):
class MediaTypeTag(Enum):
""" Response content type
"""
JSON = 'application/json'
XML = 'application/xml'
TEXT = 'text/plain'
FORM_URLENCODED = 'application/x-www-form-urlencoded'


class Header(NamedTuple):
Expand All @@ -138,38 +151,73 @@ class Header(NamedTuple):
description: str = ''


class ResponseContent(NamedTuple):
class MediaType(NamedTuple):
""" https://swagger.io/specification/#media-type-object
"""
schema: PMap[str, Any] = pmap()
example: PMap[str, Any] = pmap()
examples: Mapping[str, Any] = pmap()
encoding: Mapping[str, Any] = pmap()


class Response(NamedTuple):
""" Response of an endpoint
"""
content: PMap[ResponseContentType, ResponseContent] = pmap()
content: PMap[MediaTypeTag, MediaType] = pmap()
headers: PMap[HeaderName, Header] = pmap()
description: str = ''


class Method(NamedTuple):
class ExternalDoc(NamedTuple):
url: str
description: str = ''


class RequestBody(NamedTuple):
""" https://swagger.io/specification/#request-body-object
"""
content: Mapping[MediaTypeTag, Any]
description: str = ''
required: bool = False


class Operation(NamedTuple):
""" https://swagger.io/specification/#operation-object
"""
responses: Mapping[HTTPCode, Response]
external_docs: Optional[ExternalDoc]
summary: str = ''
operation_id: str = ''
parameters: FrozenSet[Union[OperationParameter, Reference]] = frozenset()
request_body: Union[None, RequestBody, Reference] = None
description: str = ''
tags: FrozenSet[str] = frozenset()
parameters: FrozenSet[MethodParameter] = frozenset()
responses: Mapping[HTTPCode, Response] = pmap()
callbacks: Mapping[str, Mapping[str, Any]] = pmap()


class Methods(NamedTuple):
class PathItem(NamedTuple):
""" Describes endpoint methods
"""
head: Optional[Method]
get: Optional[Method]
post: Optional[Method]
put: Optional[Method]
patch: Optional[Method]
delete: Optional[Method]
head: Optional[Operation]
get: Optional[Operation]
post: Optional[Operation]
put: Optional[Operation]
patch: Optional[Operation]
delete: Optional[Operation]
trace: Optional[Operation]
servers: Sequence[Server] = pvector()
ref: Ref = Ref('')
summary: str = ''
description: str = ''


SecurityName = NewType('SecurityName', str)


class SpecTag(NamedTuple):
name: str
external_docs: Optional[ExternalDoc]
description: str = ''


class OpenAPI(NamedTuple):
Expand All @@ -179,15 +227,17 @@ class OpenAPI(NamedTuple):
info: Info
""" Various metadata
"""
paths: Mapping[str, Methods] = pmap()
paths: Mapping[str, PathItem]
components: Components = Components(schemas=pmap(), links=pmap())
servers: Sequence[Server] = pvector()
security: Sequence[Mapping[SecurityName, Sequence[str]]] = pvector()
tags: Sequence[SpecTag] = pvector()


overrides = {
MethodParameter.in_: 'in',
RefValue.ref: '$ref',
ObjectRef.ref: '$ref'
OperationParameter.in_: 'in',
Reference.ref: '$ref',
PathItem.ref: '$ref',
}
_camelcase_attribute_names = flags.GlobalNameOverride(lambda x: camelize(x, uppercase_first_letter=False))

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def requirements(at_path: Path):
# ----------------------------

setup(name='openapi-type',
version='0.0.2',
version='0.0.3',
description='OpenAPI Type',
long_description=README,
classifiers=[
Expand Down
170 changes: 170 additions & 0 deletions tests/custom_examples/one.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"openapi": "3.0.0",
"info": {
"title": "Title",
"description": "Desc",
"contact": {
"name": "Me",
"url": "https://github.com/avanov",
"email": "me@example.com"
},
"version": "1.0"
},
"servers": [
{
"url": "https://api-dev.example.com/v2",
"description": "Development server"
},
{
"url": "https://api-integration.example.com/v2",
"description": "Integration server"
},
{
"url": "https://api.example.com/v2",
"description": "Production server"
}
],
"paths": {
"/auth": {
"post": {
"tags": [
"Authentication & Authorization"
],
"summary": "Authentication",
"description": "Authentication",
"operationId": "auth",
"parameters": [
{
"name": "Accept-Language",
"in": "header",
"description": "List of acceptable human languages for response.",
"required": false,
"style": "simple",
"explode": false,
"schema": {
"type": "string"
}
},
{
"name": "X-HTTP-Method-Override",
"in": "header",
"description": "Put here the HTTP method you want, when making call by the POST method to avoid interference of nasty firewall rules.",
"required": false,
"style": "simple",
"explode": false,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"apiKey": {
"type": "string",
"description": "The open api key that is given to the specific system."
},
"locale": {
"type": "string",
"description": "Locale"
},
"timezone": {
"type": "string",
"description": "Timezone in POSIX format."
},
"source": {
"allOf": [
{
"type": "object",
"properties": {
"tenant": {
"type": "string",
"description": "The tenant to which the origin belongs."
}
}
},
{
"title": "Source",
"required": [
"type",
"name",
"version",
"instance"
],
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"system",
"database",
"file-system"
],
"description": "The type of the source."
},
"name": {
"type": "string",
"description": "The name of the source."
},
"version": {
"type": "string",
"description": "The version of the source."
},
"instance": {
"type": "string",
"description": "Specific instance of the source."
}
},
"x-tags": [
"domain"
]
}
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"title": "Response",
"required": [
"code",
"locale"
],
"type": "object",
"properties": {
"code": {
"minimum": 0,
"type": "integer",
"description": "Response code"
},
"locale": {
"type": "string",
"description": "Response locale"
}
},
"x-tags": [
"system"
]
}
]
}
}
}
}
}
}
}
}
}
10 changes: 8 additions & 2 deletions tests/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

TESTS_ROOT = Path(__file__).parent.absolute()
SPEC_EXAMPLES_DIR = TESTS_ROOT.parent / "specification" / "examples" / "v3.0"
CUSTOM_EXAMPLES_DIR = TESTS_ROOT / "custom_examples"

SPECS = [
(x, SPEC_EXAMPLES_DIR / f"{x}.json") for x in [
Expand All @@ -10,5 +11,10 @@
'api-with-examples',
'callback-example',
'link-example',
'uspto'
]]
'uspto',
]
] + [
(x, CUSTOM_EXAMPLES_DIR / f"{x}.json") for x in [
"one"
]
]

0 comments on commit ee83bd4

Please sign in to comment.