/
api.html
456 lines (395 loc) · 15.7 KB
/
api.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
{% 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>
<h6>JWT Authentication</h6>
<p>
You can generate access token via <code>/token/</code> endpoint. Send a username and password, and you will get the
<code>access</code> token which you can use to access the private endpoints.
<pre>
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "example_username", "password": "example_password "}' \
https://wger.de/api/v2/token/
...
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}
</pre>
<p>Additionally, you can send an access token to <code>/token/verify/</code> endpoint to verify that token.</p>
<p>When this short-lived access token expires, you can use the longer-lived <code>refresh</code>
token to obtain another access token.
<pre>
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"}' \
https://wger.de/api/v2/token/refresh/
...
{"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNTY3LCJqdGkiOiJjNzE4ZTVkNjgzZWQ0NTQyYTU0NWJkM2VmMGI0ZGQ0ZSJ9.ekxRxgb9OKmHkfy-zs1Ro_xs1eMLXiR17dIDBVxeT-w"}
</pre>
</p>
</p>
<p>You should always use HTTPS if possible when communicating with the server.</p>
<p>At the moment it is not possible to register via the API.</p>
<p><strong>Deprecated: </strong>You can also generate a token via the <code>login</code> endpoint. Send a
username and password, and you will get the user's token or a new one will be
generated.</p>
<div class="container">
<div class="row">
<div class="col-6">
<h4>Public endpoints</h4>
<ul>
<li>daysofweek</li>
<li>equipment</li>
<li>exercise</li>
<li>exercisealias</li>
<li>exercisecategory</li>
<li>exercisecomment</li>
<li>exerciseimage</li>
<li>exerciseinfo</li>
<li>ingredient</li>
<li>ingredientinfo</li>
<li>ingredienttoweightunit</li>
<li>language</li>
<li>license</li>
<li>muscle</li>
<li>setting-repetitionunit</li>
<li>setting-weightunit</li>
<li>variation</li>
<li>weightunit</li>
</ul>
</div>
<div class="col-6">
<h4>Private endpoints</h4>
<ul>
<li>day</li>
<li>gallery</li>
<li>meal</li>
<li>mealitem</li>
<li>nutritiondiary</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>
</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/<endpoint>.json/</code>
</li>
<li>
<code>/api/v2/<endpoint>/?format=json</code>
</li>
<li>
<code>/api/v2/<endpoint>.api/</code> - browsable HTML view
</li>
</ul>
</li>
</ul>
<h3>Fetching Data</h3>
<pre>
# Api-Wide
/api/v2/
# Object detail view
/api/v2/<endpoint>/<id>/
</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/<endpoint>/</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=<fieldname></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=<field1>,<field2></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=<xxx></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>?<fieldname>=<value></code>, combinations are possible,
the filters will be AND-joined: <code>?<f1>=<v1>&<f2>=<v2></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. The <strong>only</strong> exception to this is the exercises endpoint,
there it is possible to OR different values, e.g. <code>?muscles=2,7</code>
which will search for exercises that train muscle 2 OR 7.
</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>
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/<id>/canonical_representation/</code>
</div>
<div class="row">
<div class="offset-md-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/<id>/thumbnails/</code>
</div>
<div class="row">
<div class="offset-md-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/<id>/</code>
</div>
<div class="row">
<div class="offset-md-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/<id>/nutritional_values/</code><br>
<code>api/v2/meal/<id>/nutritional_values/</code><br>
<code>api/v2/mealitem/<id>/nutritional_values/</code>
</div>
<div class="row">
<div class="offset-md-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>
<div style="margin-top: 1em;">
<code>api/v2/nutritionplan/<id>/get_log_overview/</code><br>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-10">
Returns a list with the combined nutritional values logged for the given
plan for all available days where a diary entry was logged.
</div>
</div>
<div style="margin-top: 1em;">
<code>api/v2/nutritionplan/<id>/log_summary/?year=<year>&month=<month>&day=<day></code><br>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-10">
Returns the nutritional values logged for the nutrition diary for a
plan for the given date. You can omit the GET parameters, then you
will get the values for today.
</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="accordion mb-4" id="api-accordion">
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<button class="btn btn-link btn-block text-left"
type="button"
data-toggle="collapse"
data-target="#api-workout"
aria-expanded="true"
aria-controls="api-workout">
Workouts
</button>
</h4>
</div>
<div id="api-workout" class="collapse" data-parent="#api-accordion">
<div class="card-body">
<a href="{% static 'images/api/db-manager.svg' %}">
<img src="{% static 'images/api/db-manager.svg' %}" class="img-fluid">
</a>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<button class="btn btn-link btn-block text-left"
type="button"
data-toggle="collapse"
data-target="#api-nutrition"
aria-expanded="true"
aria-controls="api-nutrition">
Nutrition
</button>
</h4>
</div>
<div id="api-nutrition" class="collapse" data-parent="#api-accordion">
<div class="card-body">
<a href="{% static 'images/api/db-nutrition.svg' %}">
<img src="{% static 'images/api/db-nutrition.svg' %}" class="img-fluid">
</a>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<button class="btn btn-link btn-block text-left"
type="button"
data-toggle="collapse"
data-target="#api-exercises"
aria-expanded="true"
aria-controls="api-exercises">
Exercises
</button>
</h4>
</div>
<div id="api-exercises" class="collapse" data-parent="#api-accordion">
<div class="card-body">
<a href="{% static 'images/api/db-exercises.svg' %}">
<img src="{% static 'images/api/db-exercises.svg' %}" class="img-fluid">
</a>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<button class="btn btn-link btn-block text-left"
type="button"
data-toggle="collapse"
data-target="#api-all"
aria-expanded="true"
aria-controls="api-all">
Complete DB
</button>
</h4>
</div>
<div id="api-all" class="collapse" data-parent="#api-accordion">
<div class="card-body">
<a href="{% static 'images/api/db-all.svg' %}">
<img src="{% static 'images/api/db-all.svg' %}" class="img-fluid">
</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>
{% 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://github.com/wger-project/wger" class="alert-link">we'd love to hear from you</a>.
</div>
<p><a href="/api/v2/" class="btn btn-block btn-light" rel="nofollow">Browse the API</a></p>
<p><a href="{% url 'core:user:api-key' %}" class="btn btn-block btn-light">Generate API KEY</a></p>
{% endblock %}