Skip to content

Check if coreapi is installed before using uritemplate or raise exception #6814

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

Conversation

carlosgoce
Copy link

Hello,

this just adds extra information for the developer when coreapi is not installed.

I was struggling because I was receiving the exception

`uritemplate` must be installed for OpenAPI schema support.

I installed it and tested that import uritemplate was working.
Reading the source code I noticed that even if you have uritemplate is not going to work without coreapi.

@carltongibson
Copy link
Collaborator

This doesn’t seem right. Why do you think that coreapi needs to be installed here? (For the coreapi module generator yes, but...)

@rpkilby
Copy link
Member

rpkilby commented Jul 17, 2019

I'm not that familiar with schema support, but maybe this is related to the coreapi/openapi renderer?

@carltongibson
Copy link
Collaborator

OK, so we need a stacktrace, because there's the OLD OpenAPIRenderer (for CoreAPI to OpenAPI rendering) and then the NEW straight-to-open API flow, which really shouldn't need coreapi installed.

Without actual error details it's hard to see if there's an issue or not...

@tomchristie
Copy link
Member

Going to close this one off in it's current state.
If we do need an extra check somewhere, then it oughta be wherever we're actually using coreapi.
Same as @carltongibson - let's start by seeing a stack trace, then we can advise on if and where any extra checks might be needed.

@carlosgoce
Copy link
Author

carlosgoce commented Jul 17, 2019

Hello!

Yes, my apologies. I should have included more information.

With a fresh django (2.2.3) and django rest framework installation (3.10.0)

I was following the guide at: https://www.django-rest-framework.org/api-guide/schemas/
and added the new URL:

path('openapi', get_schema_view(
        title="Your Project",
        description="API for all things …"
 ), name='openapi-schema'),

Trying to access that URL throws the following exception

[17/Jul/2019 11:22:14] "GET /api/openapi/ HTTP/1.1" 404 12563
Internal Server Error: /api/openapi
Traceback (most recent call last):
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 497, in dispatch
    response = self.handle_exception(exc)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/views.py", line 48, in handle_exception
    return super().handle_exception(exc)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 457, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 468, in raise_uncaught_exception
    raise exc
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 494, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/views.py", line 37, in get
    schema = self.schema_generator.get_schema(request, self.public)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/openapi.py", line 62, in get_schema
    paths = self.get_paths(None if public else request)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/openapi.py", line 49, in get_paths
    operation = view.schema.get_operation(path, method)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/openapi.py", line 94, in get_operation
    parameters += self._get_path_parameters(path, method)
  File "/Users/Carlos/project/.venv/lib/python3.7/site-packages/rest_framework/schemas/openapi.py", line 148, in _get_path_parameters
    assert uritemplate, '`uritemplate` must be installed for OpenAPI schema support.'
AssertionError: `uritemplate` must be installed for OpenAPI schema support.

Then if I install uritemplate as the assert is telling me, I keep getting the same exact exception.

Reading the source code I found that the problem is here:

# .venv/lib/python3.7/site-packages/rest_framework/compat.py

# coreapi is optional (Note that uritemplate is a dependency of coreapi) <- line 96
try:
    import coreapi
    import uritemplate
except ImportError:
    coreapi = None
    uritemplate = None

So if coreapi is not installed, uritemplate is going to be None, so at this point, is required.
Maybe the change should be made here and split this try in two separate trys.

I thought that coreapi/uritemplate were necessary for openapi thats why I added the new assert.

@tomchristie
Copy link
Member

Ah gotcha.

What we need here is...

try:
    import coreapi
except ImportError:
    coreapi = None

try:
    import uritemplate
except ImportError:
    uritemplate = None

It was fine before because both coreapi and uritemplate were required. Now only uritemplate is, so we'll need to switch that compat code around a bit.

@carlosgoce
Copy link
Author

Yes that is the fastest solution.

If you want I can make a new pull request or I leave it in your hands, as you prefer.
I tried updating this one but it seems it is not possible once the PR is closed.

@tomchristie tomchristie mentioned this pull request Jul 17, 2019
@carltongibson
Copy link
Collaborator

Good follow up @carlosgoce Thanks!

daleione added a commit to daleione/django-rest-framework that referenced this pull request Feb 15, 2020
daleione added a commit to daleione/django-rest-framework that referenced this pull request Feb 18, 2020
tomchristie pushed a commit that referenced this pull request Feb 19, 2020
pchiquet pushed a commit to pchiquet/django-rest-framework that referenced this pull request Nov 17, 2020
sigvef pushed a commit to sigvef/django-rest-framework that referenced this pull request Dec 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants