Skip to content

NEFORCEO/djo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Drop-in interactive API docs for Django — Swagger UI, FastAPI-style, with zero decorators and zero extra dependencies.

Publish Package version Monthly downloads

Python Django License

GitHub Stars


Documentation: https://djo.readthedocs.io

Source Code: https://github.com/NEFORCEO/djo


djo turns any Django project into a self-documenting API. Add one line to INSTALLED_APPS and a full Swagger UI shows up at /docs — no urls.py edits, no serializers, no decorators on your views. It walks your project's own urlpatterns and builds the OpenAPI schema from what it finds.

Key features:

  • Zero config — the only thing you touch is INSTALLED_APPS. No urls.py changes, no middleware to wire up by hand.
  • Automatic — paths, path parameters and HTTP methods are all inferred by walking the URLconf and the views it points to. Nothing to decorate, nothing to register.
  • Typed path params<int:pk>, <uuid:token>, <slug:handle> are mapped to real OpenAPI types straight from Django's own path converters.
  • Query paramsrequest.GET.get("page", 1) / request.GET["tag"] style access is picked up automatically, with type and required-ness inferred from how it's read.
  • Smart request bodies — instead of a blank {}, djo reads a handler's source for request.POST.get(...) / request.data[...] style access and pre-fills the example with the fields it actually uses.
  • DRF serializer aware — if a view declares serializer_class, djo reads the real fields straight off it (types, required, read_only/write_only, choices) instead of guessing from source.
  • Auth-awarepermission_classes, authentication_classes and LoginRequiredMixin are detected automatically and surfaced as a Swagger Authorize button (cookie or bearer, depending on what the view uses).
  • Error responses — status codes referenced via status=404, status.HTTP_400_BAD_REQUEST, or raised via Http404/DRF exceptions are added to the schema alongside the success response.
  • Interactive — "Try it out" works against your real endpoints out of the box; the CSRF cookie is forwarded automatically for unsafe methods.
  • No extra dependencies — pure Django. No Pydantic, no DRF required (though it plays nicely with DRF views if you have them).

Requirements

Python 3.10+, Django 5.2+.

Installation

$ pip install djo

Example

Add "djo" to INSTALLED_APPS:

INSTALLED_APPS = [
    ...,
    "djo",
]

That's it. Run your project as usual:

$ python manage.py runserver

Check it

Go to http://127.0.0.1:8000/docs.

You will see the automatic interactive API documentation, generated straight from your urlpatterns:

Expand any route to inspect path parameters and, where djo can infer them, request body fields. Click Try it out to execute the request for real and see the actual response — session auth and CSRF are handled for you.

Configuration

Everything is optional — djo works with sane defaults out of the box. Override title, version, description, or the docs paths themselves via a DJO dict in settings.py:

DJO = {
    "TITLE": "My API",
    "VERSION": "1.0.0",
    "DESCRIPTION": "Internal API for the mobile app.",
    "DOCS_URL": "/docs",
    "OPENAPI_URL": "/openapi.json",
}

How it works

  • DjangoAPIConfig.ready() prepends djo.middleware.DjangoAPIMiddleware to settings.MIDDLEWARE the moment the app is loaded — before Django builds its middleware chain — which is what lets a single INSTALLED_APPS entry serve /docs and /openapi.json with no urls.py changes.
  • The middleware intercepts those two paths ahead of normal URL resolution; every other request passes straight through untouched.
  • djo/generator.py walks get_resolver().url_patterns recursively, resolving path() converters into OpenAPI parameter types and reading each view's docstring for a summary.
  • HTTP methods are inferred from class-based views (Django's View or DRF's APIView/api_view) by checking which handlers they actually implement; plain function-based views default to GET.
  • Request/response bodies prefer a view's declared serializer_class (its fields are read directly, nothing is sent over the network) and fall back to a light, best-effort read of the handler's own source — pattern matching for body/query access, no execution of your views.
  • Auth requirements and error status codes are inferred the same way: straight off class attributes for permissions/authentication, and off the handler's source for raised exceptions and explicit status codes.

Try the demo project

The repo ships a throwaway Django project under test/ wired up with a couple of sample endpoints, just to poke at the Swagger UI:

$ cd test
$ python manage.py runserver

Then open http://127.0.0.1:8000/docs.

About

Static analysis for Django APIs. Generate OpenAPI by reading your code — no decorators, no serializers, no registration

Topics

Resources

License

Stars

12 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages