Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

drf-yasg provides wrong paths to URIs

In my application I need to have multiple Swagger pages with grouped endpoints for multiple clients.

One of my clients (paths) supplies mobile app API, another supplies web client API. URL patterns are kept in 2 different urls.py accordingly.

I'm using drf-yasg to generate schema for my API.

To generate swagger specification for those I'm initializing 2 separate schema_views for each urls.py file like this:

from api_mobile.urls import urlpatterns as mobile_patterns
from api_web.urls import urlpatterns as web_patterns

mobile_schema_view = get_schema_view(
openapi.Info(
    title="Mobile API",
    default_version='v3',
),
public=True,
permission_classes=(permissions.AllowAny,),
patterns=mobile_patterns,
)

web_schema_view = get_schema_view(
    openapi.Info(
        title="Web API",
        default_version='v1',
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
    patterns=web_patterns,
)

urlpatterns = [
    path(
        'api/mobile/docs',
        mobile_schema_view.with_ui('swagger', cache_timeout=0),
        name='mobile-schema-ui'
    ),
    path(
        'api/web/docs',
        web_schema_view.with_ui('swagger', cache_timeout=0),
        name='web-schema-ui'
    ),

    path('api/mobile/v3/', include('api_mobile.urls'), name='mobile_urls'),
    path('api/web/v1/', include('api_web.urls'), name='web_urls'),
    ...
]

Where mobile_patterns and web_patterns are just a list of url patterns.

If I open http://localhost:8000/api/mobile/docs or http://localhost:8000/api/web/docs I do see correctly generated schema for both lists of patterns, yet if I try to do a request directly from swagger specification page all endpoints return 404 error – they all try to do a request to non-existing url pattern without providing full path to endpoint.

So if I do a request to any view from mobile endpoints swagger tries to do a request at

http://localhost:8000/some_mobile_url/ instead of http://localhost:8000/api/mobile/v3/some_mobile_url/

And situation is the same for another schema, swagger wrongly requests http://localhost:8000/some_web_url/ instead of using full path http://localhost:8000/api/web/v3/some_web_url/

Obviously being able to test API directly through swagger is very important so specification itself is not enough in my case.

Is this an issue in me misconfiguring swagger itlesf or should I be somehow providing path to swagger so it prepends full path to each url accordingly?

like image 507
Stan Redoute Avatar asked Oct 14 '19 21:10

Stan Redoute


1 Answers

This is working fine for us:

api_schema.py

from django.conf.urls import include, url
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

from books.api.v1.urls import urlpatterns as api_v1


API_DESCRIPTION = openapi.Info(
    ...
)

schema_view = get_schema_view(
    info=...,
    ...
    url='https://oursite.company.io/',
    patterns=[
        url('api/v1/', include(api_v1)),
    ],
)

books.api.v1.urls.py

from django.conf.urls import include, url

urlpatterns = [
    url(r'^books', ...),
    ...
]

urls.py

from ...api_schema import schema_view

...
url(r'^api/v1/', include(api_v1)),
url(r'^api/schema(?P<format>\.json|\.yaml)$',
        schema_view.without_ui(cache_timeout=0),
        name='api_schema_v1'),
...
like image 132
Manu Avatar answered Nov 17 '22 02:11

Manu