I'm documenting a django project that use DRF. I already generated a dynamic API schema using openapi and redoc. Very cool solutions
However, I miss the permissions part in all of this
I have a lot of permissions (permission_classes) in the viewsets and some functions. Do you know any solution to include the permission in the schema, or in a documentation in general?
Going further, how do you document permissions in a APIs in general?
I already have an idea: include the permissions in a custom description in the schema, but it's still dirty
Thanks. José.-
PS: Sorry for the poor english
DRF is in the process of deprecating the use of the coreapi package, however currently there is not easy way within that solution to get security schemas to be added to your documentation.
However there is an alternative https://drf-yasg.readthedocs.io/en/stable/ this tool claims to support extracting these values (but I personally have not used it for that yet).
Related
I have a Django project with various REST APIs. The permission to access those APIs are defined throught rest_framework permission classes and django.contrib.auth.models Permission model.
The documentation of those apis is automatically generated using drf_yasg library, i need to find a way to inlcude in the schema generated from drf-yasg the needed permission to access every api without the need to write id down manually. Anyone can give me an hint?
You'll need to take a look at SchemaGenerator and AutoSchema classes.
However, please be very careful when updating or manipulating these as their whole purpose is generating OpenAPI3 compliant schemas.
And whilst it might seem very helpful and useful to have some kinds of permissions inspectors, after all inspects many things, however permissions sadly isn't one of them.
I had a little Google around and I found a github post discussing this very topic, and whilst it's fairly bad practice to link to external sites, I think this can be an exceptional circumstance as the poster of the comment has articulated the answer in a way I don't understand, but does satisfy your question (maybe with some customisations).
https://github.com/axnsan12/drf-yasg/issues/358#issuecomment-545827035
It's been a while since I last used Django for a project and there have been some really great advances in the core project and the ecosystem around it.
One of those is the mature API development libraries like django-rest-framework.
So far I'm loving it. But it seems that all the guides I've found are disabling the Django Admin when using Django Rest Framework.
The reasons I've seen given were essentially "We don't need it for anything" or "We aren't using sessions, which Admin uses, so it won't work, so we're not using it."
"Don't need it" is a valid reason.
But other than that, are there reasons that it's bad practice to keep the Django Admin enabled when the project is primarily used as an API?
For my purposes, I find it convenient to manage user permissions and as a simple way to code admin only functions for dealing with the underlying data.
note: I've considered whether this question is designed to elicit opinions, which is not appropriate on SO. I believe that the answers I'm asking for will be technical or security based reasons with fact or experience based reasoning.
Totally agree.
On my current project, users are getting and setting ALL data via django-rest-framework.
Like you, I find the admin site convenient to manage user permissions, permissions groups, writing emails, sms, mobile applications push and more.
More, all these models are being translated, and translation is set in THE ADMIN SITE !!!
So, if we need a new object with translation, we do not need a new app release (example in pic of a question).
objects translations are readable and clear.
Data is organized nicely with minimal effort.
Admin get cool skins (jet / grappelli etc etc)
Language activation works like a charm in the APIViews.
Following this post (I was looking for a library allowing me to declare Django models on a ldap backend), I have decided to use ldapdb. After having played a while with this library, I figured out that it doesn't reach the level of control I need, and I am therefore looking for other solutions. What I am thinking of now is implementing a Django db backend based on python-ldap.
EDIT
I need this because I am currently implementing a user/group management system on a ldap directory (it requires to be able to manipulate not only users, but different classes of ldap objects as well). So basically, I would like to be able to use (nearly) full Django orm, but with a ldap backend.
Because I love Django (and would be rather motivated in learning the dirty low-level details of db.backends), and because there's already a lot of things implemented in this project, I would like to stick to Django (unless somebody has a very good reason why I shouldn't, and a very good alternative !).
Do some of you have a simpler solution to this problem ?
Do some of you know about an implementation of such a thing (ldap db backend) ?
Do some of you know some good reads to get started on "implementing a Django db backend"?
Are some of you interested in helping with this project ?
You make a lot of bold statements such as "lots of things broken because of the way it is implemented" and "the subclassing is very very far from being complete", would you care to elaborate on them? As the author of django-ldapdb I would welcome your suggestions as to what you would like changed/fixed, that's what the django-ldapdb mailing list is for!
FYI, I took the approach of subclassing the Model class because you will usually want to have just a couple of models using the LDAP backend, not all the models in your application, and django 1.1 did not support multiple databases. Also, LDAP is very different from existing SQL backends:
is not a relational database
it is not "flat", it is a tree-like
the true "primary key" for an entry is the Distinguished Name (DN), which is not an actual field, but a value computed from other fields
fields can be multi-valued
For all these reasons, I have serious doubts as to what can be achieved by writing a true LDAP backend. I think you will always have some LDAP-specific quirks, and subclassing Model allows just that.
Your best bet is probably to write an authentication backend for the application. Here is some documentation about it:
http://docs.djangoproject.com/en/dev/topics/auth/?from=olddocs#writing-an-authentication-backend
And here is an article that explains how to extend the User model to enable you to use this authentication backend seamlessly:
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
Seems like there's no really good solution. And doing everything without Django's ORM is no good solution either.
I'll make new attempt at solving that problem soon, with a django-orm-based solution.
A web app written in Python is planned, Django is a leading contender as framework.
One requirement is CAC access, wihout the need to hand enter username and password. From what I can tell, CAC access is not part of the "batteries" included with Django.
As a monolithic framework (not necessarily a bad attribute) Django has a rep for being high-maintenance once you modify the core. Can I easily add CAC access to a Django site? Can it be easily maintained thereafter?
Or maybe we should consider a different Python framework?
FYI.. interesting presentation on CAC access link
You don't need to modify the core to enable this. Django supports third-party authentication backends and they're fairly easy to write - you just need to support two methods, get_user and authenticate. So your implementation just needs to perform these operations using your CAC interface, and all will work as usual.
See the documentation for details.
Edited after other answers I don't know why people are saying this is difficult in Django. Yes, many parts of Django are difficult to customise. But this is one particular part that is made very easy. I've written several authentication backends in Django and they are not only really simple, but they "just work" with the rest of the framework, including the admin. There isn't any need to modify anything else to get this to work.
I just did this today by subclassing django.contrib.auth.middleware.RemoteUserMiddleware and changed the header property to the one I had set in my apache conf. I just added the django.contrib.auth.backends.RemoteUserBackend and my middleware to the settings and it works perfectly.
Extending contrib.auth is a pain in the neck. It's the single worst thing in django. If you need highly customized auth backend, i would suggest using a different framework.
I have been struggling with choosing a methodology for creating a RESTful API with Django. None of the approaches I've tried seem to be the "silver" bullet. WAPI from http://fi.am is probably the closest to what I would like to accomplish, however I am not sure if it is acceptable in a true RESTful API to have parameters that are resource identifiers be in the querystring instead of in a "clean" URL format. Any suggestions for modifying WAPIs RestBinding.PATTERN to "clean" up the URLs? Another option I've explored is Django-Rest-Interface. However this framework seems to violate one of the most important pieces I need, and that is to include the full resource URL for references to other resources (see http://jacobian.org/writing/rest-worst-practices/ Improper Use of Links). The final option is to use django-multiresponse and basically do it the long way.
Please offer me your best advice, especially people that have dealt with this decision.
For Django, besides tastypie and piston, django-rest-framework is a promising one worth mentioning. I've already migrated one of my projects on it smoothly.
Django REST framework is a lightweight REST framework for Django, that
aims to make it easy to build well-connected, self-describing RESTful
Web APIs.
Quick example:
from django.conf.urls.defaults import patterns, url
from djangorestframework.resources import ModelResource
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from myapp.models import MyModel
class MyResource(ModelResource):
model = MyModel
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
url(r'^(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MyResource)),
)
Take the example from the official site, all above codes provide api, self explained documentation (like soap based webservice) and even sandboxing for testing. Very convenient.
Links:
http://django-rest-framework.org/
I believe the recently released django-piston is now the best solution for creating a proper REST interface in Django. django-piston
Note: django-piston seems to no longer be maintained (see comments below)
django-tastypie is a good way to do it, their slogan: "Creating delicious APIs for Django apps since 2010" is pretty comforting ;)
You could take look at django-dynamicresponse, which is a lightweight framework for adding REST API with JSON to your Django applications.
It requires minimal changes to add API support to existing Django apps, and makes it straight-forward to build-in API from the start in new projects.
Basically, it includes middleware support for parsing JSON into request.POST, in addition to serializing the returned context to JSON or rendering a template/redirecting conditionally based on the request type.
This approach differs from other frameworks (such as django-piston) in that you do not need to create separate handlers for API requests. You can also reuse your existing view logic, and keep using form validation etc. like normal views.
I don't know if this project can be useful for you, but sending a link can hardly hurt. Take a look at django-apibuilder , available from http://opensource.washingtontimes.com/projects/django-apibuilder/ . Perhaps it can be useful?
/Jesper
Have a look at this RestifyDjango.
Somewhat related are Django XML-RPC and JSON-RPC.
https://github.com/RueLaLa/savory-pie
Savory Pie is a REST framework that supports django.
I would suggest you look into Django Rest Framework (DRF), play around with this and see if it suits your requirements. The reason I recommend DRF is because it makes making the API views really simple with the use of GenericAPIView classes, Mixin Classes and Mixed in Generic views. You can easily make use of tried and tested design patterns for making your API endpoints as well as keeping your code base neat and concise. You also DRY when writing your code which is always great. Your API views are literally 2-3 lines long.
You can checkout this tutorial http://programmathics.com/programming/python/django-rest-framework-setup/ that begins from setting up your environment to going through the different ways to make your RESTful API using the django rest framework.
Disclaimer: I am the creator of that website.