Swagger Django [No operations defined in spec] - django

I have been trying to integrate Swagger with Django Application and encounter this error:
No operations defined in spec!
My project structure is
App
views.py
urls.py
..
App2
settings.py
urls.py
..
I am using drf_yasg for my purpose. I have included all details in settings.py and in App2 I have this in urls.py:
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Testing",
default_version='v1',
description="Doc Integration",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="abc#abc.com"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns=[path("admin/", admin.site.urls),
path("", include("app.urls")),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),]
My class views such as (class Att(generic.TemplateView) and methods are declared in views.py under App. I tried methods such as #swagger_auto_schema, #api_view, to display app class and functions in the documentation. But it just returns No operations defined in spec!.
I tried using routers to register the view as well but did not work, even django-rest-swagger fails. Any help is appreciated. Thanks!

I have a project made of Django and I'm new to DRF. I had seen No operations defined in spec! as well while trying drf-yasg which is one of Swagger generators. Hope this way works for you.
I imported ->
from rest_framework.views import APIView
The class in views.py was like
class FeedView(View):
and the functions showed up when I changed the class like
class FeedView(APIView):
I need to deal with #swagger_auto_schema, #api_view to make my API document works with proper parameters.

Related

How to handle namespace API versioning with DRF-YASG

In my project we want to have multiple versions of same api so as to support backward compatibility.
Right now we are using drf-yasg's swagger url at
/api/doc/
While our apis are
/api/vehicle/$
/api/warehouse/
And then each of the app vehicle and ware house have their own endpoints..
Now we want to do versioning as
/api/v1/doc
/api/v2/doc
/api/v1/vehicle
/api/v2/vehicle
/api/v1/warehouse
Goal is that /v1/doc should show v1 of both vehicle and ware house while/v2/doc should show only v2 of vehicle since only vehicle app has some apis with v2....
How to achieve this
I tried adding default version v1 initially in drf settings. But that resulted in no listing being shown in swagger view
I know this is an old question, but I ran into this same issue recently and was able to resolve it like so,
in my root app urls
# myapp/urls.py
...
path('api/v1/', include('api.v1.urls'),
name='v1'),
path('api/v2/', include('api.v2.urls'),
name='v2'),
...
then I created an app specifically to handle all api routes with different versions, inside this app i have a module for each of the versions I have as well as the urls for swagger/redoc like that
api/
__init__.py
|
v1/
|
__init__.py
urls.py
v2/
|
__init__.py
urls.py
In each of the version urls, I added the urls for the specific app apis and the urls for docs like so
# app/v1/urls.py
from django.urls import path, include
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
urlpatterns = [
path('app1/', include('app1.api.v1.urls'), name='app1-api-v1'),
path('app2/', include('app2.api.v1.urls'), name='app2-api-v1'),
path('app3/', include('app3.api.v1.urls'), name='app3-api-v1'),
]
schema_view = get_schema_view(openapi.Info(
title="My API",
default_version='v1',
description="My REST API documentation",
contact=openapi.Contact(email="dev#myapp.com"),
),
public=True, patterns=urlpatterns)
urlpatterns += [
path('swagger/',
schema_view.with_ui('swagger', cache_timeout=0),
name='schema-swagger-ui-v1'),
path('redoc/',
schema_view.with_ui('redoc', cache_timeout=0),
name='schema-redoc-v1'),
]
Did the same for api/v2/urls.py with the corresponding changes to the urls and naming. This way I had 2 separate urls for each of version of the api docs.
Hope this helps!

Django DRF Swagger: In urls.py SimpleRouter / DefaultRouter are not auto discovered by swagger docs

Django DRF Swagger docs are not showing the ModelViewSets API endpoints registered as ROUTERS (not urlpattern).
In the example below standard docs (rest_framework.documentation) are showing/documenting this "follow_up" API and swagger docs are not, total skip nothing is showing.
For urlpatterns all is good, and below code for 'this_is_showing' is being nicely documented:
from urls.py file
from rest_framework.documentation import include_docs_urls
from rest_framework.routers import SimpleRouter, DefaultRouter
from rest_framework_swagger.views import get_swagger_view
from . import views
schema_view = get_swagger_view(title=MY APP API')
router = DefaultRouter()
router.register("follow_up", views.FollowUpViewSet)
urlpatterns = [
url(r'^this_is_showing/$', views.SomeView.as_view(), name='view'),
url(r'docs/', include_docs_urls(
title='API Docs', public=True)),
url(r'^swag/', schema_view),
]
What am I missing?
django-rest-swagger==2.2.0,
djangorestframework==3.11.0
EDIT 1
django-rest-swagger Package not maintained anymore!
Moved to drf_yasg: great tool with swagger and reDocs inside.
The DRF docs suggest that if you want to get the auto-generated API list view you need to use the DefaultRouter. I wonder if the SimpleRouter lacks the introspective mechanism (or other hooks) that django-rest-swagger uses to get its information.
https://www.django-rest-framework.org/api-guide/routers/#defaultrouter
EDIT 1
The DRF-swagger docs say that their example uses the DRF example: https://django-rest-swagger.readthedocs.io/en/latest/
The DRF example uses the default router: https://github.com/encode/rest-framework-tutorial/blob/master/snippets/urls.py
EDIT 2
I believe you'll also need to include the router somewhere in your URL patterns. If you look here: https://github.com/encode/rest-framework-tutorial/blob/master/snippets/urls.py
Not only is the DefaultRouter being used, but the router that's registered is included in the URL patters:
from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter
from snippets import views
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)
# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browsable API.
urlpatterns = [
url(r'^', include(router.urls))
]

How can i generate static api documentation for django rest APIs?

I went through the documentation and tried to use swagger and coreapi, but both are interactive, I want the same api documentation without interaction. Is it possible?
Here you can see API documentation
https://editor.swagger.io/
but its interacting with the respective api. I want same UI and without interaction.
Oh it is really easy.
First install: django-rest-swagger==2.1.2
Add to settings: 'rest_framework_swagger'
Next make urls.py changes:
from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework import permissions
from rest_framework.renderers import CoreJSONRenderer
from rest_framework.schemas import get_schema_view
schema_view = get_schema_view(
title='Swagger My - API documentation',
public=True,
renderer_classes=[CoreJSONRenderer, OpenAPIRenderer, SwaggerUIRenderer],
authentication_classes=[JSONWebTokenAuthentication],
permission_classes=[permissions.AllowAny]
)
urlpatterns = [
# Swagger
path('docs/', schema_view),
]
And you choose renderer_classes=[CoreJSONRenderer, OpenAPIRenderer, SwaggerUIRenderer].
This is example with JWT JSONWebTokenAuthentication for auth.

Django REST API Generics displaying improperly

Currently using a REST API and the generic views CreateUpdateDestroy, and my admin display GUI looks like this :
All the sources online that I've followed, tutorials etc get a generic view which looks much nicer.
Here is my views.py:
from rest_framework import generics
from models import Results
from serializers import ResulutsSerializer
class ResultsList(generics.ListAPIView):
queryset = Results.objects.all()
serializer_class = ResultsSerializer
class ResultsDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Results.objects.all()
serializer_class = ResultsSerializer
and urls.py:
from django.urls import path
from main import views
urlpatterns = [
path('results/', views.ResultsList.as_view()),
path('<int:pk>/', views.ResultsDetails.as_view())
]
what am I doing wrong?
It looks like you need to collect your app assets:
$ python manage.py collectstatic
# You can provide option: --settings=<your-settings-file> if you're using custom settings which is not default in manage.py
You will need to configure staticfiles settings in your Django settings module if not already configured – e.g. settings.py. Please follow documentation at:
https://docs.djangoproject.com/en/2.0/howto/static-files/
https://docs.djangoproject.com/en/2.0/ref/contrib/staticfiles/
If you are developing locally:
You should set DEBUG=True in your Django Settings Module (i.e. normally settings.py)

Django Rest 'api-docs' is not a registered namespace

I'm setting the docs for my api and when I ask for (http://localhost:8000/api/v0/docs/) The app show me this error:
NoReverseMatch at /api/v0/docs/
'api-docs' is not a registered namespace
when try to do this
<script src="{% url **'api-docs:schema-js'** %}"></script>
this is my urls.py file:
from django.contrib import admin
from django.conf.urls import url, include
from django.contrib.auth.models import User
from . import views
from rest_framework import routers, serializers, viewsets
from rest_framework.documentation import include_docs_urls
# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'goals', views.GoalViewSet)
urlpatterns = [
url(r'^goals/$', include(router.urls)),
url(r'^docs/', include_docs_urls(title='My API title')),
]
I added the namespace to include_docs_urls but it doesn't work. (I have installed coreapi, pygments and markdown).
Beforehand thanks for helping me.
You should move your docs url pattern into your main urls.py file. This is still a problem in DRF, there is also an issue opened on the official GitHub source: https://github.com/encode/django-rest-framework/issues/4984
The official developer of Django REST Framework, Tom Christie, says:
It's important enough that I'd like to see it highly prioritized, but there's a lot of other things going on at the moment too. Even after we release 3.6.3, there's still also all the work towards 3.7.0's realtime integration.
So your docs pattern should not have any prefixes (like api/v0/).
In conclusion, change your main urls.py:
url(r'^docs/', include_docs_urls(title='API Title'))