question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support PEP-585 style collection type hints for OpenAPI?

See original GitHub issue

I’m newly discovering BlackSheep and really liking it so far! (Especially being able to use simple data classes for OpenAPI generation.)

PEP-585 adds support for generics syntax to standard collection types in Python 3.9+, eg. list and set so that we don’t need to use their equivalents from the typing module.

I had hoped the following could work:

from dataclasses import dataclass

from blacksheep.server import Application
from blacksheep.server.openapi.v3 import OpenAPIHandler
from openapidocs.v3 import Info

app = Application()

docs = OpenAPIHandler(info=Info(title="Example API", version="0.0.1"))
docs.bind_app(app)


@dataclass
class Pet:
    name: str
    age: int | None


@app.router.get("/pets")
def pets() -> list[Pet]:
    return [
        Pet(name="Ren"),
        Pet(name="Stimpy", age=3),
    ]

But, on server startup, I receive the following error:

Traceback (most recent call last):
  File "[path]/blacksheep/server/application.py", line 714, in _handle_lifespan
    await self.start()
  File "[path]/blacksheep/server/application.py", line 703, in start
    await self.after_start.fire()
  File "[path]/blacksheep/server/application.py", line 108, in fire
    await handler(self.context, *args, **keywargs)
  File "[path]/blacksheep/server/openapi/common.py", line 394, in build_docs
    docs = self.generate_documentation(app)
  File "[path]/blacksheep/server/openapi/v3.py", line 276, in generate_documentation
    info=self.info, paths=self.get_paths(app), components=self.components
  File "[path]/blacksheep/server/openapi/v3.py", line 280, in get_paths
    own_paths = self.get_routes_docs(app.router, path_prefix)
  File "[path]/blacksheep/server/openapi/v3.py", line 915, in get_routes_docs
    responses=self.get_responses(handler) or {},
  File "[path]/blacksheep/server/openapi/v3.py", line 813, in get_responses
    {
  File "[path]/blacksheep/server/openapi/v3.py", line 817, in <dictcomp>
    content=self._get_content_from_response_info(value.content),
  File "[path]/blacksheep/server/openapi/v3.py", line 754, in _get_content_from_response_info
    ] = self._get_media_type_from_content_doc(content)
  File "[path]/blacksheep/server/openapi/v3.py", line 712, in _get_media_type_from_content_doc
    media_type.schema = self.get_schema_by_type(content_doc.type)
  File "[path]/blacksheep/server/openapi/v3.py", line 449, in get_schema_by_type
    schema = self._get_schema_by_type(child_type, type_args)
  File "[path]/blacksheep/server/openapi/v3.py", line 461, in _get_schema_by_type
    if self._can_handle_class_type(object_type):
  File "[path]/blacksheep/server/openapi/v3.py", line 357, in _can_handle_class_type
    any(
  File "[path]/blacksheep/server/openapi/v3.py", line 358, in <genexpr>
    handler.handles_type(object_type)
  File "[path]/blacksheep/server/openapi/v3.py", line 151, in handles_type
    and issubclass(object_type, BaseModel)  # type: ignore
  File "[path]/abc.py", line 123, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class
ERROR:    Application startup failed. Exiting.

If I instead import typing and change…

def pets() -> list[Pet]:

… to…

def pets() -> typing.List[Pet]:

… then the server starts and I can load the docs.

The age field is hidden unless I change int | None to typing.Optional[int] but that’s a separate issue for a different PEP.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
RobertoPrevatocommented, May 15, 2022

@kevlarr thank you for your kind words! 😄 Indeed, I dedicated an incredible amount of hours to these projects. And all in my spare time. As you can see, I also try to be responsive. Anyway, in the next weeks I will be less prolific, I need to restore a bit my work-life balance, take some holiday, and study for one exam.

To give a hint of how much time I dedicated to OSS contributions, one of my first contributions here in GitHub has been a simple tool to convert pictures into Base64 encoded strings: https://github.com/RobertoPrevato/Base64 Over the years, I shared much code. These two also took a lot of time: https://github.com/RobertoPrevato/KingTable, https://github.com/RobertoPrevato/DataEntry - but I don’t maintain projects for Node.js anymore. The projects in Neoteroi are alive and I am willing to maintain them, the others under my first GH account are less lively.

Fixing this particular issue was simple, and I verified that BlackSheep already supports list[T] and Annotated. There is still an issue related to handling of PEP 604 T | None and I’ll try to fix it before releasing the new version to PyPi.

Thank You for offering your help, I welcome contributions in general, in this case I already had an idea to try and it worked immediately.

2reactions
RobertoPrevatocommented, May 10, 2022

Hi @kevlarr, Thanks for your kind words and for opening this issue. I am interested in using these latest features, too, (including Annotated), the only thing that holded me back were limited time and easier handling of support for Python 3.7 and 3.8. But I think it’s high time to add these. During working hours I don’t dedicate time to my open source projects, I’ll look into this most probably in the weekend.

Read more comments on GitHub >

github_iconTop Results From Across the Web

PEP 585 – Type Hinting Generics In Standard Collections
This PEP proposes to enable support for the generics syntax in all standard collections currently available in the typing module. Rationale and ...
Read more >
3.9+ PEP 585 - type hints for builtin types · Issue #4 - GitHub
I'll promptly add a reference to PEP 585 -- Type Hinting Generics In Standard ... list[str] style, we'll (of course) have to support...
Read more >
Python typing tips & tricks - beepb00p
[C] [2020-11-25] Decorated property not supported · Issue 1362 · python/mypy python ... PEP 585 – Type Hinting Generics In Standard Collections |...
Read more >
typing.Any in Python 3.9 and PEP 585 - Stack Overflow
This PEP proposes to enable support for the generics syntax in all standard collections currently available in the typing module.
Read more >
To use Python type hints, and get automatic data validation ...
And by using type hints, you get autocomplete everywhere, type error checks, etc. Your API gets documented with standards: OpenAPI and JSON Schema....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found