Rework API documentation to cover all supported calls.

We now generate our API documentation page based off of JSON source.

(imported from commit 0e8a91ef4278684dbcad89cad39a1977672245fc)
This commit is contained in:
Luke Faraone
2013-04-09 13:20:46 -07:00
parent 4601db82e5
commit ea7965d9bb
7 changed files with 162 additions and 76 deletions

View File

@@ -243,6 +243,10 @@ PIPELINE_JS = {
'source_filenames': ('js/signup.js',),
'output_filename': 'min/signup.js'
},
'api': {
'source_filenames': ('js/api.js',),
'output_filename': 'min/api.js'
},
'app_debug': {
'source_filenames': ('js/debug.js',),
'output_filename': 'min/app_debug.js'

View File

@@ -58,7 +58,7 @@ urlpatterns = patterns('',
url(r'^new-user$', TemplateView.as_view(template_name='zephyr/new-user.html')),
# API and integrations documentation
url(r'^api$', TemplateView.as_view(template_name='zephyr/api.html')),
url(r'^api$', 'zephyr.views.api_docs'),
url(r'^integrations$', TemplateView.as_view(template_name='zephyr/integrations.html')),
url(r'^zephyr$', TemplateView.as_view(template_name='zephyr/zephyr.html')),
url(r'^apps$', TemplateView.as_view(template_name='zephyr/apps.html')),

View File

@@ -2,7 +2,16 @@
{# API information page #}
{% load compressed %}
{% block customhead %}
{{ block.super }}
{% compressed_js 'api' %}
{% endblock %}
{% block portico_content %}
<div class="row-fluid">
<div class="span8">
<h2>We hear you like APIs...</h2>
@@ -26,84 +35,50 @@ email=YOUR_EMAIL_ADDRESS</pre></div>
<h3>Usage examples</h3>
<ul class="nav nav-tabs" id="api-example-tabs">
<li class="active"><a href="#curl" data-toggle="tab">curl</a></li>
<li><a href="#python" data-toggle="tab">Python</a></li>
<li><a href="#commandline" data-toggle="tab">humbug-send</a></li>
<li class="active"><a href="#curl" data-toggle="tab" data-class="curl">curl</a></li>
<li><a href="#python" data-toggle="tab" data-class="python">Python</a></li>
<li><a href="#commandline" data-toggle="tab" data-class="commandline">humbug-send</a></li>
</ul>
<div class="tab-content">
{% autoescape off %}
<div class="tab-pane active" id="curl">
<p>No download required!</p>
{% comment %}
These code snippets are generated using our very own Humbug tool, by
sending them to myself in a code block, and then using the inspector
to pull out the resulting HTML :)
{% endcomment %}
<h4>Stream message</h4>
<div class="codehilite"><pre>curl https://humbughq.com/api/v1/messages <span class="se">\</span>
-u YOUR_EMAIL:YOUR_API_KEY <span class="se">\</span>
-d <span class="s2">"type=stream"</span> <span class="se">\</span>
-d <span class="s2">"to=Denmark"</span> <span class="se">\</span>
-d <span class="s2">"subject=Castle"</span> <span class="se">\</span>
-d <span class="s2">"content=Something is rotten in the state of Denmark."</span>
</pre></div>
<h4>Private message</h4>
<div class="codehilite"><pre>curl https://humbughq.com/api/v1/messages <span class="se">\</span>
-u YOUR_EMAIL:YOUR_API_KEY <span class="se">\</span>
-d <span class="s2">"type=private"</span> <span class="se">\</span>
-d <span class="s2">"to=wdaher@humbughq.com"</span> <span class="se">\</span>
-d <span class="s2">"content=I come not, friends, to steal away your hearts."</span>
</pre></div>
</div>
<div class="tab-pane" id="python">
<div class="codehilite"><pre><span class="c">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">humbug</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">humbug</span><span class="o">.</span><span class="n">Client</span><span class="p">(</span>
<span class="c"> # These options are only necessary if you didn't make a .humbugrc</span>
<span class="c"> # api_key=YOUR_API_KEY,</span>
<span class="c"> # email=YOUR_EMAIL_ADDRESS,</span>
<span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">stream_message</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"type"</span><span class="p">:</span> <span class="s">"stream"</span><span class="p">,</span>
<span class="s">"to"</span><span class="p">:</span> <span class="s">"Denmark"</span><span class="p">,</span>
<span class="s">"subject"</span><span class="p">:</span> <span class="s">"Castle"</span><span class="p">,</span>
<span class="s">"content"</span><span class="p">:</span> <span class="s">"Something is rotten in the state of Denmark."</span>
<span class="p">}</span>
<span class="n">private_message</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"type"</span><span class="p">:</span> <span class="s">"private"</span><span class="p">,</span>
<span class="s">"to"</span><span class="p">:</span> <span class="s">"wdaher@humbughq.com"</span><span class="p">,</span>
<span class="s">"content"</span><span class="p">:</span> <span class="s">"I come not, friends, to steal away your hearts."</span>
<span class="p">}</span>
<span class="k">print</span> <span class="n">client</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">stream_message</span><span class="p">)</span>
<span class="k">print</span> <span class="n">client</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">private_message</span><span class="p">)</span>
</pre></div>
</div>
<div class="tab-pane" id="commandline">
<p>You can use <code>humbug-send</code> (found in <code>bin/</code> in the tarball) to easily send Humbugs from the command-line, providing the message to be sent on STDIN.
<h4>Stream message</h4>
<div class="codehilite"><pre>humbug-send --stream Denmark --subject Castle</span></pre></div>
<h4>Private message</h4>
<div class="codehilite"><pre>humbug-send wdaher@humbughq.com</span>
</pre></div>
<h4>Passing in the message on the command-line</h4>
<p>If you'd like, you can also provide the message on the command-line with the <code>-m</code> flag, as follows:</p>
<div class="codehilite"><pre>humbug-send --stream Denmark --subject Castle -m <span class="s2">"Something is rotten in the state of Denmark."</span>
</pre></div>
{% for blurb in content %}
<div class="api-block" id="{{ blurb.call }}">
<h2 class="call">{{ blurb.call }}</h2>
<div class="endpoint"><code>{{ blurb.endpoint }}</code></div>
<div class="api-details">
<h3>Arguments</h3>
<dl class="dl-horizontal arguments">
{% for argument in blurb.arguments %}
<dt><code>{{ argument.0 }}</code></dt>
<dd>{{ argument.1 }}</dd>
{% endfor %}
</dl>
<h3>Return values</h3>
<dl class="dl-horizontal returns">
{% for return in blurb.returns %}
<dt><code>{{ return.0 }}</code></dt>
<dd>{{ return.1 }}</dd>
</li>
{% endfor %}
</dl>
{%if blurb.example_request %}
<h3>Example request</h3>
{% for lang, req in blurb.example_request.items %}
<div class="example_request {{ lang }}">
{{ req }}
</div>
{% endfor %}{% endif %}
{%if blurb.example_response %}
<h3>Example response</h3>
<div class="example_response">
{{ blurb.example_response }}
</div>
{% endif %}
</div>
</div>
{% endfor %}
{% endautoescape %}
</div>
</div>

View File

@@ -0,0 +1,62 @@
[
{
"endpoint": "GET /v1/messages/latest",
"example_response": "<div class=\"codehilite\"><pre><span class=\"p\">{</span> <span class=\"s2\">\"messages\"</span> <span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"p\">{</span> <span class=\"s2\">\"client\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"website\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"content\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"hi\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"content_type\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"text/x-markdown\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"display_recipient\"</span> <span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"p\">{</span> <span class=\"s2\">\"email\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"wdaher@humbughq.com\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"full_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"Waseem Daher\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"short_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"wdaher\"</span>\n <span class=\"p\">},</span>\n <span class=\"p\">{</span> <span class=\"s2\">\"email\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"othello@humbughq.com\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"full_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"Othello, Moor of Venice\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"short_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"othello\"</span>\n <span class=\"p\">}</span>\n <span class=\"p\">],</span>\n <span class=\"s2\">\"gravatar_hash\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"948fcdfa93dd8986106032f1bad7f2c8\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"id\"</span> <span class=\"o\">:</span> <span class=\"mi\">400</span><span class=\"p\">,</span>\n <span class=\"s2\">\"recipient_id\"</span> <span class=\"o\">:</span> <span class=\"mi\">101</span><span class=\"p\">,</span>\n <span class=\"s2\">\"sender_email\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"othello@humbughq.com\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"sender_full_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"Othello, Moor of Venice\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"sender_short_name\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"othello\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"subject\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"timestamp\"</span> <span class=\"o\">:</span> <span class=\"mi\">1365532669</span><span class=\"p\">,</span>\n <span class=\"s2\">\"type\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"private\"</span>\n <span class=\"p\">}</span> <span class=\"p\">],</span>\n <span class=\"s2\">\"msg\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"result\"</span> <span class=\"o\">:</span> <span class=\"s2\">\"success\"</span><span class=\"p\">,</span>\n <span class=\"s2\">\"update_types\"</span> <span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"s2\">\"new_messages\"</span> <span class=\"p\">]</span>\n<span class=\"p\">}</span>\n</pre></div>",
"returns": [
[
"messages",
"an array (possibly zero-length if dont_block is set) of messages with IDs newer than `last_message`"
]
],
"call": "Poll for new messages",
"arguments": [
[
"last",
"(optional) Indicates the highest message ID that the client is not interested in. They are implicitly interested in all messages with ids higher than this. If the `last` argument is not present, the server assumes a value equal to the highest existing message ID."
],
[
"dont_block",
"set to \u201ctrue\u201d if the client is requesting a nonblocking reply"
]
],
"example_request": {
"python": "<div class=\"codehilite\"><pre><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get_messages<span class=\"p\">()</span>\n</span></pre></div>",
"curl": "<div class=\"codehilite\"><pre>curl -G http://api.humbughq.com/v1/messages <span class=\"se\">\\</span>\n -u you@example.com:a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5 <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"last=102345\"</span>\n</pre></div>",
"commandline": "This call is not supported via the command line."
}
},
{
"endpoint": "POST /v1/messages",
"example_response": "<div class=\"codehilite\"><pre><span class=\"p\">{</span><span class=\"s2\">\"id\"</span><span class=\"o\">:</span> <span class=\"mi\">102346</span><span class=\"p\">}</span>\n</pre></div>",
"returns": [
[
"id",
"The ID of the newly created message."
]
],
"call": "Send a message",
"arguments": [
[
"type",
"One of {private, stream}"
],
[
"content",
"The content of the message"
],
[
"to",
"In the case of a stream message, a string identifying the stream. In the case of a private message, a JSON-encoded list containing the usernames of the recipients."
],
[
"subject",
"The subject for the message (Only required if type is \u201cstream\u201d)"
]
],
"example_request": {
"python": "<div class=\"codehilite\"><pre>\n<span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">send_message</span><span class=\"p\">({</span>\n <span class=\"s\">\"type\"</span><span class=\"p\">:</span> <span class=\"s\">\"private\"</span><span class=\"p\">,</span>\n <span class=\"s\">\"to\"</span><span class=\"p\">:</span> <span class=\"s\">\"wdaher@humbughq.com\"</span><span class=\"p\">,</span>\n <span class=\"s\">\"content\"</span><span class=\"p\">:</span> <span class=\"s\">\"I come not, friends, to steal away your hearts.\"</span>\n<span class=\"p\">}</span>)</span>\n<span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">send_message</span><span class=\"p\">(</span><span class=\"n\"><span class=\"p\">{</span>\n <span class=\"s\">\"type\"</span><span class=\"p\">:</span> <span class=\"s\">\"stream\"</span><span class=\"p\">,</span>\n <span class=\"s\">\"to\"</span><span class=\"p\">:</span> <span class=\"s\">\"Denmark\"</span><span class=\"p\">,</span>\n <span class=\"s\">\"subject\"</span><span class=\"p\">:</span> <span class=\"s\">\"Castle\"</span><span class=\"p\">,</span>\n <span class=\"s\">\"content\"</span><span class=\"p\">:</span> <span class=\"s\">\"Something is rotten in the state of Denmark.\"</span>\n<span class=\"p\">}</span></span><span class=\"p\">)</span>\n</pre></div>\n",
"curl": "<h5>Stream message</h5>\n<div class=\"codehilite\"><pre>curl https://humbughq.com/api/v1/messages <span class=\"se\">\\</span>\n -u YOUR_EMAIL:YOUR_API_KEY <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"type=stream\"</span> <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"to=Denmark\"</span> <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"subject=Castle\"</span> <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"content=Something is rotten in the state of Denmark.\"</span>\n</pre></div>\n<h5>Private message</h5>\n<div class=\"codehilite\"><pre>curl https://humbughq.com/api/v1/messages <span class=\"se\">\\</span>\n -u YOUR_EMAIL:YOUR_API_KEY <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"type=private\"</span> <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"to=wdaher@humbughq.com\"</span> <span class=\"se\">\\</span>\n -d <span class=\"s2\">\"content=I come not, friends, to steal away your hearts.\"</span>\n</pre></div>",
"commandline": "<h4>Stream message</h4>\n<div class=\"codehilite\"><pre>humbug-send --stream Denmark --subject Castle</pre></div>\n<h4>Private message</h4>\n<div class=\"codehilite\"><pre>humbug-send wdaher@humbughq.com\n</pre></div>\n<h4>Passing in the message on the command-line</h4>\n<p>If you'd like, you can also provide the message on the command-line with the <code>-m</code> flag, as follows:</p>\n<div class=\"codehilite\"><pre>humbug-send --stream Denmark --subject Castle -m <span class=\"s2\">\"Something is rotten in the state of Denmark.\"</span>\n</pre></div>"
}
}
]

6
zephyr/static/js/api.js Normal file
View File

@@ -0,0 +1,6 @@
$(function () {
$('a[data-toggle="tab"]').on('shown', function (e) {
$("." + $(e.target).data("class")).show();
$("." + $(e.relatedTarget).data("class")).hide();
});
});

View File

@@ -113,3 +113,27 @@ img.screenshot{
/* Same width as a Bootstrap default text <input> with padding */
width: 220px;
}
.def:before {
content:" - "
}
.api-details {
margin-left: 2em;
}
.api-details ul {
list-style-type:none
}
.api-details dd {
margin-bottom: 1em;
}
.python {
display: none;
}
.commandline {
display: none;
}

View File

@@ -277,6 +277,21 @@ def accounts_accept_terms(request):
{ 'form': form, 'company_name': company_name, 'email': email },
context_instance=RequestContext(request))
def api_docs(request):
raw_calls = open('templates/zephyr/api_content.json', 'r').read()
calls = simplejson.loads(raw_calls)
langs = set()
for call in calls:
for example_type in ('request', 'response'):
for lang in call.get('example_' + example_type, []):
langs.add(lang)
return render_to_response(
'zephyr/api.html', {
'content': calls,
'langs': langs,
},
context_instance=RequestContext(request))
@authenticated_json_post_view
@has_request_variables
def json_invite_users(request, user_profile, invitee_emails=POST):