From fcebb7a3dfa1f8df258d74111584c700c46e1c4c Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 20 Jul 2019 21:57:35 +0200 Subject: [PATCH] update docs for remaining endpoints - fix #21 and fix some routes to add authentication --- docs/_sources/api/records.rst.txt | 2 - docs/_sources/api/sports.rst.txt | 7 +- docs/_sources/api/stats.rst.txt | 2 - docs/_sources/api/users.rst.txt | 2 - docs/api/activities.html | 89 +++++--- docs/api/auth.html | 42 +++- docs/api/records.html | 106 ++++++++- docs/api/sports.html | 158 +++++++++++-- docs/api/stats.html | 197 ++++++++++++++++- docs/api/users.html | 194 +++++++++++++++- docs/http-routingtable.html | 15 -- docs/objects.inv | Bin 774 -> 745 bytes docs/searchindex.js | 2 +- docsrc/source/api/records.rst | 2 - docsrc/source/api/sports.rst | 7 +- docsrc/source/api/stats.rst | 2 - docsrc/source/api/users.rst | 2 - .../fittrackee_api/activities/activities.py | 66 ++++-- .../fittrackee_api/activities/records.py | 96 +++++++- .../fittrackee_api/activities/sports.py | 137 +++++++++++- .../fittrackee_api/activities/stats.py | 172 ++++++++++++++- .../fittrackee_api/tests/test_users_api.py | 149 ++++++++++++- fittrackee_api/fittrackee_api/users/auth.py | 34 ++- fittrackee_api/fittrackee_api/users/users.py | 207 +++++++++++++++++- 24 files changed, 1533 insertions(+), 157 deletions(-) diff --git a/docs/_sources/api/records.rst.txt b/docs/_sources/api/records.rst.txt index fe42bf73..c78be7c4 100644 --- a/docs/_sources/api/records.rst.txt +++ b/docs/_sources/api/records.rst.txt @@ -1,8 +1,6 @@ Records ####### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: records.get_records diff --git a/docs/_sources/api/sports.rst.txt b/docs/_sources/api/sports.rst.txt index 3147efa7..078a5397 100644 --- a/docs/_sources/api/sports.rst.txt +++ b/docs/_sources/api/sports.rst.txt @@ -1,12 +1,7 @@ Sports ###### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: sports.get_sports, - sports.get_sport, - sports.post_sport, - sports.update_sport, - sports.delete_sport + sports.get_sport diff --git a/docs/_sources/api/stats.rst.txt b/docs/_sources/api/stats.rst.txt index d802fa3b..0621d298 100644 --- a/docs/_sources/api/stats.rst.txt +++ b/docs/_sources/api/stats.rst.txt @@ -1,8 +1,6 @@ Statistics ########## -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: stats.get_activities_by_sport, diff --git a/docs/_sources/api/users.rst.txt b/docs/_sources/api/users.rst.txt index 3fc1be80..09785889 100644 --- a/docs/_sources/api/users.rst.txt +++ b/docs/_sources/api/users.rst.txt @@ -1,8 +1,6 @@ Users ##### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: users.get_users, diff --git a/docs/api/activities.html b/docs/api/activities.html index 1189b658..b325aa79 100644 --- a/docs/api/activities.html +++ b/docs/api/activities.html @@ -239,7 +239,7 @@
Parameters
    -
  • auth_user_id (integer) – authenticate user id

  • +
  • auth_user_id (integer) – authenticate user id (from JSON Web Token)

Query Parameters
@@ -268,7 +268,12 @@
Status Codes
@@ -345,7 +350,7 @@
Parameters
    -
  • auth_user_id (integer) – authenticate user id

  • +
  • auth_user_id (integer) – authenticate user id (from JSON Web Token)

  • activity_id (integer) – activity id

@@ -357,7 +362,12 @@
Status Codes
@@ -456,7 +466,7 @@
Parameters
    -
  • auth_user_id (integer) – authenticate user id

  • +
  • auth_user_id (integer) – authenticate user id (from JSON Web Token)

Form Parameters
@@ -480,7 +490,12 @@
  • File extension not allowed.

  • -
  • 401 Unauthorized – invalid token

  • +
  • 401 Unauthorized

      +
    • Provide a valid auth token.

    • +
    • Signature expired. Please log in again.

    • +
    • Invalid token. Please log in again.

    • +
    +

  • 500 Internal Server Error

  • @@ -492,7 +507,7 @@ POST /api/activities/no_gpx

    Post an activity without gpx file

    Example request:

    -
    POST /api/activities/ HTTP/1.1
    +
    POST /api/activities/no_gpx HTTP/1.1
     Content-Type: application/json
     
    @@ -578,7 +593,7 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    Request JSON Object
    @@ -600,7 +615,12 @@
    @@ -698,7 +718,7 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • activity_id (integer) – activity id

    @@ -724,7 +744,12 @@
    @@ -749,7 +774,7 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • activity_id (integer) – activity id

    @@ -761,7 +786,12 @@
    Status Codes
    @@ -787,19 +817,18 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • map_id (string) – activity map id

    -
    Request Headers
    +
    Status Codes
    -
    -
    Status Codes
    -
    @@ -832,7 +861,7 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • activity_id (integer) – activity id

    @@ -845,7 +874,12 @@
    @@ -893,7 +927,7 @@
    Parameters
      -
    • auth_user_id (integer) – authenticate user id

    • +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • activity_id (integer) – activity id

    @@ -906,7 +940,12 @@
    diff --git a/docs/api/auth.html b/docs/api/auth.html index 77bd8297..1a1ac600 100644 --- a/docs/api/auth.html +++ b/docs/api/auth.html @@ -128,7 +128,7 @@ POST /api/auth/register

    register a user

    Example request:

    -
    POST /auth/register HTTP/1.1
    +
    POST /api/auth/register HTTP/1.1
     Content-Type: application/json
     
    @@ -196,7 +196,7 @@ POST /api/auth/login

    user login

    Example request:

    -
    POST /auth/login HTTP/1.1
    +
    POST /api/auth/login HTTP/1.1
     Content-Type: application/json
     
    @@ -248,7 +248,7 @@ GET /api/auth/logout

    user logout

    Example request:

    -
    GET /auth/logout HTTP/1.1
    +
    GET /api/auth/logout HTTP/1.1
     Content-Type: application/json
     
    @@ -297,7 +297,7 @@ GET /api/auth/profile

    get authenticated user info

    Example request:

    -
    GET /auth/profile HTTP/1.1
    +
    GET /api/auth/profile HTTP/1.1
     Content-Type: application/json
     
    @@ -337,7 +337,12 @@
    Status Codes
    • 200 OK – success.

    • -
    • 401 Unauthorized – Provide a valid auth token.

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    @@ -348,7 +353,7 @@ POST /api/auth/profile/edit

    edit authenticated user

    Example request:

    -
    POST /auth/profile/edit HTTP/1.1
    +
    POST /api/auth/profile/edit HTTP/1.1
     Content-Type: application/json
     
    @@ -405,7 +410,12 @@
  • Password and password confirmation don’t match.

  • -
  • 401 Unauthorized – Provide a valid auth token.

  • +
  • 401 Unauthorized

      +
    • Provide a valid auth token.

    • +
    • Signature expired. Please log in again.

    • +
    • Invalid token. Please log in again.

    • +
    +

  • 500 Internal Server Error – Error. Please try again or contact the administrator.

  • @@ -417,7 +427,7 @@ POST /api/auth/picture

    update authenticated user picture

    Example request:

    -
    POST /auth/picture HTTP/1.1
    +
    POST /api/auth/picture HTTP/1.1
     Content-Type: multipart/form-data
     
    @@ -469,7 +479,12 @@
  • File extension not allowed.

  • -
  • 401 Unauthorized – Provide a valid auth token.

  • +
  • 401 Unauthorized

      +
    • Provide a valid auth token.

    • +
    • Signature expired. Please log in again.

    • +
    • Invalid token. Please log in again.

    • +
    +

  • 500 Internal Server Error – Error during picture update.

  • @@ -481,7 +496,7 @@ DELETE /api/auth/picture

    delete authenticated user picture

    Example request:

    -
    DELETE /auth/picture HTTP/1.1
    +
    DELETE /api/auth/picture HTTP/1.1
     Content-Type: application/json
     
    @@ -499,7 +514,12 @@
    Status Codes
    diff --git a/docs/api/records.html b/docs/api/records.html index 343cec00..59b1d5ab 100644 --- a/docs/api/records.html +++ b/docs/api/records.html @@ -123,11 +123,113 @@

    Records

    -

    work in progress

    GET /api/records
    -

    Get all records for authenticated user

    +

    Get all records for authenticated user.

    +
    +
    Following types of records are available:
      +
    • average speed (record_type: ‘AS’)

    • +
    • farest distance (record_type: ‘FD’)

    • +
    • longest duration (record_type: ‘LD’)

    • +
    • maximum speed (record_type: ‘MS’)

    • +
    +
    +
    +

    Example request:

    +
    GET /api/records HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example responses:

    +
      +
    • returning records

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "records": [
    +      {
    +        "activity_date": "Sun, 07 Jul 2019 08:00:00 GMT",
    +        "activity_id": 4,
    +        "id": 9,
    +        "record_type": "AS",
    +        "sport_id": 1,
    +        "user_id": 1,
    +        "value": 18
    +      },
    +      {
    +        "activity_date": "Sun, 07 Jul 2019 08:00:00 GMT",
    +        "activity_id": 4,
    +        "id": 10,
    +        "record_type": "FD",
    +        "sport_id": 1,
    +        "user_id": 1,
    +        "value": 18
    +      },
    +      {
    +        "activity_date": "Sun, 07 Jul 2019 08:00:00 GMT",
    +        "activity_id": 7,
    +        "id": 11,
    +        "record_type": "LD",
    +        "sport_id": 1,
    +        "user_id": 1,
    +        "value": "1:01:00"
    +      },
    +      {
    +        "activity_date": "Sun, 07 Jul 2019 08:00:00 GMT",
    +        "activity_id": 4,
    +        "id": 12,
    +        "record_type": "MS",
    +        "sport_id": 1,
    +        "user_id": 1,
    +        "value": 18
    +      }
    +    ]
    +  },
    +  "status": "success"
    +}
    +
    +
    +
      +
    • no records

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "records": []
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    +
    +
    diff --git a/docs/api/sports.html b/docs/api/sports.html index be265965..14e6f02b 100644 --- a/docs/api/sports.html +++ b/docs/api/sports.html @@ -123,35 +123,159 @@

    Sports

    -

    work in progress

    GET /api/sports

    Get all sports

    +

    Example request:

    +
    GET /api/sports HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "sports": [
    +      {
    +        "_can_be_deleted": false,
    +        "id": 1,
    +        "img": "/img/sports/cycling-sport.png",
    +        "label": "Cycling (Sport)"
    +      },
    +      {
    +        "_can_be_deleted": false,
    +        "id": 2,
    +        "img": "/img/sports/cycling-transport.png",
    +        "label": "Cycling (Transport)"
    +      },
    +      {
    +        "_can_be_deleted": false,
    +        "id": 3,
    +        "img": "/img/sports/hiking.png",
    +        "label": "Hiking"
    +      },
    +      {
    +        "_can_be_deleted": false,
    +        "id": 4,
    +        "img": "/img/sports/mountain-biking.png",
    +        "label": "Mountain Biking"
    +      },
    +      {
    +        "_can_be_deleted": false,
    +        "id": 5,
    +        "img": "/img/sports/running.png",
    +        "label": "Running"
    +      },
    +      {
    +        "_can_be_deleted": false,
    +        "id": 6,
    +        "img": "/img/sports/walking.png",
    +        "label": "Walking"
    +      }
    +    ]
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    +
    +
    GET /api/sports/(int: sport_id)

    Get a sport

    -
    +

    Example request:

    +
    GET /api/sports/1 HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
      +
    • success

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
     
    -
    -
    -POST /api/sports
    -

    Post a sport

    -
    +{ + "data": { + "sports": [ + { + "_can_be_deleted": false, + "id": 1, + "img": "/img/sports/cycling-sport.png", + "label": "Cycling (Sport)" + } + ] + }, + "status": "success" +} +
    +
    +
      +
    • sport not found

    • +
    +
    HTTP/1.1 404 NOT FOUND
    +Content-Type: application/json
     
    -
    -
    -PATCH /api/sports/(int: sport_id)
    -

    Update a sport

    -
    - -
    -
    -DELETE /api/sports/(int: sport_id)
    -

    Delete a sport

    +{ + "data": { + "sports": [] + }, + "status": "not found" +} +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    • sport_id (integer) – sport id

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    • 404 Not Found – sport not found

    • +
    +
    +
    diff --git a/docs/api/stats.html b/docs/api/stats.html index 7af04732..bf8e275a 100644 --- a/docs/api/stats.html +++ b/docs/api/stats.html @@ -123,17 +123,212 @@

    Statistics

    -

    work in progress

    GET /api/stats/(int: user_id)/by_sport

    Get activities statistics for a user by sport

    +

    Example requests:

    +
      +
    • without parameters (get stats for all sports with activities)

    • +
    +
    GET /api/stats/1/by_sport HTTP/1.1
    +
    +
    +
      +
    • with sport id

    • +
    +
    GET /api/stats/1/by_sport?sport_id=1 HTTP/1.1
    +
    +
    +

    Example responses:

    +
      +
    • success

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "statistics": {
    +      "1": {
    +        "nb_activities": 3,
    +        "total_distance": 47,
    +        "total_duration": 9960
    +      },
    +      "2": {
    +        "nb_activities": 1,
    +        "total_distance": 5.613,
    +        "total_duration": 1267
    +      },
    +      "3": {
    +        "nb_activities": 2,
    +        "total_distance": 15.282,
    +        "total_duration": 12341
    +      }
    +    }
    +  },
    +  "status": "success"
    +}
    +
    +
    +
      +
    • no activities

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +      "statistics": {}
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    • user_id (integer) – user id

    • +
    +
    +
    Query Parameters
    +
      +
    • sport_id (integer) – sport id

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    • 404 Not Found

        +
      • User does not exist.

      • +
      • Sport does not exist.

      • +
      +

    • +
    +
    +
    GET /api/stats/(int: user_id)/by_time

    Get activities statistics for a user by time

    +

    Example requests:

    +
      +
    • without parameters

    • +
    +
    GET /api/stats/1/by_time HTTP/1.1
    +
    +
    +
      +
    • with parameters

    • +
    +
    GET /api/stats/1/by_time?from=2018-01-01&to=2018-06-30&time=week HTTP/1.1
    +
    +
    +

    Example responses:

    +
      +
    • success

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "statistics": {
    +      "2017": {
    +        "3": {
    +          "nb_activities": 2,
    +          "total_distance": 15.282,
    +          "total_duration": 12341
    +        }
    +      },
    +      "2019": {
    +        "1": {
    +          "nb_activities": 3,
    +          "total_distance": 47,
    +          "total_duration": 9960
    +        },
    +        "2": {
    +          "nb_activities": 1,
    +          "total_distance": 5.613,
    +          "total_duration": 1267
    +        }
    +      }
    +    }
    +  },
    +  "status": "success"
    +}
    +
    +
    +
      +
    • no activities

    • +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +      "statistics": {}
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    • user_id (integer) – user id

    • +
    +
    +
    Query Parameters
    +
      +
    • from (string) – start date (format: %Y-%m-%d)

    • +
    • to (string) – end date (format: %Y-%m-%d)

    • +
    • time (string) –

      time frame:

      +
        +
      • week: week starting Sunday

      • +
      • weekm: week starting Monday

      • +
      • month: month

      • +
      • year: year (default)

      • +
      +

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    • 404 Not Found

        +
      • User does not exist.

      • +
      +

    • +
    +
    +
    diff --git a/docs/api/users.html b/docs/api/users.html index 97545a3d..c987dc93 100644 --- a/docs/api/users.html +++ b/docs/api/users.html @@ -123,29 +123,221 @@

    Users

    -

    work in progress

    GET /api/users

    Get all users

    +

    Example request:

    +
    GET /api/users HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "users": [
    +      {
    +        "admin": true,
    +        "bio": null,
    +        "birth_date": null,
    +        "created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
    +        "email": "admin@example.com",
    +        "first_name": null,
    +        "id": 1,
    +        "last_name": null,
    +        "location": null,
    +        "nb_activities": 6,
    +        "nb_sports": 3,
    +        "picture": false,
    +        "timezone": "Europe/Paris",
    +        "total_distance": 67.895,
    +        "total_duration": "6:50:27",
    +        "username": "admin"
    +      },
    +      {
    +        "admin": false,
    +        "bio": null,
    +        "birth_date": null,
    +        "created_at": "Sat, 20 Jul 2019 11:27:03 GMT",
    +        "email": "sam@example.com",
    +        "first_name": null,
    +        "id": 2,
    +        "last_name": null,
    +        "location": null,
    +        "nb_activities": 0,
    +        "nb_sports": 0,
    +        "picture": false,
    +        "timezone": "Europe/Paris",
    +        "total_distance": 0,
    +        "total_duration": "0:00:00",
    +        "username": "sam"
    +      }
    +    ]
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    +
    +
    GET /api/users/(user_id)

    Get single user details

    +

    Example request:

    +
    GET /api/users/1 HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "data": {
    +    "admin": true,
    +    "bio": null,
    +    "birth_date": null,
    +    "created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
    +    "email": "admin@example.com",
    +    "first_name": null,
    +    "id": 1,
    +    "last_name": null,
    +    "location": null,
    +    "nb_activities": 6,
    +    "nb_sports": 3,
    +    "picture": false,
    +    "timezone": "Europe/Paris",
    +    "total_distance": 67.895,
    +    "total_duration": "6:50:27",
    +    "username": "admin"
    +  },
    +  "status": "success"
    +}
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    • user_id (integer) – user id

    • +
    +
    +
    Request Headers
    +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    • 404 Not Found

        +
      • User does not exist

      • +
      +

    • +
    +
    +
    GET /api/users/(user_id)/picture

    get user picture

    +

    Example request:

    +
    GET /api/users/1/picture HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
    HTTP/1.1 200 OK
    +Content-Type: image/jpeg
    +
    +
    +
    +
    Parameters
    +
      +
    • auth_user_id (integer) – authenticate user id (from JSON Web Token)

    • +
    • user_id (integer) – user id

    • +
    +
    +
    Status Codes
    +
      +
    • 200 OK – success

    • +
    • 401 Unauthorized

        +
      • Provide a valid auth token.

      • +
      • Signature expired. Please log in again.

      • +
      • Invalid token. Please log in again.

      • +
      +

    • +
    • 404 Not Found

        +
      • User does not exist

      • +
      • No picture.

      • +
      +

    • +
    +
    +
    GET /api/ping

    health check endpoint

    +

    Example request:

    +
    GET /api/ping HTTP/1.1
    +Content-Type: application/json
    +
    +
    +

    Example response:

    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +
    +{
    +  "message": "pong!",
    +  "status": "success"
    +}
    +
    +
    +
    +
    Status Codes
    +
    +
    +
    diff --git a/docs/http-routingtable.html b/docs/http-routingtable.html index a0930cf8..cc02c0f3 100644 --- a/docs/http-routingtable.html +++ b/docs/http-routingtable.html @@ -232,11 +232,6 @@ POST /api/auth/register - - - - POST /api/sports - @@ -247,21 +242,11 @@ DELETE /api/auth/picture - - - - DELETE /api/sports/(int:sport_id) - PATCH /api/activities/(int:activity_id) - - - - PATCH /api/sports/(int:sport_id) - diff --git a/docs/objects.inv b/docs/objects.inv index ab45d0656ba42d2dcccf7f0aba246f772bd11169..8df5bbbc1386ef3aa7ca7461b7a89a0ed9e3cb8b 100644 GIT binary patch delta 635 zcmV->0)+jB2I&Qmd4H8XZ`&{shIjo60$tpJ6}oy03IxbdAV|{Lpv8+sR2Bv5RK)+j z{FEqCcIC#4LEgRZLmhdfOV*2$RVe-l6flqmvESE#EzGxojgnh+}PpNdjoXDrfg*` zx}2s{8Ar#clP3T^b(~#2CchJM>av zW_8iT>7@&!yRvq?c89KT+#Q{r0gEh9P1*JlIGztym(h(jg`1dT2S1(s*VjOCf=?`A z?S2J&Vq1>U31e5e3((DeI$PFB%jvLu|HOTEuuGoj6Se?CfyrydFAYoj0Q5 zT}o4_grj2A$|HanF)4Hc%q2R%R)>I|7dT2-J6aQDai}!Mo34Vk6tfDE;*B@3wH_~D zLF7?#|#hkW*b4Bu4Wer$LZFUp^<;oE3ro~+-r zx%bYOlhGv$*V=g9I%e74PbdHFIgq#Ti7AZT&0v~zOMmBDVd%;a9=h32XUjTidBf}? z26s*LS7pHRSc-zs)q9*gOykU-`NZPy0rH@pphI3TIqtD@Bx^;vvX1^jeZqQvigHvRB)g&km@Mk0!^YfJ+x#=DAVVp}a|1&y z1gZ}~&dQc|>ODw?LWb+SDRf;Gh7xkJPpbk;dJW?p diff --git a/docs/searchindex.js b/docs/searchindex.js index f3ad679f..50a76567 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["api/activities","api/auth","api/index","api/records","api/sports","api/stats","api/users","changelog","features","index","installation","troubleshooting/administrator","troubleshooting/index","troubleshooting/user"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:56},filenames:["api/activities.rst","api/auth.rst","api/index.rst","api/records.rst","api/sports.rst","api/stats.rst","api/users.rst","changelog.md","features.rst","index.rst","installation.rst","troubleshooting/administrator.rst","troubleshooting/index.rst","troubleshooting/user.rst"],objects:{"":{"/api/activities":[0,1,1,"post--api-activities"],"/api/activities/(int:activity_id)":[0,3,1,"patch--api-activities-(int-activity_id)"],"/api/activities/(int:activity_id)/chart_data":[0,0,1,"get--api-activities-(int-activity_id)-chart_data"],"/api/activities/(int:activity_id)/gpx":[0,0,1,"get--api-activities-(int-activity_id)-gpx"],"/api/activities/map/(map_id)":[0,0,1,"get--api-activities-map-(map_id)"],"/api/activities/no_gpx":[0,1,1,"post--api-activities-no_gpx"],"/api/auth/login":[1,1,1,"post--api-auth-login"],"/api/auth/logout":[1,0,1,"get--api-auth-logout"],"/api/auth/picture":[1,1,1,"post--api-auth-picture"],"/api/auth/profile":[1,0,1,"get--api-auth-profile"],"/api/auth/profile/edit":[1,1,1,"post--api-auth-profile-edit"],"/api/auth/register":[1,1,1,"post--api-auth-register"],"/api/ping":[6,0,1,"get--api-ping"],"/api/records":[3,0,1,"get--api-records"],"/api/sports":[4,1,1,"post--api-sports"],"/api/sports/(int:sport_id)":[4,3,1,"patch--api-sports-(int-sport_id)"],"/api/stats/(int:user_id)/by_sport":[5,0,1,"get--api-stats-(int-user_id)-by_sport"],"/api/stats/(int:user_id)/by_time":[5,0,1,"get--api-stats-(int-user_id)-by_time"],"/api/users":[6,0,1,"get--api-users"],"/api/users/(user_id)":[6,0,1,"get--api-users-(user_id)"],"/api/users/(user_id)/picture":[6,0,1,"get--api-users-(user_id)-picture"]}},objnames:{"0":["http","get","HTTP get"],"1":["http","post","HTTP post"],"2":["http","delete","HTTP delete"],"3":["http","patch","HTTP patch"]},objtypes:{"0":"http:get","1":"http:post","2":"http:delete","3":"http:patch"},terms:{"default":0,"export":9,"float":0,"int":[0,4,5],"null":[0,1],"return":0,"static":10,"try":[0,1],NOT:[0,1],Not:[0,1],That:1,The:10,Use:7,accord:9,account:8,acit:0,activ:[2,5,7,9],activity_d:0,activity_id:0,adapt:10,add:[7,8,9],admin:[1,8,10],administr:[0,1,8,9,12],again:[0,1],all:[3,4,6,10],allow:[0,1,9],alpinequest:9,alreadi:1,also:9,android:9,api:[0,1,3,4,5,6,8,9,10,11],app:9,applic:[0,1,9,10],arch:10,archiv:10,ascent:0,auth:[0,1],auth_token:1,auth_user_id:0,authent:[0,2,3,9],author:[0,1],ave_spe:0,ave_speed_from:0,ave_speed_to:0,averag:[0,8],bad:[0,1],bearer:[0,1],beta:10,bike:[0,8],bio:1,biographi:1,birth:1,birth_dat:1,bound:0,build:10,by_sport:5,by_tim:5,calcul:7,calendar:[7,8],can:[8,9,10],chang:[9,10],charact:[1,12],chart:[0,8,10],chart_data:0,check:[6,11],client:[10,11],clone:10,code:[0,1],column:12,com:[1,10],config:[10,11],confirm:1,contact:[0,1],content:[0,1],coordin:10,copi:10,correctli:[7,11],creat:[0,1,8],created_at:1,creation:8,creation_d:0,credenti:1,current:7,custom:[10,11],cycl:8,dark:10,darkski:8,dashboard:[7,9],data:[0,1,9,10,12],databas:10,date:[0,1,8],debian:10,delet:[0,1,4,8],depend:7,desc:0,descent:0,describ:10,detail:[6,7,9],develop:9,displai:[0,7,8,9,10],distanc:[0,7,8],distance_from:0,distance_to:0,document:9,doe:0,don:1,download:10,durat:[0,7,8],duration_from:0,duration_to:0,dure:1,edit:[1,8],elev:[0,8,10],email:[1,10],encount:10,end:0,endpoint:[2,6,12],enter:8,environn:11,error:[0,1,7],europ:1,even:8,exampl:[0,1,9,10,11],exist:[0,1,9,11],exodu:9,extens:[0,1],fa33f4d996844a5c73ecd1ae24456ab8:0,fals:[0,1],farest:8,featur:9,fetch:10,file:[0,1,7,8,9,10,11],filter:[7,8],first:1,first_nam:1,fittracke:10,fix:9,flask:10,flaticon:10,follow:10,forbidden:0,forecast:10,form:[0,1],format:[0,1],former:10,forrunn:9,found:[0,1],freepik:10,fri:0,from:[0,9,10],gener:10,get:[0,1,3,4,5,6],gif:1,git:10,github:10,gmt:[0,1],gpl:9,gpx:[0,7,8,9,10],gpxpy:10,have:0,header:[0,1],health:6,hike:8,his:8,http:[0,1,10,11],icon:10,imag:[0,1,10],improv:9,incorrect:7,info:1,inform:9,initi:[10,11],instal:9,integ:0,intern:[0,1],invalid:[0,1],issu:[9,10],jan:0,javascript:10,jpg:1,json:[0,1,12],jul:[0,1],keep:9,kei:[8,10],last:[1,10],last_nam:1,leaflet:[0,10],least:0,line:12,linux:10,list:9,local:9,localhost:[10,11],locat:1,log:[1,9,10],login:[1,10],logout:1,longest:8,made:[10,11],mai:10,make:10,makefil:[10,11],mandatori:[0,10],map:[0,8,9,10],map_id:0,match:1,max:0,max_alt:0,max_spe:0,max_speed_from:0,max_speed_to:0,maxim:0,maximum:8,mean:11,messag:[0,1],min_alt:0,minim:[0,9],mobil:9,modification_d:0,mon:0,montain:8,month:[7,8],more:9,morn:0,move:[0,7],mpwoadmin:10,multipart:[0,1],must:[1,8],name:1,nb_activ:1,nb_sport:1,necessari:10,need:10,network:11,next_act:0,no_gpx:0,note:[0,7,8],now:[8,10],number:0,oauth:[0,1],object:[0,1],one:0,onli:[0,8],open:[9,10],order:0,other:10,out:1,outdoor:9,own:9,owner:8,packag:10,page:0,pagin:0,paramet:[0,1],pari:1,pars:[10,12],part:[0,1],password:[1,10],password_conf:1,past:10,patch:[0,4],paus:[0,7],payload:[0,1],per:0,per_pag:0,permiss:0,pictur:[1,6],ping:6,pleas:[0,1],png:[0,1],possibl:9,post:[0,1,4],postgresql:10,prerequisit:9,previous_act:0,privai:9,product:9,profil:1,progress:[3,4,5,6],proprietari:9,provid:[0,1,8],python:10,queri:0,react:10,react_app_api_url:11,readi:9,rebuild:11,rechart:[0,10],record:[0,2,7,8,9],record_typ:0,redux:10,regist:[1,10],registr:1,relat:10,releas:[7,10],repo:10,report:9,request:[0,1,11],requir:1,respons:[0,1],run:[8,10],runner:9,sam:1,samr1:10,search:7,second:0,see:[8,9,10,11],segment:[0,7],select:[0,1],serv:10,server:[0,1,9,10],sever:9,singl:6,sky:10,some:[0,7,10],sorri:1,sort:0,speed:[0,8,10],sport:[0,2,5,8,9,10],sport_id:[0,4],standard:8,start:[0,10],stat:[5,7],staticmap:10,statist:[2,9],statu:[0,1],step:10,still:9,store:9,street:9,string:[0,1],success:[0,1],successfulli:1,sun:[0,1],sundai:0,support:[7,8],system:10,tab:11,tar:10,test:10,them:9,thi:[0,7,9,10],thunderforest:10,time:[0,1,5,8],timezon:[1,7],titl:0,todo:[10,13],token:[0,1],tooltip:7,total:7,total_dist:1,total_dur:1,track:9,tracker:9,transport:8,troubleshoot:9,type:[0,1],unauthor:[0,1],undefin:11,under:9,unexpect:12,updat:[0,1,4,7,10],upgrad:9,upload:[7,8],user:[0,1,2,3,5,7,8,9,12],user_id:[0,5,6],usernam:1,using:[0,9],valid:[0,1],valu:[0,10],variabl:11,version:9,view:7,virtualenv:10,walk:8,weather:[7,8,10],weather_end:0,weather_start:0,web:[1,9],were:7,wget:10,when:7,with_gpx:0,without:[0,8,9],work:[3,4,5,6],workout:9,written:10,www:10,xzf:10,yarn:10,yet:9,you:[0,9],your:9,zip:0,zone:1},titles:["Activities","Authentication","API documentation","Records","Sports","Statistics","Users","Change log","Features","FitTrackee","Installation","Administrator","Troubleshooting","User"],titleterms:{"new":7,activ:[0,8],administr:11,api:2,authent:1,bug:7,chang:7,charact:11,close:7,column:11,content:9,dashboard:8,data:11,detail:8,dev:10,document:2,environ:10,featur:[7,8],fittracke:9,fix:7,improv:7,instal:10,issu:7,json:11,line:11,list:8,log:7,minim:7,misc:7,pars:11,prerequisit:10,prod:10,record:3,sport:4,statist:[5,7,8],tabl:9,troubleshoot:12,unexpect:11,upgrad:10,user:[6,13],version:7,workout:8}}) \ No newline at end of file +Search.setIndex({docnames:["api/activities","api/auth","api/index","api/records","api/sports","api/stats","api/users","changelog","features","index","installation","troubleshooting/administrator","troubleshooting/index","troubleshooting/user"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:56},filenames:["api/activities.rst","api/auth.rst","api/index.rst","api/records.rst","api/sports.rst","api/stats.rst","api/users.rst","changelog.md","features.rst","index.rst","installation.rst","troubleshooting/administrator.rst","troubleshooting/index.rst","troubleshooting/user.rst"],objects:{"":{"/api/activities":[0,1,1,"post--api-activities"],"/api/activities/(int:activity_id)":[0,3,1,"patch--api-activities-(int-activity_id)"],"/api/activities/(int:activity_id)/chart_data":[0,0,1,"get--api-activities-(int-activity_id)-chart_data"],"/api/activities/(int:activity_id)/gpx":[0,0,1,"get--api-activities-(int-activity_id)-gpx"],"/api/activities/map/(map_id)":[0,0,1,"get--api-activities-map-(map_id)"],"/api/activities/no_gpx":[0,1,1,"post--api-activities-no_gpx"],"/api/auth/login":[1,1,1,"post--api-auth-login"],"/api/auth/logout":[1,0,1,"get--api-auth-logout"],"/api/auth/picture":[1,1,1,"post--api-auth-picture"],"/api/auth/profile":[1,0,1,"get--api-auth-profile"],"/api/auth/profile/edit":[1,1,1,"post--api-auth-profile-edit"],"/api/auth/register":[1,1,1,"post--api-auth-register"],"/api/ping":[6,0,1,"get--api-ping"],"/api/records":[3,0,1,"get--api-records"],"/api/sports":[4,0,1,"get--api-sports"],"/api/sports/(int:sport_id)":[4,0,1,"get--api-sports-(int-sport_id)"],"/api/stats/(int:user_id)/by_sport":[5,0,1,"get--api-stats-(int-user_id)-by_sport"],"/api/stats/(int:user_id)/by_time":[5,0,1,"get--api-stats-(int-user_id)-by_time"],"/api/users":[6,0,1,"get--api-users"],"/api/users/(user_id)":[6,0,1,"get--api-users-(user_id)"],"/api/users/(user_id)/picture":[6,0,1,"get--api-users-(user_id)-picture"]}},objnames:{"0":["http","get","HTTP get"],"1":["http","post","HTTP post"],"2":["http","delete","HTTP delete"],"3":["http","patch","HTTP patch"]},objtypes:{"0":"http:get","1":"http:post","2":"http:delete","3":"http:patch"},terms:{"default":[0,5],"export":9,"float":0,"int":[0,4,5],"null":[0,1,6],"return":[0,3],"static":10,"true":6,"try":[0,1],NOT:[0,1,4],Not:[0,1,4,5,6],That:1,The:10,Use:7,_can_be_delet:4,accord:9,account:8,acit:0,activ:[2,5,7,9],activity_d:[0,3],activity_id:[0,3],adapt:10,add:[7,8,9],admin:[1,6,8,10],administr:[0,1,8,9,12],again:[0,1,3,4,5,6],all:[3,4,5,6,10],allow:[0,1,9],alpinequest:9,alreadi:1,also:9,android:9,api:[0,1,3,4,5,6,8,9,10,11],app:9,applic:[0,1,3,4,5,6,9,10],arch:10,archiv:10,ascent:0,auth:[0,1,3,4,5,6],auth_token:1,auth_user_id:[0,3,4,5,6],authent:[0,2,3,4,5,6,9],author:[0,1,3,4,5,6],avail:3,ave_spe:0,ave_speed_from:0,ave_speed_to:0,averag:[0,3,8],bad:[0,1],bearer:[0,1,3,4,5,6],beta:10,bike:[0,4,8],bio:[1,6],biographi:1,birth:1,birth_dat:[1,6],bound:0,build:10,by_sport:5,by_tim:5,calcul:7,calendar:[7,8],can:[8,9,10],chang:[9,10],charact:[1,12],chart:[0,8,10],chart_data:0,check:[6,11],client:[10,11],clone:10,code:[0,1,3,4,5,6],column:12,com:[1,6,10],config:[10,11],confirm:1,contact:[0,1],content:[0,1,3,4,5,6],coordin:10,copi:10,correctli:[7,11],creat:[0,1,8],created_at:[1,6],creation:8,creation_d:0,credenti:1,current:7,custom:[10,11],cycl:[4,8],dark:10,darkski:8,dashboard:[7,9],data:[0,1,3,4,5,6,9,10,12],databas:10,date:[0,1,5,8],debian:10,delet:[0,1,8],depend:7,desc:0,descent:0,describ:10,detail:[6,7,9],develop:9,displai:[0,7,8,9,10],distanc:[0,3,7,8],distance_from:0,distance_to:0,document:9,doe:[0,5,6],don:1,download:10,durat:[0,3,7,8],duration_from:0,duration_to:0,dure:1,edit:[1,8],elev:[0,8,10],email:[1,6,10],encount:10,end:[0,5],endpoint:[2,6,12],enter:8,environn:11,error:[0,1,7],europ:[1,6],even:8,exampl:[0,1,3,4,5,6,9,10,11],exist:[0,1,5,6,9,11],exodu:9,expir:[0,1,3,4,5,6],extens:[0,1],fa33f4d996844a5c73ecd1ae24456ab8:0,fals:[0,1,4,6],farest:[3,8],featur:9,fetch:10,file:[0,1,7,8,9,10,11],filter:[7,8],first:1,first_nam:[1,6],fittracke:10,fix:9,flask:10,flaticon:10,follow:[3,10],forbidden:0,forecast:10,form:[0,1],format:[0,1,5],former:10,forrunn:9,found:[0,1,4,5,6],frame:5,freepik:10,fri:0,from:[0,3,4,5,6,9,10],gener:10,get:[0,1,3,4,5,6],gif:1,git:10,github:10,gmt:[0,1,3,6],gpl:9,gpx:[0,7,8,9,10],gpxpy:10,have:0,header:[0,1,3,4,5,6],health:6,hike:[4,8],his:8,http:[0,1,3,4,5,6,10,11],icon:10,imag:[0,1,6,10],img:4,improv:9,incorrect:7,info:1,inform:9,initi:[10,11],instal:9,integ:[0,3,4,5,6],intern:[0,1],invalid:[0,1,3,4,5,6],issu:[9,10],jan:0,javascript:10,jpeg:6,jpg:1,json:[0,1,3,4,5,6,12],jul:[0,1,3,6],keep:9,kei:[8,10],label:4,last:[1,10],last_nam:[1,6],leaflet:[0,10],least:0,line:12,linux:10,list:9,local:9,localhost:[10,11],locat:[1,6],log:[0,1,3,4,5,6,9,10],login:[1,10],logout:1,longest:[3,8],made:[10,11],mai:10,make:10,makefil:[10,11],mandatori:[0,10],map:[0,8,9,10],map_id:0,match:1,max:0,max_alt:0,max_spe:0,max_speed_from:0,max_speed_to:0,maxim:0,maximum:[3,8],mean:11,messag:[0,1,6],min_alt:0,minim:[0,9],mobil:9,modification_d:0,mon:0,mondai:5,montain:8,month:[5,7,8],more:9,morn:0,mountain:4,move:[0,7],mpwoadmin:10,multipart:[0,1],must:[1,8],name:1,nb_activ:[1,5,6],nb_sport:[1,6],necessari:10,need:10,network:11,next_act:0,no_gpx:0,note:[0,7,8],now:[8,10],number:0,oauth:[0,1,3,4,5,6],object:[0,1],one:0,onli:[0,8],open:[9,10],order:0,other:10,out:1,outdoor:9,own:9,owner:8,packag:10,page:0,pagin:0,paramet:[0,1,3,4,5,6],pari:[1,6],pars:[10,12],part:[0,1],password:[1,10],password_conf:1,past:10,patch:0,paus:[0,7],payload:[0,1],per:0,per_pag:0,permiss:0,pictur:[1,6],ping:6,pleas:[0,1,3,4,5,6],png:[0,1,4],pong:6,possibl:9,post:[0,1],postgresql:10,prerequisit:9,previous_act:0,privai:9,product:9,profil:1,proprietari:9,provid:[0,1,3,4,5,6,8],python:10,queri:[0,5],react:10,react_app_api_url:11,readi:9,rebuild:11,rechart:[0,10],record:[0,2,7,8,9],record_typ:[0,3],redux:10,regist:[1,10],registr:1,relat:10,releas:[7,10],repo:10,report:9,request:[0,1,3,4,5,6,11],requir:1,respons:[0,1,3,4,5,6],run:[4,8,10],runner:9,sam:[1,6],samr1:10,sat:6,search:7,second:0,see:[8,9,10,11],segment:[0,7],select:[0,1],serv:10,server:[0,1,9,10],sever:9,signatur:[0,1,3,4,5,6],singl:6,sky:10,some:[0,7,10],sorri:1,sort:0,speed:[0,3,8,10],sport:[0,2,5,8,9,10],sport_id:[0,3,4,5],standard:8,start:[0,5,10],stat:[5,7],staticmap:10,statist:[2,9],statu:[0,1,3,4,5,6],step:10,still:9,store:9,street:9,string:[0,1,5],success:[0,1,3,4,5,6],successfulli:1,sun:[0,1,3,6],sundai:[0,5],support:[7,8],system:10,tab:11,tar:10,test:10,them:9,thi:[0,7,9,10],thunderforest:10,time:[0,1,5,8],timezon:[1,6,7],titl:0,todo:[10,13],token:[0,1,3,4,5,6],tooltip:7,total:7,total_dist:[1,5,6],total_dur:[1,5,6],track:9,tracker:9,transport:[4,8],troubleshoot:9,type:[0,1,3,4,5,6],unauthor:[0,1,3,4,5,6],undefin:11,under:9,unexpect:12,updat:[0,1,7,10],upgrad:9,upload:[7,8],user:[0,1,2,3,4,5,7,8,9,12],user_id:[0,3,5,6],usernam:[1,6],using:[0,9],valid:[0,1,3,4,5,6],valu:[0,3,10],variabl:11,version:9,view:7,virtualenv:10,walk:[4,8],weather:[7,8,10],weather_end:0,weather_start:0,web:[0,1,3,4,5,6,9],week:5,weekm:5,were:7,wget:10,when:7,with_gpx:0,without:[0,5,8,9],workout:9,written:10,www:10,xzf:10,yarn:10,year:5,yet:9,you:[0,9],your:9,zip:0,zone:1},titles:["Activities","Authentication","API documentation","Records","Sports","Statistics","Users","Change log","Features","FitTrackee","Installation","Administrator","Troubleshooting","User"],titleterms:{"new":7,activ:[0,8],administr:11,api:2,authent:1,bug:7,chang:7,charact:11,close:7,column:11,content:9,dashboard:8,data:11,detail:8,dev:10,document:2,environ:10,featur:[7,8],fittracke:9,fix:7,improv:7,instal:10,issu:7,json:11,line:11,list:8,log:7,minim:7,misc:7,pars:11,prerequisit:10,prod:10,record:3,sport:4,statist:[5,7,8],tabl:9,troubleshoot:12,unexpect:11,upgrad:10,user:[6,13],version:7,workout:8}}) \ No newline at end of file diff --git a/docsrc/source/api/records.rst b/docsrc/source/api/records.rst index fe42bf73..c78be7c4 100644 --- a/docsrc/source/api/records.rst +++ b/docsrc/source/api/records.rst @@ -1,8 +1,6 @@ Records ####### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: records.get_records diff --git a/docsrc/source/api/sports.rst b/docsrc/source/api/sports.rst index 3147efa7..078a5397 100644 --- a/docsrc/source/api/sports.rst +++ b/docsrc/source/api/sports.rst @@ -1,12 +1,7 @@ Sports ###### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: sports.get_sports, - sports.get_sport, - sports.post_sport, - sports.update_sport, - sports.delete_sport + sports.get_sport diff --git a/docsrc/source/api/stats.rst b/docsrc/source/api/stats.rst index d802fa3b..0621d298 100644 --- a/docsrc/source/api/stats.rst +++ b/docsrc/source/api/stats.rst @@ -1,8 +1,6 @@ Statistics ########## -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: stats.get_activities_by_sport, diff --git a/docsrc/source/api/users.rst b/docsrc/source/api/users.rst index 3fc1be80..09785889 100644 --- a/docsrc/source/api/users.rst +++ b/docsrc/source/api/users.rst @@ -1,8 +1,6 @@ Users ##### -work in progress - .. autoflask:: fittrackee_api:create_app() :endpoints: users.get_users, diff --git a/fittrackee_api/fittrackee_api/activities/activities.py b/fittrackee_api/fittrackee_api/activities/activities.py index 30bc7841..74ac4733 100644 --- a/fittrackee_api/fittrackee_api/activities/activities.py +++ b/fittrackee_api/fittrackee_api/activities/activities.py @@ -137,7 +137,7 @@ def get_activities(auth_user_id): "status": "success" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :query integer page: page if using pagination (default: 1) :query integer per_page: number of activities per page (default: 5) @@ -157,7 +157,10 @@ def get_activities(auth_user_id): :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success - :statuscode 401: invalid token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 500: """ @@ -302,13 +305,16 @@ def get_activity(auth_user_id, activity_id): "status": "not found" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer activity_id: activity id :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success - :statuscode 401: Provide a valid auth token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 403: You do not have permissions :statuscode 404: activity not found @@ -416,14 +422,17 @@ def get_activity_gpx(auth_user_id, activity_id): "status": "success" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer activity_id: activity id :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success :statuscode 400: no gpx file for this activity - :statuscode 401: invalid token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 404: activity not found :statuscode 500: @@ -476,14 +485,17 @@ def get_activity_chart_data(auth_user_id, activity_id): "status": "success" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer activity_id: activity id :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success :statuscode 400: no gpx file for this activity - :statuscode 401: invalid token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 404: activity not found :statuscode 500: @@ -511,13 +523,13 @@ def get_map(map_id): HTTP/1.1 200 OK Content-Type: image/png - :param integer auth_user_id: authenticate user id :param string map_id: activity map id - :reqheader Authorization: OAuth 2.0 Bearer Token - :statuscode 200: success - :statuscode 401: invalid token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 404: map does not exist :statuscode 500: @@ -636,7 +648,7 @@ def post_activity(auth_user_id): "status": "success" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :form file: gpx file (allowed extensions: .gpx, .zip) :form data: sport id and notes (example: ``{"sport_id": 1, "notes": ""}``) @@ -649,7 +661,10 @@ def post_activity(auth_user_id): - No file part. - No selected file. - File extension not allowed. - :statuscode 401: invalid token + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 500: """ @@ -721,7 +736,7 @@ def post_activity_no_gpx(auth_user_id): .. sourcecode:: http - POST /api/activities/ HTTP/1.1 + POST /api/activities/no_gpx HTTP/1.1 Content-Type: application/json **Example response**: @@ -805,7 +820,7 @@ def post_activity_no_gpx(auth_user_id): "status": "success" } - :param integer auth_user_id: authenticate user id + :param integer auth_user_id: authenticate user id (from JSON Web Token) :', methods=['GET']) @authenticate def get_sport(auth_user_id, sport_id): - """Get a sport""" + """Get a sport + + **Example request**: + + .. sourcecode:: http + + GET /api/sports/1 HTTP/1.1 + Content-Type: application/json + + **Example response**: + + - success + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "sports": [ + { + "_can_be_deleted": false, + "id": 1, + "img": "/img/sports/cycling-sport.png", + "label": "Cycling (Sport)" + } + ] + }, + "status": "success" + } + + - sport not found + + .. sourcecode:: http + + HTTP/1.1 404 NOT FOUND + Content-Type: application/json + + { + "data": { + "sports": [] + }, + "status": "not found" + } + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + :param integer sport_id: sport id + + :reqheader Authorization: OAuth 2.0 Bearer Token + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + :statuscode 404: sport not found + + """ + sport = Sport.query.filter_by(id=sport_id).first() if sport: response_object = { @@ -46,6 +177,8 @@ def get_sport(auth_user_id, sport_id): return jsonify(response_object), code +# no administration - no documentation for now + @sports_blueprint.route('/sports', methods=['POST']) @authenticate_as_admin def post_sport(auth_user_id): diff --git a/fittrackee_api/fittrackee_api/activities/stats.py b/fittrackee_api/fittrackee_api/activities/stats.py index 2555a1cd..9a5a1b7e 100644 --- a/fittrackee_api/fittrackee_api/activities/stats.py +++ b/fittrackee_api/fittrackee_api/activities/stats.py @@ -130,12 +130,180 @@ def get_activities(user_id, filter_type): @stats_blueprint.route('/stats//by_time', methods=['GET']) @authenticate def get_activities_by_time(auth_user_id, user_id): - """Get activities statistics for a user by time""" + """ + Get activities statistics for a user by time + + **Example requests**: + + - without parameters + + .. sourcecode:: http + + GET /api/stats/1/by_time HTTP/1.1 + + - with parameters + + .. sourcecode:: http + + GET /api/stats/1/by_time?from=2018-01-01&to=2018-06-30&time=week HTTP/1.1 + + **Example responses**: + + - success + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "statistics": { + "2017": { + "3": { + "nb_activities": 2, + "total_distance": 15.282, + "total_duration": 12341 + } + }, + "2019": { + "1": { + "nb_activities": 3, + "total_distance": 47, + "total_duration": 9960 + }, + "2": { + "nb_activities": 1, + "total_distance": 5.613, + "total_duration": 1267 + } + } + } + }, + "status": "success" + } + + - no activities + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "statistics": {} + }, + "status": "success" + } + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + :param integer user_id: user id + + :query string from: start date (format: ``%Y-%m-%d``) + :query string to: end date (format: ``%Y-%m-%d``) + :query string time: time frame: + + - ``week``: week starting Sunday + - ``weekm``: week starting Monday + - ``month``: month + - ``year``: year (default) + + :reqheader Authorization: OAuth 2.0 Bearer Token + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + :statuscode 404: + - User does not exist. + + """ return get_activities(user_id, 'by_time') @stats_blueprint.route('/stats//by_sport', methods=['GET']) @authenticate def get_activities_by_sport(auth_user_id, user_id): - """Get activities statistics for a user by sport""" + """ + Get activities statistics for a user by sport + + **Example requests**: + + - without parameters (get stats for all sports with activities) + + .. sourcecode:: http + + GET /api/stats/1/by_sport HTTP/1.1 + + - with sport id + + .. sourcecode:: http + + GET /api/stats/1/by_sport?sport_id=1 HTTP/1.1 + + **Example responses**: + + - success + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "statistics": { + "1": { + "nb_activities": 3, + "total_distance": 47, + "total_duration": 9960 + }, + "2": { + "nb_activities": 1, + "total_distance": 5.613, + "total_duration": 1267 + }, + "3": { + "nb_activities": 2, + "total_distance": 15.282, + "total_duration": 12341 + } + } + }, + "status": "success" + } + + - no activities + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "statistics": {} + }, + "status": "success" + } + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + :param integer user_id: user id + + :query integer sport_id: sport id + + :reqheader Authorization: OAuth 2.0 Bearer Token + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + :statuscode 404: + - User does not exist. + - Sport does not exist. + + """ return get_activities(user_id, 'by_sport') diff --git a/fittrackee_api/fittrackee_api/tests/test_users_api.py b/fittrackee_api/fittrackee_api/tests/test_users_api.py index 55d3cbbb..43f8b12f 100644 --- a/fittrackee_api/fittrackee_api/tests/test_users_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_users_api.py @@ -16,8 +16,23 @@ def test_ping(app): def test_single_user(app, user_1): """=> Get single user details""" client = app.test_client() - - response = client.get(f'/api/users/{user_1.id}') + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + f'/api/users/{user_1.id}', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) data = json.loads(response.data.decode()) assert response.status_code == 200 @@ -45,8 +60,23 @@ def test_single_user_with_activities( ): """=> Get single user details""" client = app.test_client() - - response = client.get(f'/api/users/{user_1.id}') + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + f'/api/users/{user_1.id}', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) data = json.loads(response.data.decode()) assert response.status_code == 200 @@ -68,33 +98,80 @@ def test_single_user_with_activities( assert data['data']['total_duration'] == '1:57:04' -def test_single_user_no_id(app): +def test_single_user_no_id(app, user_1): """=> Ensure error is thrown if an id is not provided.""" client = app.test_client() - response = client.get(f'/api/users/blah') + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/users/blah', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) data = json.loads(response.data.decode()) assert response.status_code == 404 assert 'fail' in data['status'] - assert 'User does not exist' in data['message'] + assert 'User does not exist.' in data['message'] -def test_single_user_wrong_id(app): +def test_single_user_wrong_id(app, user_1): """=> Ensure error is thrown if the id does not exist.""" client = app.test_client() - response = client.get(f'/api/users/99999999999') + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/users/99999999999', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) data = json.loads(response.data.decode()) assert response.status_code == 404 assert 'fail' in data['status'] - assert 'User does not exist' in data['message'] + assert 'User does not exist.' in data['message'] def test_users_list(app, user_1, user_2): """=> Ensure get single user behaves correctly.""" client = app.test_client() - response = client.get('/api/users') + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/users', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) data = json.loads(response.data.decode()) assert response.status_code == 200 @@ -129,3 +206,53 @@ def test_decode_auth_token(app, user_1): auth_token = user_1.encode_auth_token(user_1.id) assert isinstance(auth_token, bytes) assert User.decode_auth_token(auth_token) == user_1.id + + +def test_user_no_picture(app, user_1): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/users/1/picture', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'No picture.' in data['message'] + + +def test_user_picture_no_user(app, user_1): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/users/2/picture', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 404 + assert 'fail' in data['status'] + assert 'User does not exist.' in data['message'] diff --git a/fittrackee_api/fittrackee_api/users/auth.py b/fittrackee_api/fittrackee_api/users/auth.py index b84b608b..125ee871 100644 --- a/fittrackee_api/fittrackee_api/users/auth.py +++ b/fittrackee_api/fittrackee_api/users/auth.py @@ -22,7 +22,7 @@ def register_user(): .. sourcecode:: http - POST /auth/register HTTP/1.1 + POST /api/auth/register HTTP/1.1 Content-Type: application/json **Example responses**: @@ -153,7 +153,7 @@ def login_user(): .. sourcecode:: http - POST /auth/login HTTP/1.1 + POST /api/auth/login HTTP/1.1 Content-Type: application/json **Example responses**: @@ -240,7 +240,7 @@ def logout_user(user_id): .. sourcecode:: http - GET /auth/logout HTTP/1.1 + GET /api/auth/logout HTTP/1.1 Content-Type: application/json **Example responses**: @@ -310,7 +310,7 @@ def get_user_status(user_id): .. sourcecode:: http - GET /auth/profile HTTP/1.1 + GET /api/auth/profile HTTP/1.1 Content-Type: application/json **Example response**: @@ -345,7 +345,10 @@ def get_user_status(user_id): :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success. - :statuscode 401: Provide a valid auth token. + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. """ user = User.query.filter_by(id=user_id).first() @@ -366,7 +369,7 @@ def edit_user(user_id): .. sourcecode:: http - POST /auth/profile/edit HTTP/1.1 + POST /api/auth/profile/edit HTTP/1.1 Content-Type: application/json **Example response**: @@ -413,7 +416,10 @@ def edit_user(user_id): :statuscode 400: - Invalid payload. - Password and password confirmation don't match. - :statuscode 401: Provide a valid auth token. + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 500: Error. Please try again or contact the administrator. """ @@ -489,7 +495,7 @@ def edit_picture(user_id): .. sourcecode:: http - POST /auth/picture HTTP/1.1 + POST /api/auth/picture HTTP/1.1 Content-Type: multipart/form-data **Example response**: @@ -531,7 +537,10 @@ def edit_picture(user_id): - No file part. - No selected file. - File extension not allowed. - :statuscode 401: Provide a valid auth token. + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 500: Error during picture update. """ @@ -592,7 +601,7 @@ def del_picture(user_id): .. sourcecode:: http - DELETE /auth/picture HTTP/1.1 + DELETE /api/auth/picture HTTP/1.1 Content-Type: application/json **Example response**: @@ -605,7 +614,10 @@ def del_picture(user_id): :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 204: picture deleted - :statuscode 401: Provide a valid auth token. + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. :statuscode 500: Error during picture deletion. """ diff --git a/fittrackee_api/fittrackee_api/users/users.py b/fittrackee_api/fittrackee_api/users/users.py index 45b5365e..4797c10b 100644 --- a/fittrackee_api/fittrackee_api/users/users.py +++ b/fittrackee_api/fittrackee_api/users/users.py @@ -2,13 +2,86 @@ from flask import Blueprint, jsonify, send_file from ..activities.utils_files import get_absolute_file_path from .models import User +from .utils import authenticate users_blueprint = Blueprint('users', __name__) @users_blueprint.route('/users', methods=['GET']) -def get_users(): - """Get all users""" +@authenticate +def get_users(auth_user_id): + """ + Get all users + + **Example request**: + + .. sourcecode:: http + + GET /api/users HTTP/1.1 + Content-Type: application/json + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "users": [ + { + "admin": true, + "bio": null, + "birth_date": null, + "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", + "email": "admin@example.com", + "first_name": null, + "id": 1, + "last_name": null, + "location": null, + "nb_activities": 6, + "nb_sports": 3, + "picture": false, + "timezone": "Europe/Paris", + "total_distance": 67.895, + "total_duration": "6:50:27", + "username": "admin" + }, + { + "admin": false, + "bio": null, + "birth_date": null, + "created_at": "Sat, 20 Jul 2019 11:27:03 GMT", + "email": "sam@example.com", + "first_name": null, + "id": 2, + "last_name": null, + "location": null, + "nb_activities": 0, + "nb_sports": 0, + "picture": false, + "timezone": "Europe/Paris", + "total_distance": 0, + "total_duration": "0:00:00", + "username": "sam" + } + ] + }, + "status": "success" + } + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + + :reqheader Authorization: OAuth 2.0 Bearer Token + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + + """ users = User.query.all() response_object = { 'status': 'success', @@ -20,11 +93,64 @@ def get_users(): @users_blueprint.route('/users/', methods=['GET']) -def get_single_user(user_id): - """Get single user details""" +@authenticate +def get_single_user(auth_user_id, user_id): + """ + Get single user details + + **Example request**: + + .. sourcecode:: http + + GET /api/users/1 HTTP/1.1 + Content-Type: application/json + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "admin": true, + "bio": null, + "birth_date": null, + "created_at": "Sun, 14 Jul 2019 14:09:58 GMT", + "email": "admin@example.com", + "first_name": null, + "id": 1, + "last_name": null, + "location": null, + "nb_activities": 6, + "nb_sports": 3, + "picture": false, + "timezone": "Europe/Paris", + "total_distance": 67.895, + "total_duration": "6:50:27", + "username": "admin" + }, + "status": "success" + } + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + :param integer user_id: user id + + :reqheader Authorization: OAuth 2.0 Bearer Token + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + :statuscode 404: + - User does not exist + """ + response_object = { 'status': 'fail', - 'message': 'User does not exist' + 'message': 'User does not exist.' } try: user = User.query.filter_by(id=int(user_id)).first() @@ -41,26 +167,83 @@ def get_single_user(user_id): @users_blueprint.route('/users//picture', methods=['GET']) -def get_picture(user_id): - """ get user picture """ +@authenticate +def get_picture(auth_user_id, user_id): + """ get user picture + + **Example request**: + + .. sourcecode:: http + + GET /api/users/1/picture HTTP/1.1 + Content-Type: application/json + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: image/jpeg + + :param integer auth_user_id: authenticate user id (from JSON Web Token) + :param integer user_id: user id + + :statuscode 200: success + :statuscode 401: + - Provide a valid auth token. + - Signature expired. Please log in again. + - Invalid token. Please log in again. + :statuscode 404: + - User does not exist + - No picture. + + """ response_object = { - 'status': 'fail', - 'message': 'User does not exist' + 'status': 'not found', + 'message': 'No picture.' } try: user = User.query.filter_by(id=int(user_id)).first() if not user: + response_object = { + 'status': 'fail', + 'message': 'User does not exist.' + } return jsonify(response_object), 404 - else: + if user.picture is not None: picture_path = get_absolute_file_path(user.picture) return send_file(picture_path) - except ValueError: + return jsonify(response_object), 404 + except Exception: return jsonify(response_object), 404 @users_blueprint.route('/ping', methods=['GET']) def ping_pong(): - """ health check endpoint """ + """ health check endpoint + + **Example request**: + + .. sourcecode:: http + + GET /api/ping HTTP/1.1 + Content-Type: application/json + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "message": "pong!", + "status": "success" + } + + :statuscode 200: success + + """ return jsonify({ 'status': 'success', 'message': 'pong!'