Skip to content

Commit

Permalink
Manage DuplicateComponentNameError apispec error.
Browse files Browse the repository at this point in the history
Ref #137
  • Loading branch information
buxx committed Feb 25, 2019
1 parent 2ad8d18 commit 1a26689
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 25 deletions.
2 changes: 1 addition & 1 deletion hapic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from hapic.hapic import Hapic
from hapic.data import HapicData
from hapic.hapic import Hapic
from hapic.infos import __version__

# To make a default hapic instance, must determine processor
Expand Down
20 changes: 12 additions & 8 deletions hapic/doc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from apispec import APISpec
from apispec import BasePlugin
from apispec.exceptions import DuplicateComponentNameError
import yaml

from hapic.context import ContextInterface
Expand Down Expand Up @@ -319,14 +320,17 @@ def get_doc(
schema_usages.append(SchemaUsage(error_schema))

for schema_usage in set(schema_usages):
spec.components.schema(
main_plugin.schema_name_resolver(
schema_usage.schema,
**schema_usage.plugin_name_resolver_kwargs,
),
schema=schema_usage.schema,
**schema_usage.plugin_helper_kwargs,
)
try:
spec.components.schema(
main_plugin.schema_name_resolver(
schema_usage.schema,
**schema_usage.plugin_name_resolver_kwargs,
),
schema=schema_usage.schema,
**schema_usage.plugin_helper_kwargs,
)
except DuplicateComponentNameError:
pass # Already registered schema

# add views
for controller in controllers:
Expand Down
2 changes: 1 addition & 1 deletion hapic/error/serpyco.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
import dataclasses
import typing

import dataclasses
from hapic.error.main import DefaultErrorBuilder
from hapic.processor.main import ProcessValidationError
from hapic.type import TYPE_SCHEMA
Expand Down
4 changes: 3 additions & 1 deletion hapic/ext/aiohttp/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ def add_view(
http_method: str,
view_func: typing.Callable[..., typing.Any],
) -> None:
self.app.router.add_routes([web.route(http_method, path=route, handler=view_func)])
self.app.router.add_routes(
[web.route(http_method, path=route, handler=view_func)]
)

def serve_directory(self, route_prefix: str, directory_path: str) -> None:
self.app.router.add_static(route_prefix, path=directory_path)
Expand Down
2 changes: 1 addition & 1 deletion hapic/processor/marshmallow.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import typing

from apispec import BasePlugin
from apispec_marshmallow_advanced import MarshmallowAdvancedPlugin
from apispec_marshmallow_advanced.common import generate_schema_name
from apispec_marshmallow_advanced.common import (
schema_class_resolver as schema_class_resolver_
)

from apispec_marshmallow_advanced import MarshmallowAdvancedPlugin
from hapic.doc.schema import SchemaUsage
from hapic.error.main import ErrorBuilderInterface
from hapic.error.marshmallow import MarshmallowDefaultErrorBuilder
Expand Down
56 changes: 44 additions & 12 deletions tests/func/fake_api/test_fake_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,25 @@ def test_func__test_fake_api_doc_ok__all_framework(context):
doc["definitions"]["AboutResponseSchema"]
== SWAGGER_DOC_API["definitions"]["AboutResponseSchema"]
)
assert (
doc["definitions"]["ListsUserSchema"]
== SWAGGER_DOC_API["definitions"]["ListsUserSchema"]
)

# FIXME BS 2019-02-04: With irregularity,
# apispec.ext.marshmallow.common.get_unique_schema_name increment counter
# on UserSchema_without_email_address_first_name_last_name . See #136
try:
assert (
"#/definitions/UserSchema_without_email_address_first_name_last_name"
== doc["definitions"]["ListsUserSchema"]["properties"]["items"][
"items"
]["$ref"]
)
except AssertionError:
assert (
"#/definitions/UserSchema_without_email_address_first_name_last_name1"
== doc["definitions"]["ListsUserSchema"]["properties"]["items"][
"items"
]["$ref"]
)

assert (
doc["definitions"]["NoContentSchema"]
== SWAGGER_DOC_API["definitions"]["NoContentSchema"]
Expand All @@ -212,11 +227,28 @@ def test_func__test_fake_api_doc_ok__all_framework(context):
doc["definitions"]["UserSchema_without_id"]
== SWAGGER_DOC_API["definitions"]["UserSchema_without_id"]
)
assert (
doc["definitions"][
"UserSchema_without_email_address_first_name_last_name"
]
== SWAGGER_DOC_API["definitions"][
"UserSchema_without_email_address_first_name_last_name"
]
)

# FIXME BS 2019-02-04: With irregularity,
# apispec.ext.marshmallow.common.get_unique_schema_name increment counter
# on UserSchema_without_email_address_first_name_last_name . See #136
if (
"UserSchema_without_email_address_first_name_last_name1"
in doc["definitions"]
):
assert (
doc["definitions"][
"UserSchema_without_email_address_first_name_last_name1"
]
== SWAGGER_DOC_API["definitions"][
"UserSchema_without_email_address_first_name_last_name"
]
)
else:
assert (
doc["definitions"][
"UserSchema_without_email_address_first_name_last_name"
]
== SWAGGER_DOC_API["definitions"][
"UserSchema_without_email_address_first_name_last_name"
]
)
26 changes: 26 additions & 0 deletions tests/func/test_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,3 +883,29 @@ def my_controller():
assert schema_field["maxLength"] == 5
assert schema_field["minLength"] == 5
assert schema_field["enum"] == ["01000", "11111"]

def test_func__schema_with_many__ok__with_exclude(self):
hapic = Hapic(processor_class=MarshmallowProcessor)
# TODO BS 20171113: Make this test non-bottle
app = bottle.Bottle()
hapic.set_context(MyContext(app=app))

class MySchema(marshmallow.Schema):
first_name = marshmallow.fields.String(required=True)
last_name = marshmallow.fields.String(required=False)

@hapic.with_api_doc()
@hapic.output_body(MySchema(many=True, exclude=("last_name",)))
def my_controller(hapic_data=None):
pass

app.route("/", method="GET", callback=my_controller)
doc = hapic.generate_doc()

assert {
"MySchema_without_last_name": {
"type": "object",
"properties": {"first_name": {"type": "string"}},
"required": ["first_name"],
}
} == doc["definitions"]
3 changes: 2 additions & 1 deletion tests/func/test_doc_serpyco.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# coding: utf-8
import dataclasses

import bottle

import dataclasses
from hapic import Hapic
from hapic.error.serpyco import SerpycoDefaultErrorBuilder
from hapic.ext.bottle import BottleContext
Expand Down

0 comments on commit 1a26689

Please sign in to comment.