Skip to content
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

add frozenset to schema.py/field_class_to_schema #1557

Closed
wangpeibao opened this issue May 26, 2020 · 5 comments · Fixed by #1560
Closed

add frozenset to schema.py/field_class_to_schema #1557

wangpeibao opened this issue May 26, 2020 · 5 comments · Fixed by #1560

Comments

@wangpeibao
Copy link
Contributor

wangpeibao commented May 26, 2020

Feature Request

         pydantic version: 1.5.1
        pydantic compiled: False
             install path: /home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic
           python version: 3.6.5 (default, May 11 2018, 13:30:17)  [GCC 7.3.0]
                 platform: Linux-4.15.0-29deepin-generic-x86_64-with-Deepin-15.11-stable
 optional deps. installed: []
Use pydantic to validate frozenset in FastApi, when I open SwaggerUI in Chrome, error occurs.
Add frozenset type in schema.py/field_class_to_schema to resolve the error.

```exception
Traceback (most recent call last):
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/fastapi/applications.py", line 148, in __call__
    await super().__call__(scope, receive, send)  # pragma: no cover
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/applications.py", line 102, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/routing.py", line 550, in __call__
    await route.handle(scope, receive, send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/routing.py", line 227, in handle
    await self.app(scope, receive, send)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/starlette/routing.py", line 41, in app
    response = await func(request)
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/fastapi/applications.py", line 103, in openapi
    return JSONResponse(self.openapi())
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/fastapi/applications.py", line 95, in openapi
    openapi_prefix=self.openapi_prefix,
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/fastapi/openapi/utils.py", line 291, in get_openapi
    flat_models=flat_models, model_name_map=model_name_map
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/fastapi/utils.py", line 84, in get_model_definitions
    model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic/schema.py", line 456, in model_process_schema
    model, by_alias=by_alias, model_name_map=model_name_map, ref_prefix=ref_prefix, known_models=known_models
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic/schema.py", line 492, in model_type_schema
    f, by_alias=by_alias, model_name_map=model_name_map, ref_prefix=ref_prefix, known_models=known_models
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic/schema.py", line 191, in field_schema
    known_models=known_models or set(),
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic/schema.py", line 418, in field_type_schema
    known_models=known_models,
  File "/home/wang/PycharmProjects/FastApiLearn/venv/lib/python3.6/site-packages/pydantic/schema.py", line 686, in field_singleton_schema
    raise ValueError(f'Value not declarable with JSON Schema, field: {field}')
ValueError: Value not declarable with JSON Schema, field: name='a' type=frozenset required=True


```schema.py 

field_class_to_schema: Tuple[Tuple[Any, Dict[str, Any]], ...] = (
    (Path, {'type': 'string', 'format': 'path'}),
    (datetime, {'type': 'string', 'format': 'date-time'}),
    (date, {'type': 'string', 'format': 'date'}),
    (time, {'type': 'string', 'format': 'time'}),
    (timedelta, {'type': 'number', 'format': 'time-delta'}),
    (IPv4Network, {'type': 'string', 'format': 'ipv4network'}),
    (IPv6Network, {'type': 'string', 'format': 'ipv6network'}),
    (IPv4Interface, {'type': 'string', 'format': 'ipv4interface'}),
    (IPv6Interface, {'type': 'string', 'format': 'ipv6interface'}),
    (IPv4Address, {'type': 'string', 'format': 'ipv4'}),
    (IPv6Address, {'type': 'string', 'format': 'ipv6'}),
    (str, {'type': 'string'}),
    (bytes, {'type': 'string', 'format': 'binary'}),
    (bool, {'type': 'boolean'}),
    (int, {'type': 'integer'}),
    (float, {'type': 'number'}),
    (Decimal, {'type': 'number'}),
    (UUID, {'type': 'string', 'format': 'uuid'}),
    (dict, {'type': 'object'}),
    (list, {'type': 'array', 'items': {}}),
    (tuple, {'type': 'array', 'items': {}}),
    (set, {'type': 'array', 'items': {}, 'uniqueItems': True}),
    (frozenset, {'type': 'array', 'items': {}, 'uniqueItems': True}),  # my addition
)
@samuelcolvin
Copy link
Member

Could you fix your formatting in the issue?

It would be useful to see a demonstration of the problem: e.g. code that raises an exception.

@wangpeibao
Copy link
Contributor Author

I have added my exception.

@wangpeibao wangpeibao reopened this May 26, 2020
@samuelcolvin
Copy link
Member

I meant a self contained example that demonstrates the problem.

E.g.:

from pydantic import BaseModel

...

@wangpeibao
Copy link
Contributor Author

from pydantic import BaseModel
class Item(BaseModel):
    item1: frozenset

This piece of code is ok. But when I read "SwaggerUI" in web framework "FastApi", the above exception occured.

@samuelcolvin
Copy link
Member

That's not a demonstration of the problem. The error can be caused with:

from pydantic import BaseModel


class Item(BaseModel):
    item1: frozenset


item = Item(item1={1, 2, 3})
print(item.schema())

exception:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print(item.schema())
  File "/Users/samuel/code/pydantic/pydantic/main.py", line 558, in schema
    s = model_schema(cls, by_alias=by_alias)
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 137, in model_schema
    m_schema, m_definitions, nested_models = model_process_schema(
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 465, in model_process_schema
    m_schema, m_definitions, nested_models = model_type_schema(
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 501, in model_type_schema
    f_schema, f_definitions, f_nested_models = field_schema(
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 190, in field_schema
    f_schema, f_definitions, f_nested_models = field_type_schema(
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 417, in field_type_schema
    f_schema, f_definitions, f_nested_models = field_singleton_schema(
  File "/Users/samuel/code/pydantic/pydantic/schema.py", line 733, in field_singleton_schema
    raise ValueError(f'Value not declarable with JSON Schema, field: {field}')
ValueError: Value not declarable with JSON Schema, field: name='item1' type=frozenset required=True

This is what I was looking for.

PR welcome to to fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants