{% extends "base.html" %}
{% load static %}
{% load wger_extras %}


{% block title %}REST API{% endblock %}

{% block content %}
<p>wger Workout Manager provides a full REST API to all database
objects: <a href="/api/v2/" rel="nofollow">https://wger.de/api/v2/</a></p>


<h3>Authentication</h3>
<p>Public endpoints, such as the list of exercises or the
ingredients can be accessed without authentication. For <strong>user owned
objects such as workouts, you need to generate an API KEY</strong> and pass
it in the header, see the link on the sidebar for details.</p>
<p>You should always use HTTPS if possible when communicating with the server.</p>


<div class="row">
    <div class="col-xs-6">
        <h4>Public endpoints</h4>
        <ul>
            <li>daysofweek</li>
            <li>equipment</li>
            <li>exercise</li>
            <li>exerciseinfo</li>
            <li>exercisecategory</li>
            <li>exercisecomment</li>
            <li>exerciseimage</li>
            <li>ingredient</li>
            <li>ingredienttoweightunit</li>
            <li>language</li>
            <li>license</li>
            <li>muscle</li>
            <li>weightunit</li>
            <li>setting-repetitionunit</li>
            <li>setting-weightunit</li>
        </ul>
    </div>
    <div class="col-xs-6">
        <h4>Private endpoints</h4>
        <ul>
            <li>day</li>
            <li>meal</li>
            <li>mealitem</li>
            <li>nutritionplan</li>
            <li>schedule</li>
            <li>schedulestep</li>
            <li>set</li>
            <li>setting</li>
            <li>userprofile</li>
            <li>weightentry</li>
            <li>workout</li>
            <li>workoutlog</li>
        </ul>
    </div>
</div>


<h3>Format negotiation</h3>
<p>
    At the moment only JSON and the browsable HTML view are supported, but other
    formats such as YAML or XML could be theoretically be added, should the
    need arise. Because of this, for the majority of REST clients it will not be
    necessary to explicitly set the format, but you have the following options:
</p>
<ul>
    <li>Set the <strong>Accept</strong> header:
        <ul>
            <li><code>application/json</code></li>
            <li>
                <code>application/json; indent=4</code> - useful for debugging, will
                indent the result
            </li>
            <li>
                <code>text/html</code> - browsable HTML view
            </li>
        </ul>
    </li>
    <li>
        Set the format <strong>directly in the URL</strong>:
        <ul>
            <li>
                <code>/api/v2/&lt;endpoint&gt;.json/</code>
            </li>
            <li>
                <code>/api/v2/&lt;endpoint&gt;/?format=json</code>
            </li>
            <li>
                <code>/api/v2/&lt;endpoint&gt;.api/</code> - browsable HTML view
            </li>
        </ul>
    </li>
</ul>


<h3>Fetching Data</h3>

<pre>
# Api-Wide
/api/v2/

# Object detail view
/api/v2/&lt;endpoint&gt;/&lt;id&gt;/
</pre>

<p>
    This lists out all the different resources available. If you visit the
    link with a browser, you'll get a human-browsable HTML version of the
    contents. If you are logged in, you can use the built in form to try
    different requests (POST, PATCH, etc.)
</p>

<p>
    You can do a <code>OPTIONS /api/v2/&lt;endpoint&gt;/</code> to get more
    information on the endpoint such as the accepted formats. It also outputs
    a listing with all the resource's fields, their type (date, int, etc.) and
    a short description. This is more easier done when using the browseable
    version.
</p>



<h3>Miscellaneous operations</h3>
<h4>Ordering</h4>
<p>
    Simply use <code>?ordering=&lt;fieldname&gt;</code> to order by that field.
    You can also specify more than one field name, just give it a list separated
    by commas <code>?ordering=&lt;field1&gt;,&lt;field2&gt;</code>. To reverse
    the order use like in django a <code>-</code> in front of the field.
</p>



<h4>Pagination</h4>
<p>
    By default all results are paginated by 20 elements per page. If you want to
    change this value, add a <code>?limit=&lt;xxx&gt;</code> to your query.
    You will find in the answer JSON the <code>next</code> and <code>previous</code>
    keywords with links to the next or previous result pages.
</p>



<h4>Filtering resources</h4>
<p>
    You can easily filter all resources by specifying the filter queries in the
    URL: <code>?&lt;fieldname&gt;=&lt;value&gt;</code>, combinations are possible,
    the filters will be AND-joined: <code>?&lt;f1&gt;=&lt;v1&gt;&amp;&lt;f2&gt;=&lt;v2&gt;</code>.
    Please note that for boolean values you must pass 'False' or 'True' other
    values, e.g. 1, 0, false, etc. will be ignored. Like with not filtered queries,
    your objects will be available under the 'results' key.
</p>
<p>
    Note that it is not currently possible to specify more than one value, e.g.
    category 1 or 2.
</p>
<p>Some examples:</p>

<ul>
    <li>All exercises in German: <code>api/v2/exercise/?language=1</code></li>
    <li>'Main' image for all exercises: <code>api/v2/exerciseimage/?is_main=True</code></li>
    <li>Exercises that train the biceps with barbells:  <code>api/v2/exercise/?muscles=1&equipment=3</code>
    </li>
</ul>

<h4>Submitting exercise images</h4>
<p>
    If you want to submit exercise pictures, remember that you have to set the
    correct header <code>Content-Type: multipart/form-data</code>, otherwise the
    file upload won't work.
</p>

<h4>Exercises</h4>
<p>
    When accessing exercises, consider that by default <em>all</em> exercises are
    returned, including those submitted by users but not yed approved. You will
    very probably want to add a <code>&status=2</code> to your URL to only get the
    ones already added to the database.
</p>
<p>
    Also note that, at the moment, to actually retrieve all the details for an exercise
    you will need to fire up different queries for the images, comments, etc.
</p>


<h3>Special endpoints</h3>
<p>
    The following endpoints provide additional information, comfort functions, etc.:
</p>
<div style="margin-top: 1em;">
    <code>api/v2/workout/&lt;id&gt;/canonical_representation/</code>
</div>
<div class="row">
    <div class="col-md-offset-1 col-md-10">
        This is a complete representation of a workout, including all objects
        like workout days, exercises, etc. This form used by the django application
        to render workouts or perform other operations. The data is cached so,
        accessing or using is faster than performing many different requests.
    </div>
</div>


<div style="margin-top: 1em;">
    <code>api/v2/exerciseimage/&lt;id&gt;/thumbnails/</code>
</div>
<div class="row">
    <div class="col-md-offset-1 col-md-10">
        Returns a list of available thumbnails for this image. The 'settings' key
        refers to the settings used by the thumbnailing application to generate
        that image. The special key 'original' is simply a downloadable link to
        the original image used.
    </div>
</div>


<div style="margin-top: 1em;">
    <code>api/v2/exerciseiinfo/&lt;id&gt;/</code>
</div>
<div class="row">
    <div class="col-md-offset-1 col-md-10">
        A convenience function that returns all the information about an exercise,
        including, muscles, equipment, etc. This can be used to avoid having to call
        the other endpoints individually.
    </div>
</div>

<div style="margin-top: 1em;">
    <code>api/v2/nutritionplan/&lt;id&gt;/nutritional_values/</code><br>
    <code>api/v2/meal/&lt;id&gt;/nutritional_values/</code><br>
    <code>api/v2/mealitem/&lt;id&gt;/nutritional_values/</code>
</div>
<div class="row">
    <div class="col-md-offset-1 col-md-10">
        Returns the total nutritional values for a nutritional plan, a meal or
        an individual meal item. The nutritional plan lists this under the
        'total' key, the other two return a flat list.

        The nutritional plan also returns under the 'per_kg' key the calculated
        values of grams per user body weight (if available) and 'percent' lists
        the percent each macronutrient contributes to the total calories.
    </div>
</div>


<h3>Data documentation</h3>
<p>The data structures should be pretty forward and easy to understand: a workout
is composed of workout days. Each day has different exercises they in turn have
repetitions, and so on. These diagrams are automatically generated from the
database structure, which is basically exposed through the API 1-to-1. Click on
the images to download a bigger version.</p>


<div class="panel-group" id="api-accordion">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h4 class="panel-title">
                <a data-toggle="collapse" data-parent="#api-accordion" href="#api-workout">
                Workouts
                </a>
            </h4>
        </div>
        <div id="api-workout" class="panel-collapse collapse in">
            <div class="panel-body">
                <a href="{% static 'images/api/db-manager.svg' %}">
                    <img src="{% static 'images/api/db-manager.svg' %}" class="img-responsive">
                </a>
            </div>
        </div>
    </div>

    <div class="panel panel-default">
        <div class="panel-heading">
            <h4 class="panel-title">
                <a data-toggle="collapse" data-parent="#api-accordion" href="#api-nutrition">
                Nutrition
                </a>
            </h4>
        </div>
        <div id="api-nutrition" class="panel-collapse collapse">
            <div class="panel-body">
                <a href="{% static 'images/api/db-nutrition.svg' %}">
                    <img src="{% static 'images/api/db-nutrition.svg' %}" class="img-responsive">
                </a>
            </div>
        </div>
    </div>

    <div class="panel panel-default">
        <div class="panel-heading">
            <h4 class="panel-title">
                <a data-toggle="collapse" data-parent="#api-accordion" href="#api-exercises">
                Exercises
                </a>
            </h4>
        </div>
        <div id="api-exercises" class="panel-collapse collapse">
            <div class="panel-body">
                <a href="{% static 'images/api/db-exercises.svg' %}">
                    <img src="{% static 'images/api/db-exercises.svg' %}" class="img-responsive">
                </a>
            </div>
        </div>
    </div>

    <div class="panel panel-default">
        <div class="panel-heading">
            <h4 class="panel-title">
                <a data-toggle="collapse" data-parent="#api-accordion" href="#api-all">
                Complete DB
                </a>
            </h4>
        </div>
        <div id="api-all" class="panel-collapse collapse">
            <div class="panel-body">
                <a href="{% static 'images/api/db-all.svg' %}">
                    <img src="{% static 'images/api/db-all.svg' %}" class="img-responsive">
                </a>
            </div>
        </div>
    </div>
</div>



<h3>Tools</h3>
<p>
    You can play and experiment with the API by sending the requests with many
    tools, here are two:
</p>

<pre>
# In the terminal, e.g. bash
curl -H "Authorization: Token 123456..." \
     -H "Accept: application/json; indent=4" \
     -X PATCH --data '{"key": value, ...}' \
     --dump-header -
     https://wger.de/api/v2/....
</pre>

<pre>
# In the python console
>>> import requests
>>> import json
>>> from pprint import pprint
>>>
>>> url = 'https://wger.de/api/v2/....'
>>> data = '{"key": "value"}'
>>> headers = {'Accept': 'application/json',
               'Authorization': 'Token 12345...'}
>>> r = requests.patch(url=url, data=data, headers=headers)
>>> r
>>> r.content
>>> pprint(json.loads(r.content))
</pre>


<h3>/api/v1</h3>
<div class="panel panel-warning">
    <div class="panel-heading">
        <h3 class="panel-title">Deprecation warning</h3>
    </div>
    <div class="panel-body">
        The first API supported only read operations. Due to different reasons
        it is being deprecated and should not be used anymore, it will be
        deactivated on June 2015.
    </div>
</div>
<p>
</p>

{% endblock %}



{% block sidebar %}
<div class="alert alert-info" style="margin-top:1em;">
    This is also new for us, if you plan on using the API,
    <a href="https://groups.google.com/group/wger" class="alert-link">we'd love to hear from you</a>.
</div>

<p><a href="/api/v2/" class="btn btn-block btn-default" rel="nofollow">Browse the API</a></p>
<p><a href="{% url 'core:user:api-key' %}" class="btn btn-block btn-default">Generate API KEY</a></p>
{% endblock %}
