Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions drfdocs/api_docs.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
from django.conf import settings
from django.core.urlresolvers import RegexURLResolver, RegexURLPattern
from drfdocs.api_endpoint import ApiEndpoint
from rest_framework.views import APIView


class ApiDocumentation(object):
excluded_apps = ["admin", "drfdocs"]
excluded_endpoints = ["serve"]
root_urlconf = __import__(settings.ROOT_URLCONF)

def __init__(self):
self.view_names = []
self.get_all_view_names(self.root_urlconf.urls.urlpatterns)
self.endpoints = []
root_urlconf = __import__(settings.ROOT_URLCONF)
self.get_all_view_names(root_urlconf.urls.urlpatterns)

def get_all_view_names(self, urlpatterns):
def get_all_view_names(self, urlpatterns, parent_pattern=None):
for pattern in urlpatterns:
if isinstance(pattern, RegexURLResolver) and (pattern.app_name not in self.excluded_apps):
self.get_all_view_names(pattern.url_patterns)
elif isinstance(pattern, RegexURLPattern) and (pattern.callback.__name__ not in self.excluded_endpoints):
self.view_names.append(pattern.callback.__name__)
self.get_all_view_names(urlpatterns=pattern.url_patterns, parent_pattern=pattern)
elif isinstance(pattern, RegexURLPattern) and (pattern.callback.__name__ not in self.excluded_endpoints) and self._is_drf_view(pattern):
api_endpoint = ApiEndpoint(pattern, parent_pattern)
self.endpoints.append(api_endpoint)

def get_views(self):
return self.view_names
def _is_drf_view(self, pattern):
# Should check whether a pattern inherits from DRF's APIView
if (hasattr(pattern.callback, 'cls') and issubclass(pattern.callback.cls, APIView)):
return True
return False

def get_endpoints(self):
return self.endpoints
16 changes: 16 additions & 0 deletions drfdocs/api_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.contrib.admindocs.views import simplify_regex


class ApiEndpoint(object):

def __init__(self, pattern, parent_pattern=None):
self.pattern = pattern
self.name = pattern.name
self.path = self._get_path(parent_pattern)
self.view_name = pattern.callback.__name__

def _get_path(self, parent_pattern):
if parent_pattern:
parent_path = simplify_regex(parent_pattern.regex.pattern)[:-1]
return "{0}{1}".format(parent_path, simplify_regex(self.pattern.regex.pattern))
return simplify_regex(self.pattern.regex.pattern)
92 changes: 92 additions & 0 deletions drfdocs/static/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* @group Misc */

body {
background-color: #FEFEFE;
}

.jumbotron {
margin: 50px 0 40px;
text-align: center;
}

/* @end Misc */


/* @group Endpoint */

.endpoint {
padding: 5px 20px;
margin: 20px 0;
background-color: #ecf0f1;
}

.endpoint .title {
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
}

/* @end Endpoint */


/* @group Footer */

.footer {
text-align: center;
padding: 20px;
margin-bottom: 20px;
}

.footer .links {
padding: 20px 0;
}

.footer .links .fa {
margin: 0 10px;
font-size: 22px;
}

/* @end Footer */


/* @group Github Ribbon - SVG */

.github-corner:hover .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}

@keyframes octocat-wave {
0% {
transform: rotate(0deg);
}

20% {
transform: rotate(-25deg);
}

40% {
transform: rotate(10deg);
}

60% {
transform: rotate(-25deg);
}

80% {
transform: rotate(10deg);
}

100% {
transform: rotate(0deg);
}
}

@media (max-width: 500px) {
.github-corner:hover .octo-arm {
animation: none;
}

.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}
}

/* @end Github Ribbon - SVG */
40 changes: 38 additions & 2 deletions drfdocs/templates/drfdocs/base.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
{% load staticfiles %}

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>DRF Docs</title>

<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<!-- Flatly -->
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.5/flatly/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
<!-- Custom Style -->
<link href="{% static "css/style.css" %}" rel="stylesheet">
</head>

<body>
<h1>Django Rest Frameworks Docs</h1>
<a href="https://github.com/ekonstantinidis/drf-docs/" class="github-corner" target="_blank">
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#18bc9c; color:#fff; position: absolute; top: 0; border: 0; right: 0;">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
</svg>
</a>

<div class="container">
<div class="jumbotron">
<h1>DRF Docs</h1>
<h3>Documentation for Web APIs made with <a href="http://www.django-rest-framework.org/" target="_blank">Django Rest Framework</a>.</h3>
</div>

{% block content %}{% endblock %}
{% block content %}{% endblock %}

<div class="footer">
<div class="links">
<a href="http://www.iamemmanouil.com"><i class="fa fa-link"></i></a>
<a href="http://www.github.com/ekonstantinidis"><i class="fa fa-github"></i></a>
<a href="http://www.twitter.com/iamemmanouil"><i class="fa fa-twitter"></i></a>
</div>
Copyright © 2015 Emmanouil Konstantinidis.
</div>
</div>
</body>
</html>
12 changes: 8 additions & 4 deletions drfdocs/templates/drfdocs/home.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{% extends "drfdocs/base.html" %}

{% block content %}
<ul>
{% for view in views %}
<li>{{ view }}</li>
<h2>API Endpoints</h2>

{% for endpoint in endpoints %}
<div class="endpoint">
<h3 class="title">{{ endpoint.path }}</h3>
<p>View Name: {{ endpoint.view_name }}</p>
<p>URL Name: {{ endpoint.name }}</p>
</div>
{% endfor %}
</ul>
{% endblock %}
2 changes: 1 addition & 1 deletion drfdocs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ class DRFDocsView(TemplateView):
def get_context_data(self, **kwargs):
context = super(DRFDocsView, self).get_context_data(**kwargs)
docs = ApiDocumentation()
context['views'] = docs.get_views()
context['endpoints'] = docs.get_endpoints()
return context