{
  "num_results": 41,
  "objects": [
    {
      "association_proxies": [
        {
          "model": "tag",
          "name": "tags",
          "target_collection": "annotation_tags"
        }
      ],
      "collection": "annotation",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foreign key `id` for related [label](#label) (or class label)",
          "foreign_key": "label.id",
          "name": "label_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "1.0",
          "doc": "(Optional) likelihood/probability of the label assignment",
          "foreign_key": null,
          "name": "likelihood",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not this annotation requires review",
          "foreign_key": null,
          "name": "needs_review",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Creation time (UTC)",
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foriegn key `id` for owner [user](#user) object",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foriegn key `id` for [point](#point) object",
          "foreign_key": "point.id",
          "name": "point_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foriegn key `id` for [annotation_set](#annotation_set) object",
          "foreign_key": "annotation_set.id",
          "name": "annotation_set_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "User comment",
          "foreign_key": null,
          "name": "comment",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "`id` of parent [annotation](#annotation) for group of linked observations",
          "foreign_key": "annotation.id",
          "name": "parent_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Annotation resource. Links [label](#label) objects to [point](#point) objects.\n    Also stores comments, [tag](#tag) associations, review flags, probability estimates, linked observations, etc...\n    ",
      "endpoints": [
        {
          "description": "Create new [annotation](#annotation) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/annotation",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [annotation](#annotation) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/annotation",
          "fields": [
            "id",
            "created_at",
            "updated_at",
            "annotation_set_id",
            "data",
            "label",
            "label.id",
            "label.name",
            "label.uuid",
            "label.parent_id",
            "label.label_scheme_id",
            "point",
            "point.media_id",
            "point.x",
            "point.y",
            "user",
            "user.id",
            "user.username",
            "point.t",
            "point.data",
            "point.annotation_set_id",
            "likelihood",
            "needs_review",
            "point.id",
            "tags",
            "tags.id",
            "tags.name",
            "comment",
            "timestamp",
            "parent_id",
            "color",
            "suggested_tags",
            "object_id",
            "label.lineage_names"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        Filter results based on permissions from parent [annotation_set](#annotation_set)\n        ",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [annotation](#annotation) object with pk field matching param `id`",
          "endpoint": "/api/annotation/<id>",
          "fields": [
            "id",
            "created_at",
            "updated_at",
            "annotation_set_id",
            "data",
            "label",
            "label.id",
            "label.name",
            "label.uuid",
            "label.parent_id",
            "label.label_scheme_id",
            "point",
            "point.media_id",
            "point.x",
            "point.y",
            "user",
            "user.id",
            "user.username",
            "point.t",
            "point.data",
            "point.annotation_set_id",
            "likelihood",
            "needs_review",
            "point.id",
            "tags",
            "tags.id",
            "tags.name",
            "comment",
            "timestamp",
            "parent_id",
            "color",
            "suggested_tags",
            "object_id",
            "label.lineage_names",
            "label_id",
            "point.updated_at",
            "observation_count",
            "linked_observations",
            "media",
            "version_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [annotation](#annotation) object with pk field matching param `id`",
          "endpoint": "/api/annotation/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Batch update [annotation](#annotation) objects. Set `q` in querystring to filter selected [annotations](#annotation) as\n        per [Making API search queries](#api_query). Returned results are pre-filtered for only the annotations that come from\n        [annotation_sets](#annotation_set) where `current_user_can_edit` is set to `true`. As a safety measure, there\n        is a limit of `200` annotations that can be updated in a single request.\n\n        **CAUTION**: this endpoint can batch update many annotations in a single request! If used incorrectly, you can\n        loose your annotations and any annotations that have been shared with you for which you have been granted edit\n        access. Please use with caution.\n        **TIP**: Test your search query (`q`) on a `GET` request first to see what is returned before updating.\n\n        PATCH request data must be JSON with the following fields:\n        ```{ \"label_id\": ..., \"tags\": [...], \"comment\": \"...\" }```\n        Where `label_id` is the `id` of the [label](#label) object that you would like to assign to the list of matched\n        [annotations](#annotation). Setting `label_id` to `false` will reset the label and any assigned tags.\n        `tags` is a list of `[tag.id](#tag)'s` and `comment` is a string that can be assigned to each annotation.\n\n        ```\n        # Example: batch change ALL annotations matching filter. Set label_id=7326 (\"Ecklonia radiata\") for all annotations in an annotation_set annotation_set_id=2171 annotated by user user_id=1 with a label matching label_id=7331 (\"Sargasm spp\")\n\n        # PATCH: (TIP first run as GET request to check filter before PATCHING)\n        /api/annotation?q={\"filters\": [{\"name\": \"annotation_set_id\", \"op\": \"eq\", \"val\": 2171}, {\"name\": \"label_id\", \"op\": \"eq\", \"val\": 7331}, {\"name\": \"user_id\", \"op\": \"eq\", \"val\": 1}]}\n\n        # JSON PATCH DATA:\n        { \"label_id\": 7326 }\n        ```\n        ",
          "endpoint": "/api/annotation",
          "method": "PATCH"
        },
        {
          "description": null,
          "endpoint": "/api/annotation/<int:id>",
          "method": "PATCH"
        },
        {
          "description": null,
          "endpoint": "/api/annotation/<int:annotation_id>/tag/<int:tag_id>",
          "method": "DELETE"
        },
        {
          "description": "Updates `parent_id` of annotation to group observations of the same object. If `link_id` points to a child annotation, the observation\n        will be linked to its `parent`.\n        An observation group is used to link observations of the same object that has been annotated multiple times.",
          "endpoint": "/api/annotation/<int:id>/link/<int:link_id>",
          "method": "PATCH"
        },
        {
          "description": "View all previous versions of this annotation, i.e.: a change log.",
          "endpoint": "/api/annotation/<int:id>/versions",
          "method": "GET"
        },
        {
          "description": "Unlink this annotation from the observation group. If it is a group parent, the first child will be set as the\n        new parent.\n        An observation group is used to link observations of the same object that has been annotated multiple times.",
          "endpoint": "/api/annotation/<int:id>/link",
          "method": "DELETE"
        },
        {
          "description": "Set this annotation as the parent of the observation group.\n        An observation group is used to link observations of the same object that has been annotated multiple times.",
          "endpoint": "/api/annotation/<int:id>/link",
          "method": "PATCH"
        },
        {
          "description": "\n        General [annotation](#annotation) export endpoint. This can export annotations across multiple\n        [annotation_sets](#annotation_set). However, this endpoint is limited to a maximum of 200,000 annotations\n        in any single query. You can export more in separate queries using a combination of `limit` and `offset`\n        parameters. To export a single `annotation_set` without limits, see the `export` endpoint in the\n        [annotation_set](annotation_set) resource.\n\n        \n        Export [annotations](#annotation) matching query define in `q`.\n        Search queries are executed on the [annotation](#annotation) model. This endpoint also supports translating\n        to a target `label_scheme` (when possible)\n\n        \n        Querystring parameters are:\n\n        ```?q={...}&f={...}&disposition=...&template=...&include_columns=[...]```\n\n        Where `q` is a JSON search query (see [Making API search queries](#api_query)) on the collection model,\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` defines the download type which can be `attachment` (default, triggers a download) or `inline` (displays in\n        the browser),\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `include_columns` is a JSON list of column fields for the exported model.\n        Nested fields for related models delimited with a `.`\n        If `include_columns` is omitted, all allowed columns will be returned.\n\n        Metadata for the dataset is also returned in the response. Depending on the output\n        format, this could be as part of the response body in a `metadata` field (e.g., Json) or in the response headers with the key\n        `X-Content-Metadata` (e.g., CSV or HTML).\n    \n\n        Allowed fields include:\n\n        `id`, `tag_names`, `comment`, `label.id`, `label.name`, `label.lineage_names`, `label.uuid`, `label.color`,\n        `supplementary_label`, `updated_at`, `object_id`, `parent_id`, `needs_review`, `likelihood`,`timestamp`,\n        `point.is_targeted`,`point.id`, `point.x`, `point.y`, `point.t`, `point.data`, `point.media.id`, `point.media.key`,\n        `point.polygon`, `annotation_set.id`, `annotation_set.name`, `media_collection.id`, `media_collection.name`,\n        `point.media.path_best`, `point.media.timestamp_start`, `point.media.timestamp_start_local`,\n        `point.media.path_best_thm`, `point.media.data`, `point.pose.timestamp`, `point.pose.timestamp_local`,\n        `point.pose.lat`, `point.pose.lon`, `point.pose.alt`, `point.pose.dep`, `point.pose.data`, `point.pose.id`,\n        `point.media.deployment.campaign.id`, `point.media.deployment.campaign.key`, `point.media.deployment.campaign.name`,\n        `point.media.deployment.platform.id`, `point.media.deployment.platform.key`, `point.media.deployment.platform.name`,\n        `user.username`,`user.full_name`, `user.affiliations_names`,\n        `point.media.deployment.key`, `point.media.deployment.id`, `point.media.deployment.name`,\n        `point.bbox`, `point.has_xy`, `point.has_polygon`, `point.pixels`\n\n        See [annotation](#annotation) model columns, relations and attributes for more information on each of the included fields.\n\n        **TRANSLATING TO OTHER LABEL_SCHEMES**\n\n        This endpoint also supports the translation of labels from a source to a target label_scheme.\n        another label_scheme using the semantic translation framework. In order to do this, you need to specify the\n        additional `translate` url query parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required. With translation parameters you will also need to specify additional columns in the `include_columns`\n        parameter to obtain the translation output.\n\n        Additional allowed columns include:\n\n        `label.translated.id`, `label.translated.name`, `label.translated.lineage_names`,\n        `label.translated.uuid`, `label.translated.translation_info`,\n\n        These columns are ignored if no `translate` query parameter is supplied.\n        \n\n        **EXAMPLES**\n\n        ```\n        # TODO\n        ```\n        ",
          "endpoint": "/api/annotation/export",
          "method": "GET"
        },
        {
          "description": "\n        Get a tally of [annotations](#annotation).\n\n        \n        The tally of [annotations](#annotation) can be grouped by different properties. `group_by` can be one of\n        [`month`,'year_collected', 'month_collected', `user`, `platform`, `campaign`, `deployment`, `label`,\n        `annotation_set`, `affiliation`^, `usergroup`^]. Set `q` in querystring to filter\n        selected [annotations](#annotation) as per [Making API search queries](#api_query). Note, the same query in `q`\n        can be applied to all `group_by` types to filter the list of [annotations](#annotation) that are included in the\n        tally. Results are also paginated with a default of `500` and a maximum on `5000` returned per page. This can be\n        controlled by setting the `results_per_page` parameter in the query string.\n        Returned results are pre-filtered to return only the annotations that have been labeled (`label_id != null`).\n        Also accepts a query string parameter `template` which formats the data using a predefined template. Some example\n        templates include: `data.html` which returns an HTML table, `json.html` which returns HTML-formatted JSON, `data.csv`\n        which returns a CSV file for download. If left blank, raw JSON will be returned.\n\n        ^ **NOTE**: the counts in the `affiliation` and `usergroup` tally should be interpreted with care.\n        If someone belongs to more than one group, then their annotations will contribute to both so they may be double\n        counted. The corollary of that is if someone has not linked themselves to an affiliation or group, then their\n        annotations will not be counted in the tally.\n\n        **TRANSLATING TO OTHER LABEL_SCHEMES**\n\n        When using `group_by=label` it is possible translate labels from a source to a target label_scheme using the\n        semantic translation framework. In order to do this, you need to specify the additional `translate` url query\n        parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required. When passing translation parameters, there will the following additional output columns:\n        `label_lineage_names`, `translated_id`, `translated_lineage_names`, `translated_name`,\n        `translated_label_scheme_name`, `translated_info`.\n        \n\n        **EXAMPLES**\n\n        ```\n        # Example: tally of annotations for top 500 most commonly used labels returned as an HTML table\n        /api/annotation/tally/label?template=data.html&results_per_page=500\n\n        # Example: tally of annotations for the top 1000 users returned as a CSV file\n        /api/annotation/tally/user?&results_per_page=1000&template=data.csv\n\n        # Example: tally of annotations for the top 20 affiliations returned as an HTML table\n        /api/annotation/tally/affiliation?&results_per_page=20&template=data.html\n\n        # Example: tally of annotations by the top 200 usergroups returned as an HTML table\n        /api/annotation/tally/usergroup?&template=data.html&results_per_page=200\n\n        # Example: tally of annotations by month between 2020-01-01 and 2021-01-01 returned as an HTML table\n        /api/annotation/tally/month?q={\"filters\": [{\"name\":\"updated_at\",\"op\":\"gt\",\"val\":\"2020-01-01\"}, {\"name\":\"updated_at\",\"op\":\"lt\",\"val\":\"2021-01-01\"}] }&template=data.html\n\n        # Example: tally of annotations by platform returned as raw JSON\n        /api/annotation/tally/platform\n\n        # Example: tally of annotations by campaign returned as a HTML-formatted JSON\n        /api/annotation/tally/campaign?&template=json.html\n\n        # Example: tally of annotations for top 2000 deployments returned as an HTML table\n        /api/annotation/tally/deployment?&template=data.html&results_per_page=2000\n\n        # Example: tally annotations by deployment filtered by annotation_set.usergroup with ID=63 returned as an HTML table\n        /api/annotation/tally/deployment?&results_per_page=2000&template=data.html&q={\"filters\": [{\"name\":\"annotation_set\",\"op\":\"has\",\"val\": {\"name\":\"usergroups\",\"op\":\"any\",\"val\": {\"name\":\"id\",\"op\":\"eq\",\"val\":63}}}]}\n\n        # Example: tally of annotations for the top 20 users for platform(s) containing \"IMOS\" in their name that were labeled during the year 2020. Return the result as an HTML table using the template \"data.html\", GET:\n        /api/annotation/tally/user?q={\"filters\": [{\"name\":\"point\",\"op\":\"has\",\"val\": {\"name\":\"media\",\"op\":\"has\",\"val\": {\"name\":\"deployment\",\"op\":\"has\",\"val\": {\"name\":\"platform\",\"op\":\"has\",\"val\": {\"name\":\"name\",\"op\":\"ilike\",\"val\":\"%IMOS%\"}}}}}, {\"name\":\"created_at\",\"op\":\"gt\",\"val\":\"2020-01-01\"}, {\"name\":\"created_at\",\"op\":\"lt\",\"val\":\"2021-01-01\"}] }&results_per_page=20&template=data.html\n\n        # Example: tally of annotations by top 100 labels for a give deployment (id=10306) returned as an HTML table\n        # Translated into the catami annotation scheme (id=2) using the \"caab\" and \"worms\" vocab_registries (only works with compatible schemas)\n        /api/annotation/tally/label?q={\"filters\":[{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"media\",\"op\":\"has\",\"val\":{\"name\":\"deployment_id\",\"op\":\"eq\",\"val\":10306}}}]}&results_per_page=100&unannotated_point_count=294&translate={\"vocab_registry_keys\":[\"caab\",\"worms\"],\"target_label_scheme_id\":\"2\"}&template=data.html\n\n        # Example: tally annotations by label in a deployment matching the key \"r20200131_021337_NG02_middleton_22\", filtered for occurrences between 20-30m, showing only primary observation (no linked children, i.e. only count an observation group/object once)\n        /api/annotation/tally/label?q={\"filters\":[{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"media\",\"op\":\"has\",\"val\":{\"name\":\"deployment\",\"op\":\"has\",\"val\":{\"name\":\"key\",\"op\":\"eq\",\"val\":\"r20200131_021337_NG02_middleton_22\"}}}},{\"name\":\"point\",\"op\":\"has\",\"val\": {\"name\":\"media\",\"op\":\"has\",\"val\": {\"name\":\"poses\",\"op\":\"any\",\"val\": {\"name\":\"dep\",\"op\":\"gt\",\"val\":20}}}},{\"name\":\"point\",\"op\":\"has\",\"val\": {\"name\":\"media\",\"op\":\"has\",\"val\": {\"name\":\"poses\",\"op\":\"any\",\"val\": {\"name\":\"dep\",\"op\":\"lt\",\"val\":30}}}},{\"name\":\"is_child\",\"op\":\"eq\",\"val\":false}]}\n        ```\n        ",
          "endpoint": "/api/annotation/tally/<group_by>",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "\n        BOOLEAN, whether or not this annotation has a linked parent annotation\n        (queryable)\n        ",
          "name": "is_child",
          "type": "property"
        },
        {
          "args": [],
          "doc": "The in-situ timestamp for when the annotated object was captured/sampled in the media frame.\n        Returns `media.timestamp_start + point.t` if `point.t` is set, otherwise it just\n        returns `media.timestamp_start` ",
          "name": "timestamp",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set flagged as QA/QC complete",
          "name": "is_qaqc",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set flagged as final",
          "name": "is_final",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set flagged as full bio score (instead of only specific targets species)",
          "name": "is_full_bio_score",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set flagged as real science",
          "name": "is_real_science",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set flagged as supplementary",
          "name": "is_supplementary",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation is from an annotation_set that is released publicly",
          "name": "is_public",
          "type": "property"
        },
        {
          "args": [
            "ts"
          ],
          "doc": "Absolute difference in seconds of the in-situ timestamp and input `ts`, which is datetime string\n        eg: `\"2020-09-25T00:57:11.945009\"` (or in a format that is parsable by `dateutil.parser.parse`)",
          "name": "timestamp_proximity",
          "type": "method"
        },
        {
          "args": [
            "lat",
            "lon"
          ],
          "doc": "FLOAT, distance (in meters) of closest linked [pose](#pose) relative to `lat` and `lon` (which are both in decimal degrees)",
          "name": "distance",
          "type": "method"
        },
        {
          "args": [
            "x",
            "y"
          ],
          "doc": "FLOAT, euclidean distance to `x` and `y` (which are proportions of the image width and height)",
          "name": "xy_distance",
          "type": "method"
        },
        {
          "args": [
            "label_id",
            "include_synonyms",
            "include_descendants"
          ],
          "doc": "\n        BOOLEAN. True if this annotation's label matches the provided `label_id`,\n        or any synonymous labels linked via `vocab_elements`. If `include_descendants`\n        is True, all descendant labels (children at any depth) of the matching set\n        are also considered matches.\n\n        Usage via API (examples):\n\n        - Match direct label only:\n          `{\"name\":{\"method\":\"matches_label\",\"kwargs\":{\"label_id\":123,\"include_synonyms\":false}},\"op\":\"eq\",\"val\":true}`\n        - Match label and synonyms:\n          `{\"name\":{\"method\":\"matches_label\",\"kwargs\":{\"label_id\":123,\"include_synonyms\":true}},\"op\":\"==\",\"val\":true}`\n        - Match label, synonyms and all descendants:\n          `{\"name\":{\"method\":\"matches_label\",\"kwargs\":{\"label_id\":123,\"include_synonyms\":true,\"include_descendants\":true}},\"op\":\"eq\",\"val\":true}`\n        ",
          "name": "matches_label",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": "Implied color code for this annotation based on [label](#label) assignment",
          "name": "color",
          "type": "method"
        },
        {
          "doc": "BOOLEAN, whether or not the current user has edit rights for this annotation as implied by the permissions of the parent [annotation_set](#annotation_set)",
          "name": "current_user_can_edit",
          "type": "method"
        },
        {
          "doc": "\n        INT, denoting the number of linked observations of this object\n        ",
          "name": "observation_count",
          "type": "method"
        },
        {
          "doc": "Properties for related [pose](#pose) item excluding [posedata](#posedata) fields",
          "name": "pose",
          "type": "method"
        },
        {
          "doc": "Properties for related [pose](#pose) item including any linked [posedata](#posedata) fields",
          "name": "pose_data",
          "type": "method"
        },
        {
          "doc": "List of suggested [tag](#tag) implied from [label](#label) definition",
          "name": "suggested_tags",
          "type": "method"
        },
        {
          "doc": "INT, denoting the number of changes in the version history of this object",
          "name": "version_count",
          "type": "method"
        },
        {
          "doc": "List of [annotation](#annotation) objects (as dicts) linked with the same `object_id`",
          "name": "linked_observations",
          "type": "property"
        },
        {
          "doc": "[media](#media) object information for this [annotation](#annotation) via `point.media` link",
          "name": "media",
          "type": "property"
        },
        {
          "doc": "\n        ID of observation group: ID of primary observation (parent annotation) if linked, otherwise own ID.\n        ",
          "name": "object_id",
          "type": "property"
        },
        {
          "doc": "Selected fiedls of supplementary labels for relates [point](#point). Returns `id`, `likelihood`, `name`,\n        `lineage_names`, `username`. Can optionally filter through URL param: `supplementary_annotation_set_id`, which\n        will filter for specific supplementary annotation_set. If not supplied will return all.",
          "name": "supplementary_label",
          "type": "property"
        },
        {
          "doc": "Comma-delimited names of applied tags. Can also be used to set tags using comma-delimited tags when creating annotaions",
          "name": "tag_names",
          "type": "property"
        },
        {
          "doc": "\n        Returns `id` of `label.translated` for [label](#label) if defined and if a match is found, otherwise  `None`.\n        ",
          "name": "translated_label_id",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Related [label](#label) object",
          "key": "label",
          "model": "label"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related owner [user](#user) object",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related [point](#point) object",
          "key": "point",
          "model": "point"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related [annotation_set](#annotation_set) object",
          "key": "annotation_set",
          "model": "annotation_set"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Parent annotation in a linked set of observations",
          "key": "parent",
          "model": "annotation"
        },
        {
          "direction": "ONETOMANY",
          "doc": "Collection of linked child observations",
          "key": "children",
          "model": "annotation"
        },
        {
          "direction": "ONETOMANY",
          "doc": "Collection of [annotation_tags](#annotation_tags) associations",
          "key": "annotation_tags",
          "model": "annotation_tags"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "versions",
          "model": "annotation_version"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "annotation_set",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media_collection.id",
          "name": "media_collection_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "label_scheme.id",
          "name": "label_scheme_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foreign key reference for ID of related owner [users](#users) model",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "annotation_set.id",
          "name": "parent_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "is_exemplar",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": "whether or not the intent was full biodiversity scoring, or just targeted scoring",
          "foreign_key": null,
          "name": "is_full_bio_score",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": "whether or not this is for science, or was for education / training / testing",
          "foreign_key": null,
          "name": "is_real_science",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "whether or not the annotation set has been QA/QC'd",
          "foreign_key": null,
          "name": "is_qaqc",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "whether or not the annotator has completed annotating",
          "foreign_key": null,
          "name": "is_final",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "base",
          "doc": null,
          "foreign_key": null,
          "name": "type",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        }
      ],
      "description": "\n    Annotation Set resource: defines how the [media](#media) objects contained in a [media_collection](#media_collection) should be annotated /\n    analysed. Each [media_collection](#media_collection) can have multiple [annotation_sets](#annotation_set) attached to it.\n    ",
      "endpoints": [
        {
          "description": "Create new [annotation_set](#annotation_set) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/annotation_set",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [annotation_set](#annotation_set) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/annotation_set/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": null,
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [annotation_set](#annotation_set) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/annotation_set",
          "fields": [
            "id",
            "name",
            "parent_id",
            "description",
            "user",
            "user.id",
            "user.username",
            "user.first_name",
            "user.last_name",
            "created_at",
            "children",
            "media_collection",
            "media_collection.id",
            "media_collection.name",
            "media_collection.current_user_can_view",
            "label_scheme",
            "label_scheme.id",
            "label_scheme.name",
            "data",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "is_exemplar",
            "is_full_bio_score",
            "is_real_science",
            "is_qaqc",
            "is_final",
            "annotation_count",
            "usergroup_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [annotation_set](#annotation_set) object with pk field matching param `id`",
          "endpoint": "/api/annotation_set/<id>",
          "fields": [
            "id",
            "name",
            "parent_id",
            "description",
            "user",
            "user.id",
            "user.username",
            "user.first_name",
            "user.last_name",
            "created_at",
            "children",
            "media_collection",
            "media_collection.id",
            "media_collection.name",
            "media_collection.current_user_can_view",
            "label_scheme",
            "label_scheme.id",
            "label_scheme.name",
            "data",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "is_exemplar",
            "is_full_bio_score",
            "is_real_science",
            "is_qaqc",
            "is_final",
            "annotation_count",
            "usergroup_count",
            "files",
            "files.id",
            "files.name",
            "files.file_url",
            "files.created_at",
            "media_count",
            "point_count",
            "unannotated_point_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object view permission from shared `usergroups`. Checks current_user has view permission. Also allows\n        owner of `parent` to view `children` or supplementary annotation_sets",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [annotation_set](#annotation_set) object with pk field matching param `id`",
          "endpoint": "/api/annotation_set/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object delete permission from shared `usergroups`. Checks current user is owner and object is not\n        shared in a `usergroup`. Also allows owner of `parent` to delete the `child`",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Add object with id `instance_id` to group with id `group_id`\n        ",
          "endpoint": "/api/annotation_set/<int:instance_id>/group/<int:group_id>",
          "method": "POST"
        },
        {
          "description": "Remove resource with id `instance_id` from group with id `group_id`",
          "endpoint": "/api/annotation_set/<int:instance_id>/group/<int:group_id>",
          "method": "DELETE"
        },
        {
          "description": "\n        Export [annotations](#annotation) from [annotation_set](#annotation_set) matching `id`.\n        \n        Export [annotations](#annotation) matching query define in `q`.\n        Search queries are executed on the [annotation](#annotation) model. This endpoint also supports translating\n        to a target `label_scheme` (when possible)\n\n        \n        Querystring parameters are:\n\n        ```?q={...}&f={...}&disposition=...&template=...&include_columns=[...]```\n\n        Where `q` is a JSON search query (see [Making API search queries](#api_query)) on the collection model,\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` defines the download type which can be `attachment` (default, triggers a download) or `inline` (displays in\n        the browser),\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `include_columns` is a JSON list of column fields for the exported model.\n        Nested fields for related models delimited with a `.`\n        If `include_columns` is omitted, all allowed columns will be returned.\n\n        Metadata for the dataset is also returned in the response. Depending on the output\n        format, this could be as part of the response body in a `metadata` field (e.g., Json) or in the response headers with the key\n        `X-Content-Metadata` (e.g., CSV or HTML).\n    \n\n        Allowed fields include:\n\n        `id`, `tag_names`, `comment`, `label.id`, `label.name`, `label.lineage_names`, `label.uuid`, `label.color`,\n        `supplementary_label`, `updated_at`, `object_id`, `parent_id`, `needs_review`, `likelihood`,`timestamp`,\n        `point.is_targeted`,`point.id`, `point.x`, `point.y`, `point.t`, `point.data`, `point.media.id`, `point.media.key`,\n        `point.polygon`, `annotation_set.id`, `annotation_set.name`, `media_collection.id`, `media_collection.name`,\n        `point.media.path_best`, `point.media.timestamp_start`, `point.media.timestamp_start_local`,\n        `point.media.path_best_thm`, `point.media.data`, `point.pose.timestamp`, `point.pose.timestamp_local`,\n        `point.pose.lat`, `point.pose.lon`, `point.pose.alt`, `point.pose.dep`, `point.pose.data`, `point.pose.id`,\n        `point.media.deployment.campaign.id`, `point.media.deployment.campaign.key`, `point.media.deployment.campaign.name`,\n        `point.media.deployment.platform.id`, `point.media.deployment.platform.key`, `point.media.deployment.platform.name`,\n        `user.username`,`user.full_name`, `user.affiliations_names`,\n        `point.media.deployment.key`, `point.media.deployment.id`, `point.media.deployment.name`,\n        `point.bbox`, `point.has_xy`, `point.has_polygon`, `point.pixels`\n\n        See [annotation](#annotation) model columns, relations and attributes for more information on each of the included fields.\n\n        **TRANSLATING TO OTHER LABEL_SCHEMES**\n\n        This endpoint also supports the translation of labels from a source to a target label_scheme.\n        another label_scheme using the semantic translation framework. In order to do this, you need to specify the\n        additional `translate` url query parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required. With translation parameters you will also need to specify additional columns in the `include_columns`\n        parameter to obtain the translation output.\n\n        Additional allowed columns include:\n\n        `label.translated.id`, `label.translated.name`, `label.translated.lineage_names`,\n        `label.translated.uuid`, `label.translated.translation_info`,\n\n        These columns are ignored if no `translate` query parameter is supplied.\n        \n\n        **EXAMPLES**\n\n        ```\n        # Example1: get all columns as a downloaded CSV file, only point annotations - filter out whole frame labels\n        /api/annotation_set/2194/export?template=dataframe.csv&f={\"operations\":[{\"module\":\"pandas\", \"method\":\"json_normalize\"}]}&q={\"filters\":[{\"name\":\"point\", \"op\":\"has\", \"val\":{\"name\":\"has_xy\", \"op\":\"eq\",\"val\":true}}]}\n\n        # Example2: aggregate label counts per frame (percent cover, no point information) as a downloaded csv\n        /api/annotation_set/2171/export?template=dataframe.csv&include_columns=[\"label.name\", \"label.lineage_names\", \"point.media.key\", \"point.pose.timestamp\", \"point.pose.lat\", \"point.pose.lon\", \"point.pose.alt\", \"point.pose.dep\"]&f={\"operations\":[{\"module\":\"pandas\", \"method\":\"json_normalize\"},{\"method\":\"fillna\", \"kwargs\":{\"value\":\"-\"}},{\"module\":\"pandas\", \"method\":\"count_unstack\", \"kwargs\":{\"columns\":[\"label.id\", \"label.uuid\", \"label.name\", \"label.lineage_names\", \"comment\", \"tag_names\"]}}]}\n\n        # Example3: show selected columns as an HTML table in the browser, filter out unlabeled annotations\n        /api/annotation_set/2171/export?template=dataframe.html&disposition=inline&include_columns=[\"label.name\",\"label.lineage_names\", \"updated_at\", \"point.x\", \"point.y\", \"point.media.key\", \"point.pose.timestamp\", \"point.pose.lat\", \"point.pose.lon\", \"point.pose.alt\", \"point.pose.dep\", \"point.media.deployment.key\", \"point.media.deployment.campaign.key\"]&f={\"operations\":[{\"module\":\"pandas\", \"method\":\"json_normalize\"}]}&q={\"filters\":[{\"name\":\"label_id\", \"op\":\"is_not_null\"}]}\n\n        # Example4: show HTML table in browser with tally of label counts (can be refreshed for readable live summary)\n        /api/annotation_set/2171/export?template=dataframe.html&disposition=inline&include_columns=[\"label.uuid\",\"label.name\",\"label.lineage_names\",\"label.id\"]&f={\"operations\":[{\"module\":\"pandas\",\"method\":\"json_normalize\"},{\"module\":\"pandas\",\"method\":\"groupby_count\"}]}&q={\"filters\":[{\"name\":\"label_id\",\"op\":\"is_not_null\"}]}\n        ```\n\n        NB: the UI contains an \"ADVANCED\" option which can help build more complex export queries.\n        ",
          "endpoint": "/api/annotation_set/<int:id>/export",
          "method": "GET"
        },
        {
          "description": "\n        Validate supplementary `annotation_set` `label` suggestions. It accepts an optional query string parameter\n        `supplementary_annotation_set_id` which specifies the `id` of the supplementary annotation_set to filter.\n        If omitted, it will validate against all supplementary `annotation_sets`. It evaluates the maximal `likelihood`\n        supplementary `annotation` for which to conduct the validation. It outputs `classification_report` which includes\n        a variety of classification performance parameters and a `confusion_matrix` oriented with rows showing actual\n        labels and columns showing the maximal likelihood supplementary labels.\n\n        This endpoint utilises the `translate` parameters, which allows validation by cross mapping to different\n        vocabularies. This can be useful if there are difference in the taxonomic resolution. The translation parameters\n        can be added as:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required. With translation parameters you will also need to specify additional columns in the `include_columns`\n        parameter to obtain the translation output.\n        ",
          "endpoint": "/api/annotation_set/<int:id>/annotations/validate",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/annotation_set/<int:id>/media",
          "method": "GET"
        },
        {
          "description": "\n        Returns list of [annotation](#annotation) objects contained in the `annotation_set` with an ID matching `id`.\n        The results can be filtered and searched. See [Making API search queries](#api_query) for instructions on making search queries.\n        In addition it accepts `include_columns` and `include_methods` query parameters which override returned\n        fields of [annotation](#annotation) model.\n        ",
          "endpoint": "/api/annotation_set/<int:id>/annotations",
          "method": "GET"
        },
        {
          "description": "Get any shared `[group_dashboards](group_dashboard)` for this resource",
          "endpoint": "/api/annotation_set/<int:id>/dashboards",
          "method": "GET"
        },
        {
          "description": "\n        Get a tally of [annotations](#annotation) for an `annotation_set` matching `id`.\n\n        \n        The tally of [annotations](#annotation) can be grouped by different properties. `group_by` can be one of\n        [`month`,'year_collected', 'month_collected', `user`, `platform`, `campaign`, `deployment`, `label`,\n        `annotation_set`, `affiliation`^, `usergroup`^]. Set `q` in querystring to filter\n        selected [annotations](#annotation) as per [Making API search queries](#api_query). Note, the same query in `q`\n        can be applied to all `group_by` types to filter the list of [annotations](#annotation) that are included in the\n        tally. Results are also paginated with a default of `500` and a maximum on `5000` returned per page. This can be\n        controlled by setting the `results_per_page` parameter in the query string.\n        Returned results are pre-filtered to return only the annotations that have been labeled (`label_id != null`).\n        Also accepts a query string parameter `template` which formats the data using a predefined template. Some example\n        templates include: `data.html` which returns an HTML table, `json.html` which returns HTML-formatted JSON, `data.csv`\n        which returns a CSV file for download. If left blank, raw JSON will be returned.\n\n        ^ **NOTE**: the counts in the `affiliation` and `usergroup` tally should be interpreted with care.\n        If someone belongs to more than one group, then their annotations will contribute to both so they may be double\n        counted. The corollary of that is if someone has not linked themselves to an affiliation or group, then their\n        annotations will not be counted in the tally.\n\n        **TRANSLATING TO OTHER LABEL_SCHEMES**\n\n        When using `group_by=label` it is possible translate labels from a source to a target label_scheme using the\n        semantic translation framework. In order to do this, you need to specify the additional `translate` url query\n        parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required. When passing translation parameters, there will the following additional output columns:\n        `label_lineage_names`, `translated_id`, `translated_lineage_names`, `translated_name`,\n        `translated_label_scheme_name`, `translated_info`.\n        \n\n        **EXAMPLES**\n\n        ```\n        ```\n        ",
          "endpoint": "/api/annotation_set/<int:id>/annotations/tally/<group_by>",
          "method": "GET"
        },
        {
          "description": "\n        Returns lists of the labels used in the `annotation_set` with an ID matching `id`. The `list_type` parameter\n        must one of [`updated_at`, `count`] which returns the most recently used labels or\n        counts by label (most frequently used), respectively. Depending on the `list_type`, an additional field containing\n        either the `count` or most recent `updated_at` datetime will be returned.\n        The number of results and page can be controlled with the optional `results_per_page` query parameter,\n        with a maximum of 200 results and a default of 20.\n        ",
          "endpoint": "/api/annotation_set/<int:id>/labels/list/<list_type>",
          "method": "GET"
        },
        {
          "description": "\n        Add the [media](#media) object with the ID `media_id` to the [media_collection](#media_collection) of the [annotation_set](#annotation_set) matching `annotation_set_id`\n        ",
          "endpoint": "/api/annotation_set/<int:annotation_set_id>/media/<int:media_id>",
          "method": "POST"
        },
        {
          "description": "\n        Remove the [media](#media) object with the ID `media_id` from the [media_collection](#media_collection) of the [annotation_set](#annotation_set) matching `annotation_set_id`\n        ",
          "endpoint": "/api/annotation_set/<int:annotation_set_id>/media/<int:media_id>",
          "method": "DELETE"
        },
        {
          "description": "\n        Clone the [annotation_set](#annotation_set) matching `id` to create a new one under the same collection.\n        This will clone all annotation_set properties along with all [points](#point), [annotations](#annotation),\n        [tags](#tag), [labels](#labels) including all annotation properties (`needs_review`, `likelihood`, `comment`).\n\n        This endpoint also supports the translation of labels from a source to a target label_scheme using the semantic\n        translation framework. In order to do this, you need to specify the additional `translate` url query parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required.\n        ",
          "endpoint": "/api/annotation_set/<int:id>/clone",
          "method": "POST"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "Number of media items in the media_collection",
          "name": "media_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Total number of labeled [annotations](#annotation) this `annotation_set`",
          "name": "annotation_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this annotation has a linked parent annotation",
          "name": "is_child",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not this object is public (i.e. shared in a public group)",
          "name": "is_public",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of this object",
          "name": "current_user_is_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member of a group that includes this object",
          "name": "current_user_is_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member with edit permission of a group that includes this object",
          "name": "current_user_is_edit_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of a group that includes this object",
          "name": "current_user_is_group_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not the current user has permission to view this object",
          "name": "current_user_can_view",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user has edit permission (owner or edit_member)",
          "name": "current_user_can_edit",
          "type": "property"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of this object",
          "name": "user_is_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member of a group that includes this object",
          "name": "user_is_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member with edit permission of a group that includes this object",
          "name": "user_is_edit_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of a group that includes this object",
          "name": "user_is_group_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Returns true is user is owner, dataset belongs to a public group, user owns a group or dataset belongs to an\n        unrestricted group that user is a member of",
          "name": "user_can_view",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user has edit permission (owner or edit_member)",
          "name": "user_can_edit",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": null,
          "name": "point_count",
          "type": "method"
        },
        {
          "doc": "\n        Preserve linking of annotations (observation groups) for cloning and import of annotations\n        @return:\n        ",
          "name": "preserve_object_links",
          "type": "method"
        },
        {
          "doc": null,
          "name": "unannotated_point_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "usergroup_count",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media_collection",
          "model": "media_collection"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "label_scheme",
          "model": "label_scheme"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related owner [users](#users) model",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "parent",
          "model": "annotation_set"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "List of [groups](#groups) objects that contain this resource",
          "key": "usergroups",
          "model": "groups"
        },
        {
          "direction": "ONETOMANY",
          "doc": "List of [point](#point) objects",
          "key": "points",
          "model": "point"
        },
        {
          "direction": "ONETOMANY",
          "doc": "List of related [annotation](#annotation) objects",
          "key": "annotations",
          "model": "annotation"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "children",
          "model": "annotation_set"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "files",
          "model": "annotation_set_file"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "annotation_set_file",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Sequence of file operations performed at last save",
          "foreign_key": null,
          "name": "last_save",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the file (optional). Defaults to `basename` of either `file_url` or the path of the uploaded file",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The URL of the file to be loaded dynamically (if `data` field is not set)",
          "foreign_key": null,
          "name": "file_url",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The description of the file (optional)",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The raw file storage for the file. This is not directly accessible through the API",
          "foreign_key": null,
          "name": "_rawfiledata",
          "nullable": true,
          "primary_key": false,
          "type": "LargeBinary()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not the file is compressed or not. If so, it will be automatically decompressed upon access.",
          "foreign_key": null,
          "name": "iscompressed",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "annotation_set.id",
          "name": "annotation_set_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Annotation Set File resource: a file associated with a [annotation_set](#annotation_set) object. Can be used for\n    batch importing / updating of [annotation](#annotation) and [point](#point) objects, as well as batch adding\n    [media](#media) objects to a [media_collection](#media_collection).\n    ",
      "endpoints": [
        {
          "description": "Create new [annotation_set_file](#annotation_set_file) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. Add user_id to post payload if not supplied",
          "endpoint": "/api/annotation_set_file",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [annotation_set_file](#annotation_set_file) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/annotation_set_file/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [annotation_set_file](#annotation_set_file) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/annotation_set_file",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "annotation_set_id",
            "file_url",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [annotation_set_file](#annotation_set_file) object with pk field matching param `id`",
          "endpoint": "/api/annotation_set_file/<id>",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "annotation_set_id",
            "file_url",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [annotation_set_file](#annotation_set_file) object with pk field matching param `id`",
          "endpoint": "/api/annotation_set_file/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Annotation Set File resource. \n        Get the data for the file resource matching `fid`. This endpoint also provides options to manipulate, transform\n        and save data to the database. The querystring takes the following form:\n        ```\n        ?f={...}&save={...}&disposition=...&template=...\n        ```\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` is optional and defines the download type which can be `inline` (default, displays in\n        the browser) or `attachment` (triggers a download) ,\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `save` is a JSON dictionary that defines batch save operations. This can be used to save the file content or the\n        output of the operations in `f` to a related database model collection.\n\n        \n\n        **Example1:** TODO\n        ```\n        /api/annotation_set_file/2/data?save={\"collection\": \"annotations\"}&f={\"operations\": [{\"module\": \"pandas\", \"method\": \"read_csv\", \"kwargs\": {\"parse_dates\": [\"time\"], \"skiprows\": 2, \"usecols\": [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}}, {\"method\": \"rename\", \"kwargs\": {\"columns\": {\"image_filename\": \"key\", \"longitude\": \"pose.lon\", \"latitude\": \"pose.lat\", \"depth_sensor\": \"pose.data.dep\", \"altitude_sensor\": \"pose.alt\", \"depth\": \"pose.dep\", \"sea_water_temperature\": \"pose.data.temp\", \"sea_water_salinity\": \"pose.data.salinity\", \"chlorophyll_concentration_in_sea_water\": \"pose.data.chlorophyll\", \"backscattering_ratio\": \"pose.data.backscater\", \"colored_dissolved_organic_matter\": \"pose.data.colored_dissolved_organic_matter\", \"time\": \"timestamp_start\", \"cluster_tag\": \"pose.data.cluster_tag\"}}}, {\"method\": \"to_dict\", \"kwargs\": {\"orient\": \"records\"}}, {\"module\": \"data\", \"method\": \"unflatten_dicts\", \"kwargs\": {}}]}\n        ```\n        ",
          "endpoint": "/api/annotation_set_file/<int:fid>/data",
          "method": "GET"
        },
        {
          "description": "\n        Save file data to database. Use this if it is not possible to dynamically link the file using the `file_url` or\n        if the `file_url` is potentially unstable / ephemeral. This should be a multipart form post with `file`\n        parameter set to the uploaded file and all other fields as in the object definition below.\n        ",
          "endpoint": "/api/annotation_set_file/data",
          "method": "POST"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": "Override to run special method after for preserving annotation linking",
          "name": "batch_save",
          "type": "method"
        },
        {
          "doc": null,
          "name": "data",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "annotation_set",
          "model": "annotation_set"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "annotation_tags",
      "columns": [
        {
          "default": null,
          "doc": "`id` of linked [annotation](#annotation)",
          "foreign_key": "annotation.id",
          "name": "annotation_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "`id` of linked [tag](#tag)",
          "foreign_key": "tag.id",
          "name": "tag_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "assoc_created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Tag Annotation Associate resource: links [tag](#tag) objects to [annotation](#annotation) objects.\n    ",
      "endpoints": [
        {
          "description": "Create new [annotation_tags](#annotation_tags) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/annotation_tags",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [annotation_tags](#annotation_tags) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/annotation_tags",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [annotation_tags](#annotation_tags) object with pk field matching param `annotation_id`",
          "endpoint": "/api/annotation_tags/<annotation_id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [annotation_tags](#annotation_tags) object with pk field matching param `annotation_id`",
          "endpoint": "/api/annotation_tags/<annotation_id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Linked [annotation](#annotation) object",
          "key": "annotation",
          "model": "annotation"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Linked [tag](#tag) object",
          "key": "tag",
          "model": "tag"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "campaign-deployment",
      "columns": [],
      "description": "\n    A special resource for listing / querying campaigns in a different format.\n    ",
      "endpoints": [
        {
          "description": "\n\n        ** Examples: **\n        ```\n        # search campaign-deployments for \"gbr\"\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"or\":[{\"name\":\"key\",\"op\":\"ilike\",\"val\":\"%gbr%\"},{\"name\":\"campaign\",\"op\":\"has\",\"val\":{\"name\":\"key\",\"op\":\"ilike\",\"val\":\"%gbr%\"}}]}]}\n        # match list of deployment keys (campaign-deployment)\n        /api/campaign-deployment?q={\"filters\":[{\"name\":\"key\",\"op\":\"in\",\"val\":[\"r20071004_013437_gbr_05_noggin_grids\",\"r20071010_230932_gbr_09_hydrographers_leg\"]}]}\n        # as above but for deployments\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"name\":\"key\",\"op\":\"in\",\"val\":[\"r20071004_013437_gbr_05_noggin_grids\",\"r20071010_230932_gbr_09_hydrographers_leg\"]}]}\n        # as above but for IDs and not keys\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"name\":\"id\",\"op\":\"in\",\"val\":[9495,9491]}]}\n        ```\n        ",
          "endpoint": "/api/campaign-deployment/<resource>",
          "method": "GET"
        },
        {
          "description": "\n\n        ** Examples: **\n        ```\n        # search campaign-deployments for \"gbr\"\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"or\":[{\"name\":\"key\",\"op\":\"ilike\",\"val\":\"%gbr%\"},{\"name\":\"campaign\",\"op\":\"has\",\"val\":{\"name\":\"key\",\"op\":\"ilike\",\"val\":\"%gbr%\"}}]}]}\n        # match list of deployment keys (campaign-deployment)\n        /api/campaign-deployment?q={\"filters\":[{\"name\":\"key\",\"op\":\"in\",\"val\":[\"r20071004_013437_gbr_05_noggin_grids\",\"r20071010_230932_gbr_09_hydrographers_leg\"]}]}\n        # as above but for deployments\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"name\":\"key\",\"op\":\"in\",\"val\":[\"r20071004_013437_gbr_05_noggin_grids\",\"r20071010_230932_gbr_09_hydrographers_leg\"]}]}\n        # as above but for IDs and not keys\n        /api/campaign-deployment/deployment?q={\"filters\":[{\"name\":\"id\",\"op\":\"in\",\"val\":[9495,9491]}]}\n        ```\n        ",
          "endpoint": "/api/campaign-deployment",
          "method": "GET"
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": []
    },
    {
      "association_proxies": [],
      "collection": "campaign",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Name of this `campaign`",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": "Key of this `campaign` (used for generating paths and links in repo)",
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "path",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Hex colour code for this `campaign`",
          "foreign_key": null,
          "name": "color",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=10)",
          "unique": false
        },
        {
          "default": null,
          "doc": "Description for this `campaign`",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "ID of the [user][#users] who created this `campaign`",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Datetime of creation",
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "media_path_pattern",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "thm_path_pattern",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_start",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_end",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_centroid",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "dep_min",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "dep_max",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "alt_min",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "alt_max",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp_start",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp_end",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "0",
          "doc": null,
          "foreign_key": null,
          "name": "pose_count",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "0",
          "doc": null,
          "foreign_key": null,
          "name": "media_count",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "0",
          "doc": null,
          "foreign_key": null,
          "name": "deployment_count",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Campaign resource: a group of [deployments](#deployment). Eg: a specific expedition, cruise or data collection initiative\n    ",
      "endpoints": [
        {
          "description": "Create new [campaign](#campaign) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. Add user_id to post payload if not supplied",
          "endpoint": "/api/campaign",
          "method": "POST",
          "postprocessors": [
            {
              "doc": "Clears the request cache object for this resource (to cause cache refresh on next request)",
              "name": "_clear_cache"
            }
          ],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [campaign](#campaign) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/campaign/<id>",
          "method": "PATCH",
          "postprocessors": [
            {
              "doc": "Clears the request cache object for this resource (to cause cache refresh on next request)",
              "name": "_clear_cache"
            }
          ],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [campaign](#campaign) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/campaign",
          "fields": [
            "color",
            "id",
            "key",
            "name",
            "description",
            "deployment_count",
            "media_count",
            "total_annotation_count",
            "public_annotation_count",
            "latlon"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [campaign](#campaign) object with pk field matching param `id`",
          "endpoint": "/api/campaign/<id>",
          "fields": [
            "color",
            "id",
            "key",
            "name",
            "description",
            "deployment_count",
            "media_count",
            "total_annotation_count",
            "public_annotation_count",
            "latlon",
            "user_id",
            "stats",
            "platforms",
            "total_annotation_count",
            "public_annotation_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [campaign](#campaign) object with pk field matching param `id`",
          "endpoint": "/api/campaign/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Deployment resource\n\n        Minimal Deployment Resource for map data - result is cached for fast loading. Cache is cleared when new deployments are saved.\n\n        :param GET: json: q: restless search query.\n        :returns GET: json: a json string containing the structure of stuff\n        ",
          "endpoint": "/api/campaign/map",
          "method": "GET"
        },
        {
          "description": "Finalise the campaign computing cached `pose` metrics and 'geo' properties",
          "endpoint": "/api/campaign/<int:id>/finalise",
          "method": "PATCH"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "The centroid `geom` point of all the [poses](#pose) contained in this `campaign`",
          "name": "geom",
          "type": "property"
        },
        {
          "args": [],
          "doc": "A `timestamp` from the [poses](#pose) contained in this `campaign`",
          "name": "timestamp",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Fetch total annotation count from the materialized view.",
          "name": "total_annotation_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Fetch public annotation count from the materialized view.",
          "name": "public_annotation_count",
          "type": "property"
        }
      ],
      "methods": [
        {
          "doc": "\n        Compute spatial extent of Campaign\n        :return: list with format [[SW_LAT, SW_LON],[NE_LAT,NE_LON]]\n        ",
          "name": "extent",
          "type": "method"
        },
        {
          "doc": null,
          "name": "file_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "platforms",
          "type": "method"
        },
        {
          "doc": null,
          "name": "stats",
          "type": "method"
        },
        {
          "doc": null,
          "name": "timestamp_range",
          "type": "method"
        },
        {
          "doc": null,
          "name": "latlon",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "deployments",
          "model": "deployment"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "info",
          "model": "campaigninfo"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "files",
          "model": "campaign_file"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "campaign_file",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Sequence of file operations performed at last save",
          "foreign_key": null,
          "name": "last_save",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the file (optional). Defaults to `basename` of either `file_url` or the path of the uploaded file",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The URL of the file to be loaded dynamically (if `data` field is not set)",
          "foreign_key": null,
          "name": "file_url",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The description of the file (optional)",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The raw file storage for the file. This is not directly accessible through the API",
          "foreign_key": null,
          "name": "_rawfiledata",
          "nullable": true,
          "primary_key": false,
          "type": "LargeBinary()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not the file is compressed or not. If so, it will be automatically decompressed upon access.",
          "foreign_key": null,
          "name": "iscompressed",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "campaign.id",
          "name": "campaign_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Campaign File resource: a file associated with a [campaign](#campaign) object.\n    ",
      "endpoints": [
        {
          "description": "Create new [campaign_file](#campaign_file) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. Add user_id to post payload if not supplied",
          "endpoint": "/api/campaign_file",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [campaign_file](#campaign_file) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/campaign_file/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [campaign_file](#campaign_file) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/campaign_file",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "campaign_id",
            "file_url",
            "id",
            "name"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [campaign_file](#campaign_file) object with pk field matching param `id`",
          "endpoint": "/api/campaign_file/<id>",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "campaign_id",
            "file_url",
            "id",
            "name"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [campaign_file](#campaign_file) object with pk field matching param `id`",
          "endpoint": "/api/campaign_file/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Get the data for the file resource matching `fid`. This endpoint also provides options to manipulate, transform\n        and save data to the database. The querystring takes the following form:\n        ```\n        ?f={...}&save={...}&disposition=...&template=...\n        ```\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` is optional and defines the download type which can be `inline` (default, displays in\n        the browser) or `attachment` (triggers a download) ,\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `save` is a JSON dictionary that defines batch save operations. This can be used to save the file content or the\n        output of the operations in `f` to a related database model collection.\n\n        ",
          "endpoint": "/api/campaign_file/<int:fid>/data",
          "method": "GET"
        },
        {
          "description": "\n        Save file data to database. Use this if it is not possible to dynamically link the file using the `file_url` or\n        if the `file_url` is potentially unstable / ephemeral. This should be a multipart form post with `file`\n        parameter set to the uploaded file and all other fields as in the object definition below.\n        ",
          "endpoint": "/api/campaign_file/data",
          "method": "POST"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "data",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "campaign",
          "model": "campaign"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "campaigninfo",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "campaign.id",
          "name": "campaign_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Deprecated.\n    ",
      "endpoints": [
        {
          "description": "Create new [campaigninfo](#campaigninfo) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/campaigninfo",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [campaigninfo](#campaigninfo) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/campaigninfo",
          "fields": [
            "name",
            "description",
            "created_at",
            "campaign_id",
            "id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [campaigninfo](#campaigninfo) object with pk field matching param `id`",
          "endpoint": "/api/campaigninfo/<id>",
          "fields": [
            "name",
            "description",
            "created_at",
            "campaign_id",
            "id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [campaigninfo](#campaigninfo) object with pk field matching param `id`",
          "endpoint": "/api/campaigninfo/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "campaign",
          "model": "campaign"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "datasource",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "campaign_search",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "datafile_pattern",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "datafile_search",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "deployment_search",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "media_pattern",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "mediadir_search",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "thumb_pattern",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "thumbdir_search",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "urlbase_browse",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "credential_key",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "datafile_operations",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "datasource_type.id",
          "name": "datasource_type_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "platform.id",
          "name": "platform_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Datasource resource: the parameters that define the structure and format of the data on the\n    `Datasource Repository` and which `Datasource Plugin` to use. Each [platform](#platform) must have at least one [datasource](#datasource).\n    ",
      "endpoints": [
        {
          "description": "Create new [datasource](#datasource) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/datasource",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [datasource](#datasource) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/datasource/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [datasource](#datasource) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/datasource",
          "fields": [
            "id",
            "name",
            "campaign_search",
            "datafile_pattern",
            "datafile_search",
            "deployment_search",
            "media_pattern",
            "mediadir_search",
            "thumb_pattern",
            "thumbdir_search",
            "urlbase_browse",
            "datafile_operations",
            "datasource_type",
            "datasource_type.id",
            "datasource_type.name",
            "platform",
            "platform.id",
            "platform.name",
            "user_id",
            "created_at",
            "credential_key"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [datasource](#datasource) object with pk field matching param `id`",
          "endpoint": "/api/datasource/<id>",
          "fields": [
            "id",
            "name",
            "campaign_search",
            "datafile_pattern",
            "datafile_search",
            "deployment_search",
            "media_pattern",
            "mediadir_search",
            "thumb_pattern",
            "thumbdir_search",
            "urlbase_browse",
            "datafile_operations",
            "datasource_type",
            "datasource_type.id",
            "datasource_type.name",
            "platform",
            "platform.id",
            "platform.name",
            "user_id",
            "created_at",
            "credential_key"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [datasource](#datasource) object with pk field matching param `id`",
          "endpoint": "/api/datasource/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "datasource_type",
          "model": "datasource_type"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "platform",
          "model": "platform"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "deployments",
          "model": "deployment"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "datasource_type",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Datasource Type resource: defines mapping to a datasource plugin.\n    ",
      "endpoints": [
        {
          "description": "Get list of [datasource_type](#datasource_type) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/datasource_type",
          "fields": [
            "id",
            "name",
            "created_at"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [datasource_type](#datasource_type) object with pk field matching param `id`",
          "endpoint": "/api/datasource_type/<id>",
          "fields": [
            "id",
            "name",
            "created_at"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "datasources",
          "model": "datasource"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "deployment",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "path",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "campaign.id",
          "name": "campaign_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "platform.id",
          "name": "platform_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "datasource.id",
          "name": "datasource_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "True",
          "doc": null,
          "foreign_key": null,
          "name": "is_valid",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_line",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_start",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_end",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom_centroid",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "dep_min",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "dep_max",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "alt_min",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "alt_max",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp_start",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp_end",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "0",
          "doc": null,
          "foreign_key": null,
          "name": "pose_count",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "0",
          "doc": null,
          "foreign_key": null,
          "name": "media_count",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Deployment resource: a dataset containing a group of [media](#media) objects collected from an operation of the [platform](#platform), eg: a survey, transect or mission\n    ",
      "endpoints": [
        {
          "description": "Create new [deployment](#deployment) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. Add user_id to post payload if not supplied",
          "endpoint": "/api/deployment",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [deployment](#deployment) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/deployment/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [deployment](#deployment) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/deployment",
          "fields": [
            "name",
            "key",
            "id",
            "created_at",
            "campaign",
            "campaign.id",
            "campaign.name",
            "platform",
            "platform.id",
            "platform.name",
            "is_valid",
            "dep_max",
            "alt_min",
            "media_count",
            "dep_min",
            "alt_max",
            "pose_count",
            "timestamp_end",
            "timestamp_start",
            "color",
            "pose"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [deployment](#deployment) object with pk field matching param `id`",
          "endpoint": "/api/deployment/<id>",
          "fields": [
            "name",
            "key",
            "id",
            "created_at",
            "campaign",
            "campaign.id",
            "campaign.name",
            "platform",
            "platform.id",
            "platform.name",
            "is_valid",
            "dep_max",
            "alt_min",
            "media_count",
            "dep_min",
            "alt_max",
            "pose_count",
            "timestamp_end",
            "timestamp_start",
            "color",
            "pose",
            "user_id",
            "created_at",
            "description",
            "campaign.key",
            "platform",
            "platform.id",
            "platform.name",
            "platform.key",
            "files",
            "files.id",
            "files.name",
            "files.file_url",
            "media_count",
            "pose_stats",
            "layers",
            "total_annotation_count",
            "public_annotation_count",
            "annotated_media_count",
            "extent"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [deployment](#deployment) object with pk field matching param `id`",
          "endpoint": "/api/deployment/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Deployment resource\n\n        Minimal Deployment Resource for map data - result is cached for fast loading. Cache is cleared when new deployments are saved.\n\n        :param GET: json: q: restless search query.\n        :returns GET: json: a json string containing the structure of stuff\n        ",
          "endpoint": "/api/deployment/map",
          "method": "GET"
        },
        {
          "description": "\n        Export [media](#media) from [deployment](#deployment) matching `id`.\n        \n        Export [media](#media) matching query define in `q`.\n        Search queries are executed on the [media](#media) model. \n\n        \n        Querystring parameters are:\n\n        ```?q={...}&f={...}&disposition=...&template=...&include_columns=[...]```\n\n        Where `q` is a JSON search query (see [Making API search queries](#api_query)) on the collection model,\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` defines the download type which can be `attachment` (default, triggers a download) or `inline` (displays in\n        the browser),\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `include_columns` is a JSON list of column fields for the exported model.\n        Nested fields for related models delimited with a `.`\n        If `include_columns` is omitted, all allowed columns will be returned.\n\n        Metadata for the dataset is also returned in the response. Depending on the output\n        format, this could be as part of the response body in a `metadata` field (e.g., Json) or in the response headers with the key\n        `X-Content-Metadata` (e.g., CSV or HTML).\n    \n\n        Allowed fields include:\n\n        `id`, `key`, `data`, `is_valid`,`media_type.id`,`media_type.name`, `path_best`, `timestamp_start`,\n        `timestamp_start_local`, `path_best_thm`, `pose.timestamp`, `pose.timestamp_local`, `pose.lat`, `pose.lon`,\n        `pose.alt`, `pose.dep`, `pose.data`, `pose.id`, `deployment.campaign.id`, `deployment.campaign.key`,\n        `deployment.campaign.name`, `deployment.key`, `deployment.id`, `deployment.name`\n\n        See [media](#media) model columns, relations and attributes for more information on each of the included fields.\n        \n        \n\n        **EXAMPLES**\n\n        ```\n        ```\n        ",
          "endpoint": "/api/deployment/<int:id>/export",
          "method": "GET"
        },
        {
          "description": "Finalise the deployment setting `is_valid=True` and computing cached `pose` metrics and 'geo' properties",
          "endpoint": "/api/deployment/<int:id>/finalise",
          "method": "PATCH"
        },
        {
          "description": "\n        Get ecoregion info from ESRI API Marine Ecoregions Of the World (MEOW) feature layer. Uses `latlon` of deployment to\n        determine the relevant ecoregion. Accepts querystring parameter: `fields` which is a comma-separated list\n        of properties to return, which can be a subset of:\n        `fields = FID, ECO_CODE, ECOREGION, PROV_CODE, PROVINCE, RLM_CODE, REALM, ALT_CODE, ECO_CODE_X, Lat_Zone, Shape__Area, Shape__Length`\n        if not set, it will default to `fields=*`, which will return all properties.\n        ",
          "endpoint": "/api/deployment/<int:id>/ecoregion",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "Number of [media](#media) objects with one or more labeled [annotations](#annotation) in this `deployment`",
          "name": "annotated_media_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "The centroid `geom` point of all the [poses](#pose) contained in this `deployment`",
          "name": "geom",
          "type": "property"
        },
        {
          "args": [],
          "doc": "A `timestamp` from the [poses](#pose) contained in this `deployment`",
          "name": "timestamp",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Fetch total annotation count from the materialized view.",
          "name": "total_annotation_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Fetch public annotation count from the materialized view.",
          "name": "public_annotation_count",
          "type": "property"
        }
      ],
      "methods": [
        {
          "doc": null,
          "name": "color",
          "type": "method"
        },
        {
          "doc": "\n        Compute spatial extent of Campaign\n        :return: list with format [[SW_LAT, SW_LON],[NE_LAT,NE_LON]]\n        ",
          "name": "extent",
          "type": "method"
        },
        {
          "doc": null,
          "name": "layers",
          "type": "method"
        },
        {
          "doc": null,
          "name": "pose_stats",
          "type": "method"
        },
        {
          "doc": null,
          "name": "timestamp_range",
          "type": "method"
        },
        {
          "doc": null,
          "name": "latlon",
          "type": "property"
        },
        {
          "doc": null,
          "name": "pose",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "campaign",
          "model": "campaign"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "platform",
          "model": "platform"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "datasource",
          "model": "datasource"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "media",
          "model": "media"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "events",
          "model": "deployment_event"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "files",
          "model": "deployment_file"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "deployment_event",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "pose.id",
          "name": "pose_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media.id",
          "name": "media_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "deployment_event_type.id",
          "name": "deployment_event_type_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "deployment.id",
          "name": "deployment_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Deployment Event resource: a freeform text log that can be associated with a [pose](#pose) and/or a [media](#media) object.\n    ",
      "endpoints": [
        {
          "description": "Create new [deployment_event](#deployment_event) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/deployment_event",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [deployment_event](#deployment_event) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/deployment_event/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [deployment_event](#deployment_event) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/deployment_event",
          "fields": [
            "media",
            "media.id",
            "media.key",
            "media.path_best",
            "media.path_best_thm",
            "user_id",
            "description",
            "timestamp",
            "created_at",
            "pose",
            "pose.lat",
            "pose.lon",
            "pose.alt",
            "pose.dep",
            "pose.timestamp",
            "deployment",
            "deployment.name",
            "deployment.key",
            "deployment.id",
            "deployment.created_at",
            "deployment.campaign_id",
            "deployment_event_type",
            "user",
            "user.username",
            "user.info",
            "user.first_name",
            "user.last_name",
            "user.email",
            "user.id",
            "deployment_event_type_id",
            "media_id",
            "deployment_id",
            "id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [deployment_event](#deployment_event) object with pk field matching param `id`",
          "endpoint": "/api/deployment_event/<id>",
          "fields": [
            "media",
            "media.id",
            "media.key",
            "media.path_best",
            "media.path_best_thm",
            "user_id",
            "description",
            "timestamp",
            "created_at",
            "pose",
            "pose.lat",
            "pose.lon",
            "pose.alt",
            "pose.dep",
            "pose.timestamp",
            "deployment",
            "deployment.name",
            "deployment.key",
            "deployment.id",
            "deployment.created_at",
            "deployment.campaign_id",
            "deployment_event_type",
            "user",
            "user.username",
            "user.info",
            "user.first_name",
            "user.last_name",
            "user.email",
            "user.id",
            "deployment_event_type_id",
            "media_id",
            "deployment_id",
            "id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [deployment_event](#deployment_event) object with pk field matching param `id`",
          "endpoint": "/api/deployment_event/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "pose",
          "model": "pose"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media",
          "model": "media"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "deployment_event_type",
          "model": "deployment_event_type"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "deployment",
          "model": "deployment"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "deployment_event_type",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        }
      ],
      "description": "\n    Deployment Event resource: timestamped freeform text observation with optional link to [media](#media) and [pose](#pose) objects.\n    ",
      "endpoints": [
        {
          "description": "Create new [deployment_event_type](#deployment_event_type) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/deployment_event_type",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [deployment_event_type](#deployment_event_type) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/deployment_event_type/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [deployment_event_type](#deployment_event_type) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/deployment_event_type",
          "fields": [
            "name",
            "id",
            "data"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [deployment_event_type](#deployment_event_type) object with pk field matching param `id`",
          "endpoint": "/api/deployment_event_type/<id>",
          "fields": [
            "name",
            "id",
            "data"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [deployment_event_type](#deployment_event_type) object with pk field matching param `id`",
          "endpoint": "/api/deployment_event_type/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "deployment_events",
          "model": "deployment_event"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "deployment_file",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Sequence of file operations performed at last save",
          "foreign_key": null,
          "name": "last_save",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the file (optional). Defaults to `basename` of either `file_url` or the path of the uploaded file",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The URL of the file to be loaded dynamically (if `data` field is not set)",
          "foreign_key": null,
          "name": "file_url",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The description of the file (optional)",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The raw file storage for the file. This is not directly accessible through the API",
          "foreign_key": null,
          "name": "_rawfiledata",
          "nullable": true,
          "primary_key": false,
          "type": "LargeBinary()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not the file is compressed or not. If so, it will be automatically decompressed upon access.",
          "foreign_key": null,
          "name": "iscompressed",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "deployment.id",
          "name": "deployment_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Deployment File resource: a file associated with a [deployment](#deployment) object. Can be used for batch importing / updating\n    of [media](#media), [pose](#pose) and [pose_data](#pose_data) objects.\n    ",
      "endpoints": [
        {
          "description": "Create new [deployment_file](#deployment_file) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. Add user_id to post payload if not supplied",
          "endpoint": "/api/deployment_file",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [deployment_file](#deployment_file) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/deployment_file/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [deployment_file](#deployment_file) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/deployment_file",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "deployment_id",
            "file_url",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [deployment_file](#deployment_file) object with pk field matching param `id`",
          "endpoint": "/api/deployment_file/<id>",
          "fields": [
            "user_id",
            "description",
            "iscompressed",
            "deployment_id",
            "file_url",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [deployment_file](#deployment_file) object with pk field matching param `id`",
          "endpoint": "/api/deployment_file/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Deployment file resource. \n        Get the data for the file resource matching `fid`. This endpoint also provides options to manipulate, transform\n        and save data to the database. The querystring takes the following form:\n        ```\n        ?f={...}&save={...}&disposition=...&template=...\n        ```\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` is optional and defines the download type which can be `inline` (default, displays in\n        the browser) or `attachment` (triggers a download) ,\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `save` is a JSON dictionary that defines batch save operations. This can be used to save the file content or the\n        output of the operations in `f` to a related database model collection.\n\n        \n\n        **Example1:** convert CSV file into serialized, nested JSON expected for [media](#media) resource and batch save rows to the related `deployment.media` collection for this model\n        ```\n        /api/deployment_file/2/data?save={\"collection\": \"deployment.media\"}&f={\"operations\": [{\"module\": \"pandas\", \"method\": \"read_csv\", \"kwargs\": {\"parse_dates\": [\"time\"], \"skiprows\": 2, \"usecols\": [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}}, {\"method\": \"rename\", \"kwargs\": {\"columns\": {\"image_filename\": \"key\", \"longitude\": \"pose.lon\", \"latitude\": \"pose.lat\", \"depth_sensor\": \"pose.data.dep\", \"altitude_sensor\": \"pose.alt\", \"depth\": \"pose.dep\", \"sea_water_temperature\": \"pose.data.temp\", \"sea_water_salinity\": \"pose.data.salinity\", \"chlorophyll_concentration_in_sea_water\": \"pose.data.chlorophyll\", \"backscattering_ratio\": \"pose.data.backscater\", \"colored_dissolved_organic_matter\": \"pose.data.colored_dissolved_organic_matter\", \"time\": \"timestamp_start\", \"cluster_tag\": \"pose.data.cluster_tag\"}}}, {\"method\": \"to_dict\", \"kwargs\": {\"orient\": \"records\"}}, {\"module\": \"data\", \"method\": \"unflatten_dicts\", \"kwargs\": {}}]}\n        ```\n\n        **Example 2:** similar to above, but perform an update rather than an insert. Can optinally create missing. This is slower.\n        ```\n        /api/deployment_file/4/data?save={\"collection\": \"deployment.media\", \"update_existing\": true, \"match_on\": [\"key\"], \"create_missing\": true}&f={\"operations\": [{\"module\": \"pandas\", \"method\": \"read_csv\", \"kwargs\": {\"parse_dates\": [\"time\"], \"skiprows\": 2, \"usecols\": [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]}}, {\"method\": \"rename\", \"kwargs\": {\"columns\": {\"image_filename\": \"key\", \"longitude\": \"pose.lon\", \"latitude\": \"pose.lat\", \"depth_sensor\": \"pose.data.dep\", \"altitude_sensor\": \"pose.alt\", \"depth\": \"pose.dep\", \"sea_water_temperature\": \"pose.data.temp\", \"sea_water_salinity\": \"pose.data.salinity\", \"chlorophyll_concentration_in_sea_water\": \"pose.data.chlorophyll\", \"backscattering_ratio\": \"pose.data.backscater\", \"colored_dissolved_organic_matter\": \"pose.data.colored_dissolved_organic_matter\", \"time\": \"timestamp_start\", \"cluster_tag\": \"pose.data.cluster_tag\"}}}, {\"method\": \"to_dict\", \"kwargs\": {\"orient\": \"records\"}}, {\"module\": \"data\", \"method\": \"unflatten_dicts\", \"kwargs\": {}}]}\n        ```\n        ",
          "endpoint": "/api/deployment_file/<int:fid>/data",
          "method": "GET"
        },
        {
          "description": "\n        Save file data to database. Use this if it is not possible to dynamically link the file using the `file_url` or\n        if the `file_url` is potentially unstable / ephemeral. This should be a multipart form post with `file`\n        parameter set to the uploaded file and all other fields as in the object definition below.\n        ",
          "endpoint": "/api/deployment_file/data",
          "method": "POST"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "data",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "deployment",
          "model": "deployment"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "group_dashboard",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Name of Dashboard",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": null,
          "doc": "Dashboard resource",
          "foreign_key": null,
          "name": "resource",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Date this was created",
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Base URL for Dashboard",
          "foreign_key": null,
          "name": "url_base",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=256)",
          "unique": null
        },
        {
          "default": null,
          "doc": "Description for this dashboard",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Metadata for Dashboard",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foriegn key `id` for owner [user](#user) object",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foriegn key `id` for owner [group](#groups) object",
          "foreign_key": "groups.id",
          "name": "group_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether User must be a member of the Group",
          "foreign_key": null,
          "name": "requires_user_is_member",
          "nullable": false,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether User is Dataset owner",
          "foreign_key": null,
          "name": "requires_user_is_owner",
          "nullable": false,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether User needs Dataset edit permission",
          "foreign_key": null,
          "name": "requires_user_can_edit",
          "nullable": false,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether User can share data to Group",
          "foreign_key": null,
          "name": "requires_user_can_share_data",
          "nullable": false,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether User can add members to Group",
          "foreign_key": null,
          "name": "requires_user_can_add_member",
          "nullable": false,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        }
      ],
      "description": "\n    Group Dashboard resource. Enables sharing of dashboards through Groups.\n    ",
      "endpoints": [
        {
          "description": "Create new [group_dashboard](#group_dashboard) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/group_dashboard",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [group_dashboard](#group_dashboard) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/group_dashboard/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [group_dashboard](#group_dashboard) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/group_dashboard",
          "fields": [
            "id",
            "name",
            "url_base",
            "description",
            "data",
            "created_at",
            "user_id",
            "group",
            "group.id",
            "group.name",
            "resource",
            "requires_user_is_owner",
            "requires_user_is_member",
            "requires_user_can_edit",
            "requires_user_can_share_data",
            "requires_user_can_add_member"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [group_dashboard](#group_dashboard) object with pk field matching param `id`",
          "endpoint": "/api/group_dashboard/<id>",
          "fields": [
            "id",
            "name",
            "url_base",
            "description",
            "data",
            "created_at",
            "user_id",
            "group",
            "group.id",
            "group.name",
            "resource",
            "requires_user_is_owner",
            "requires_user_is_member",
            "requires_user_can_edit",
            "requires_user_can_share_data",
            "requires_user_can_add_member"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [group_dashboard](#group_dashboard) object with pk field matching param `id`",
          "endpoint": "/api/group_dashboard/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Related owner [user](#user) object",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related [group](#groups) object",
          "key": "group",
          "model": "groups"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "group_types",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        }
      ],
      "description": "\n    Group Type resource.\n    ",
      "endpoints": [
        {
          "description": "Get list of [group_types](#group_types) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/group_types",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [group_types](#group_types) object with pk field matching param `id`",
          "endpoint": "/api/group_types/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": []
    },
    {
      "association_proxies": [],
      "collection": "groups",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Name of Group",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not contents are publicly viewable",
          "foreign_key": null,
          "name": "is_public",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "True",
          "doc": "Whether or not members can see other member's datasets",
          "foreign_key": null,
          "name": "is_restricted",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "True",
          "doc": "Whether or not custodian approval is required",
          "foreign_key": null,
          "name": "requires_approval",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not members need to agree to Data Usage Agreement (DUA)",
          "foreign_key": null,
          "name": "requires_agreement",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Extra information about the Group",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Data Usage Agreement (DUA) link. Must be an HTTP accessible, embeddable document",
          "foreign_key": null,
          "name": "dua_link",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "`id` of group custodian [user](#users)",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "`id` of related [group_type](#group_type)",
          "foreign_key": "group_types.id",
          "name": "group_type_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Shorter description / tagline of Group",
          "foreign_key": null,
          "name": "groupinfo",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Datetime of creation",
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Group resource: user groups for managing shared resources and permissions.\n    ",
      "endpoints": [
        {
          "description": "Create new [groups](#groups) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/groups",
          "method": "POST",
          "postprocessors": [
            {
              "doc": null,
              "name": "post_postprocessor"
            }
          ],
          "preprocessors": [
            {
              "doc": "Handle group_type_name parameter and secure against membership/dataset tampering",
              "name": "group_data_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [groups](#groups) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/groups/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Handle group_type_name parameter and secure against membership/dataset tampering",
              "name": "group_data_preprocessor"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [groups](#groups) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/groups",
          "fields": [
            "id",
            "name",
            "is_public",
            "dua_link",
            "user",
            "user.id",
            "user.first_name",
            "user.last_name",
            "user.username",
            "is_restricted",
            "group_type",
            "groupinfo",
            "created_at",
            "current_user_is_edit_member",
            "current_user_is_member",
            "current_user_is_owner",
            "current_user_can_share_data",
            "current_user_can_add_member",
            "current_user_has_agreed",
            "current_user_is_pending_approval",
            "requires_agreement",
            "requires_approval",
            "member_count",
            "pending_member_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [groups](#groups) object with pk field matching param `id`",
          "endpoint": "/api/groups/<id>",
          "fields": [
            "id",
            "name",
            "is_public",
            "dua_link",
            "user",
            "user.id",
            "user.first_name",
            "user.last_name",
            "user.username",
            "is_restricted",
            "group_type",
            "groupinfo",
            "created_at",
            "current_user_is_edit_member",
            "current_user_is_member",
            "current_user_is_owner",
            "current_user_can_share_data",
            "current_user_can_add_member",
            "current_user_has_agreed",
            "current_user_is_pending_approval",
            "requires_agreement",
            "requires_approval",
            "member_count",
            "pending_member_count",
            "description",
            "dataset_counts"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [groups](#groups) object with pk field matching param `id`",
          "endpoint": "/api/groups/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "\n\n        :return:\n        ",
          "name": "current_user_is_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "\n\n        :return:\n        ",
          "name": "current_user_is_pending_approval",
          "type": "property"
        },
        {
          "args": [],
          "doc": "\n\n        :return:\n        ",
          "name": "current_user_is_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "\n\n        :return:\n        ",
          "name": "current_user_is_edit_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOL, whether current_user has permission to share",
          "name": "current_user_can_share_data",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOL, whether current_user has permission to share",
          "name": "current_user_can_add_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOL, whether current_user has permission to share",
          "name": "current_user_has_agreed",
          "type": "property"
        }
      ],
      "methods": [
        {
          "doc": "the number of different datasets that are shared in this group",
          "name": "dataset_counts",
          "type": "method"
        },
        {
          "doc": null,
          "name": "member_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "pending_member_count",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Related [user](#users) for group custodian",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": "related [group_type](#group_type) object",
          "key": "group_type",
          "model": "group_types"
        },
        {
          "direction": "MANYTOMANY",
          "doc": null,
          "key": "members",
          "model": "users"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "usergroups",
          "model": "usergroups"
        },
        {
          "direction": "ONETOMANY",
          "doc": "Dashboards for this Group",
          "key": "dashboards",
          "model": "group_dashboard"
        },
        {
          "direction": "MANYTOMANY",
          "doc": null,
          "key": "shared_label_schemes",
          "model": "label_scheme"
        },
        {
          "direction": "MANYTOMANY",
          "doc": null,
          "key": "shared_annotation_sets",
          "model": "annotation_set"
        },
        {
          "direction": "MANYTOMANY",
          "doc": null,
          "key": "shared_media_collections",
          "model": "media_collection"
        }
      ]
    },
    {
      "association_proxies": [
        {
          "model": "tag",
          "name": "tags",
          "target_collection": "label_tags"
        }
      ],
      "collection": "label",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "A universally unique identifier for this object",
          "foreign_key": null,
          "name": "uuid",
          "nullable": true,
          "primary_key": false,
          "type": "UUID(as_uuid=True)",
          "unique": true
        },
        {
          "default": null,
          "doc": "The name of this class label",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=160)",
          "unique": false
        },
        {
          "default": "function",
          "doc": "The colour of this class label (hex code, including #)",
          "foreign_key": null,
          "name": "color",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=10)",
          "unique": false
        },
        {
          "default": null,
          "doc": "The `id` of the user who owns or created this class label",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The `id` of the annotation scheme ([label_scheme](#label_scheme)) containing this class label",
          "foreign_key": "label_scheme.id",
          "name": "label_scheme_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "`id` of the parent class label",
          "foreign_key": "label.id",
          "name": "parent_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether this class label has been approved by the custodian",
          "foreign_key": null,
          "name": "is_approved",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Creation time (UTC)",
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "origin_code",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "parent_origin_code",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": false
        }
      ],
      "description": "\n    Label resource. This defines the list of labels contained in a [label_scheme](#label_scheme) and the labels to be applied to\n    [annotation](#annotation) objects. Each label can also have suggested [tag](#tag) objects linked to it.\n    ",
      "endpoints": [
        {
          "description": "Create new [label](#label) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/label",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        if `parent_id` is set, checks that nominated parent class label is valid, i.e.: that the `parent_id` exists,\n        is from the same annotation scheme (`label_scheme_id`) and is not a circular reference to itself (witch can break\n        things).\n        ",
              "name": "validate_preprocessor"
            },
            {
              "doc": null,
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [label](#label) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/label/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        if `parent_id` is set, checks that nominated parent class label is valid, i.e.: that the `parent_id` exists,\n        is from the same annotation scheme (`label_scheme_id`) and is not a circular reference to itself (witch can break\n        things).\n        ",
              "name": "validate_preprocessor"
            },
            {
              "doc": "\n        checks that the current user has permission to edit this class label.\n        ",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [label](#label) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/label",
          "fields": [
            "user_id",
            "name",
            "color",
            "parent_id",
            "label_scheme_id",
            "id",
            "uuid",
            "is_child",
            "is_parent",
            "created_at",
            "updated_at",
            "is_approved",
            "origin_code",
            "parent_origin_code",
            "name_path",
            "lineage"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [label](#label) object with pk field matching param `id`",
          "endpoint": "/api/label/<id>",
          "fields": [
            "user_id",
            "name",
            "color",
            "parent_id",
            "label_scheme_id",
            "id",
            "uuid",
            "is_child",
            "is_parent",
            "created_at",
            "updated_at",
            "is_approved",
            "origin_code",
            "parent_origin_code",
            "name_path",
            "lineage",
            "info",
            "info.name",
            "info.value",
            "info.id",
            "tags",
            "tags.id",
            "tags.name",
            "label_scheme",
            "label_scheme.id",
            "label_scheme.name",
            "label_scheme.user_id",
            "parent",
            "parent.id",
            "parent.name",
            "user",
            "user.id",
            "user.username",
            "user.last_login",
            "user.first_name",
            "user.last_name",
            "user.active",
            "user.info",
            "user.role",
            "annotation_count",
            "descendant_count",
            "exemplar_annotation_sets",
            "label_scheme_custodian",
            "current_user_can_edit",
            "current_user_is_custodian"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [label](#label) object with pk field matching param `id`",
          "endpoint": "/api/label/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        checks that the class label does not have any children or annotations which may be orphaned by delete.\n        ",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": null,
          "endpoint": "/api/label/<int:id>/tag/<int:tag_id>",
          "method": "DELETE"
        },
        {
          "description": null,
          "endpoint": "/api/label/<int:id>/tag/<int:tag_id>",
          "method": "POST"
        },
        {
          "description": "\n        Get list of exemplar images for the label_scheme with the ID matching `id`. Optionally you can specify an exemplar\n        `annontation_set_id` if there are more than one for this scheme. If not `annotation_set_id` is specified.\n        All will be returned.\n        :param id:\n        :param annotation_set_id:\n        :return:\n        ",
          "endpoint": "/api/label/<int:id>/exemplars",
          "method": "GET"
        },
        {
          "description": "\n        Get list of exemplar images for the label_scheme with the ID matching `id`. Optionally you can specify an exemplar\n        `annontation_set_id` if there are more than one for this scheme. If not `annotation_set_id` is specified.\n        All will be returned.\n        :param id:\n        :param annotation_set_id:\n        :return:\n        ",
          "endpoint": "/api/label/<int:id>/exemplars/<int:annotation_set_id>",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this class label has a parent class label",
          "name": "is_child",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether this label has one or more vocab_element mappings",
          "name": "is_mapped",
          "type": "property"
        }
      ],
      "methods": [
        {
          "doc": "Number of annotations that have been assigned with this label",
          "name": "annotation_count",
          "type": "method"
        },
        {
          "doc": "Number of direct children labels nested under this label",
          "name": "descendant_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "exemplar_annotation_sets",
          "type": "method"
        },
        {
          "doc": null,
          "name": "label_scheme_custodian",
          "type": "method"
        },
        {
          "doc": null,
          "name": "current_user_can_edit",
          "type": "property"
        },
        {
          "doc": null,
          "name": "current_user_is_custodian",
          "type": "property"
        },
        {
          "doc": null,
          "name": "name_path",
          "type": "property"
        },
        {
          "doc": "Comma-delimited names of applied tags. Can also be used to set tags using comma-delimited tags when creating annotaions",
          "name": "tag_names",
          "type": "property"
        },
        {
          "doc": "Special API property returns [label](#label) object in target label scheme.\n        Requires `translate` query parameter containing `target_label_scheme_id` and optional `vocab_registry_keys`\n        parameters. See [Label Translation](#label_translation) for more information.",
          "name": "translated",
          "type": "property"
        },
        {
          "doc": "Dictionary representation of `vocab_elements` by registry key (conveniently formatted for exporting schemes)",
          "name": "vocab_registry",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "The user who owns or created this class label",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": "The annotation scheme containing this class label",
          "key": "label_scheme",
          "model": "label_scheme"
        },
        {
          "direction": "MANYTOONE",
          "doc": "The parent class label (linked observation)",
          "key": "parent",
          "model": "label"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "A list of `vocab_elements` linked to this `label`",
          "key": "vocab_elements",
          "model": "vocab_element"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "children",
          "model": "label"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "label_tags",
          "model": "label_tags"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "info",
          "model": "label_info"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "label_vocab_element",
          "model": "label_vocab_element"
        },
        {
          "direction": "ONETOMANY",
          "doc": "List of related [annotation](#annotation) objects",
          "key": "annotations",
          "model": "annotation"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "label_info",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "value",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "label.id",
          "name": "label_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Label Info resource. Attaches name-value information to [label](#label) objects.\n    ",
      "endpoints": [
        {
          "description": "Create new [label_info](#label_info) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/label_info",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [label_info](#label_info) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/label_info/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [label_info](#label_info) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/label_info",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [label_info](#label_info) object with pk field matching param `id`",
          "endpoint": "/api/label_info/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [label_info](#label_info) object with pk field matching param `id`",
          "endpoint": "/api/label_info/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "label",
          "model": "label"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "label_scheme",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foreign key reference for ID of related owner [users](#users) model",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "is_hierarchy",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Creation time (UTC)",
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "label_scheme.id",
          "name": "parent_label_scheme_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Label Scheme resource. This resource is for managing and define label schemes otherwise known as (annotation scheme,\n    taxonomic hierarchy, category lists, label lists, classification scheme)\n    ",
      "endpoints": [
        {
          "description": "Create new [label_scheme](#label_scheme) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/label_scheme",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [label_scheme](#label_scheme) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/label_scheme/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object edit permission from shared `usergroups`. Checks current_user has edit permission.",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [label_scheme](#label_scheme) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/label_scheme",
          "fields": [
            "user_id",
            "description",
            "is_hierarchy",
            "id",
            "name",
            "user",
            "user.username",
            "user.first_name",
            "user.last_name",
            "user.id",
            "label_scheme_files",
            "label_scheme_files.description",
            "label_scheme_files.file_url",
            "label_scheme_files.id",
            "label_scheme_files.name",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "is_child",
            "parent_label_scheme",
            "parent_label_scheme.id",
            "parent_label_scheme.name",
            "created_at",
            "updated_at",
            "usergroup_count",
            "annotation_set_count",
            "exemplar_annotation_set_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [label_scheme](#label_scheme) object with pk field matching param `id`",
          "endpoint": "/api/label_scheme/<id>",
          "fields": [
            "user_id",
            "description",
            "is_hierarchy",
            "id",
            "name",
            "user",
            "user.username",
            "user.first_name",
            "user.last_name",
            "user.id",
            "label_scheme_files",
            "label_scheme_files.description",
            "label_scheme_files.file_url",
            "label_scheme_files.id",
            "label_scheme_files.name",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "is_child",
            "parent_label_scheme",
            "parent_label_scheme.id",
            "parent_label_scheme.name",
            "created_at",
            "updated_at",
            "usergroup_count",
            "annotation_set_count",
            "exemplar_annotation_set_count",
            "parent_label_scheme_ids"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object view permission from shared `usergroups`. Checks current_user has view permission.",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [label_scheme](#label_scheme) object with pk field matching param `id`",
          "endpoint": "/api/label_scheme/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        checks that the scheme does not contain annotation sets or children.\n        ",
              "name": "delete_preprocessor"
            },
            {
              "doc": "Assert object delete permission from shared `usergroups`. Checks current user is owner and object is not\n        shared in a `usergroup`",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Add object with id `instance_id` to group with id `group_id`",
          "endpoint": "/api/label_scheme/<int:instance_id>/group/<int:group_id>",
          "method": "POST"
        },
        {
          "description": "Remove resource with id `instance_id` from group with id `group_id`",
          "endpoint": "/api/label_scheme/<int:instance_id>/group/<int:group_id>",
          "method": "DELETE"
        },
        {
          "description": "\n        Reset [labels](#label) parents for `label_scheme` with `id` matching `label_scheme_id`.\n        Uses `origin_code` and `parent_origin_code` to match up [labels](#label). Accepts optional query string argument\n        `replace_existing=true`, which will reset parent_ids for labels that are already set. By default this is set to `false`\n        ",
          "endpoint": "/api/label_scheme/<int:label_scheme_id>/reset_label_parents",
          "method": "PATCH"
        },
        {
          "description": "\n        Export [labels](#label) collection from [label_scheme](#label_scheme) matching `id`.\n        Search queries are executed on the [label](#label) model.\n\n        \n        Querystring parameters are:\n\n        ```?q={...}&f={...}&disposition=...&template=...&include_columns=[...]```\n\n        Where `q` is a JSON search query (see [Making API search queries](#api_query)) on the collection model,\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` defines the download type which can be `attachment` (default, triggers a download) or `inline` (displays in\n        the browser),\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `include_columns` is a JSON list of column fields for the exported model.\n        Nested fields for related models delimited with a `.`\n        If `include_columns` is omitted, all allowed columns will be returned.\n\n        Metadata for the dataset is also returned in the response. Depending on the output\n        format, this could be as part of the response body in a `metadata` field (e.g., Json) or in the response headers with the key\n        `X-Content-Metadata` (e.g., CSV or HTML).\n    \n\n        Allowed fields include:\n\n        `id`, `parent_id`, `uuid`, `name`, `color`, `user.id`, `user.full_name`, `label_scheme.id`,\n        `label_scheme.name`, `lineage_names`, `is_approved`, `tags`, `vocab_registry`,\n        `created_at`, `updated_at`, `origin_code`, `parent_origin_code`, `is_mapped`\n\n        See [label](#label) model columns, relations and attributes for more information on each of the included fields.\n\n        **TRANSLATING TO OTHER LABEL_SCHEMES**\n\n        This endpoint also supports the translation of labels from a source to a target label_scheme.\n        another label_scheme using the semantic translation framework. In order to do this, you need to specify the\n        additional `translate` url query parameter:\n\n        ```\n        &translate={\"target_label_scheme_id\":..., \"vocab_registry_keys\": ..., \"mapping_override\": ...}\n        ```\n        Where `target_label_scheme_id` [required] is an INT with the `id` of the target label scheme,\n        `vocab_registry_keys` [optional] is a list containing the priority order of keys for `vocab_registries` for\n        which to perform the semantic translation and `mapping_override` defines a set of key-value pairs containing\n        `source label.id : target label.id` for which to override the translation.\n        Note: for extended schemes, labels are translated through `tree_traversal` and no semantic translation is\n        required.\n\n        NOTE: you also need to add the `translated.*` columns to obtain the translation output. These columns are\n        ignored if no `translate` query parameter is supplied.\n\n        **EXAMPLES**\n\n        ```\n        # Example1: get all columns as an HTML table in the browser (including all labels from base scheme)\n        /api/label_scheme/7/export?template=data.html&disposition=inline\n\n        # Example2: get all columns as a downloaded CSV file (including all labels from base scheme)\n        /api/label_scheme/7/export?template=data.csv&disposition=inline\n\n        # Example3: get all columns as an HTML table in the browser, but only for labels defined in the extended scheme (not the base scheme)\n        /api/label_scheme/7/export?template=data.html&disposition=inline&q={\"filters\":[{\"name\":\"label_scheme_id\",\"op\":\"eq\",\"val\":7}]}\n\n        # Example4: get translation lookup between schemes, and only return specific columns\n        /api/label_scheme/8/export?disposition=inline&translate={\"vocab_registry_keys\":[\"worms\",\"caab\",\"catami\"],\"target_label_scheme_id\":\"7\"}\n          &include_columns=[\"label_scheme.name\",\"lineage_names\",\"name\",\"id\",\"translated.id\",\"translated.name\",\"translated.lineage_names\",\n          \"translated.translation_info\",\"translated.label_scheme.name\"]\n\n        # MORE TO COME... Need something else or an example added here, please ask...\n        ```\n        ",
          "endpoint": "/api/label_scheme/<int:label_scheme_id>/export",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/label_scheme/<int:label_scheme_id>/labels",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/label_scheme/<int:label_scheme_id>/labels/<int:label_parent_id>",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this class label has a parent class label",
          "name": "is_child",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not this object is public (i.e. shared in a public group)",
          "name": "is_public",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of this object",
          "name": "current_user_is_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member of a group that includes this object",
          "name": "current_user_is_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member with edit permission of a group that includes this object",
          "name": "current_user_is_edit_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of a group that includes this object",
          "name": "current_user_is_group_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not the current user has permission to view this object",
          "name": "current_user_can_view",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user has edit permission (owner or edit_member)",
          "name": "current_user_can_edit",
          "type": "property"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of this object",
          "name": "user_is_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member of a group that includes this object",
          "name": "user_is_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member with edit permission of a group that includes this object",
          "name": "user_is_edit_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of a group that includes this object",
          "name": "user_is_group_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Returns true is user is owner, dataset belongs to a public group, user owns a group or dataset belongs to an\n        unrestricted group that user is a member of",
          "name": "user_can_view",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user has edit permission (owner or edit_member)",
          "name": "user_can_edit",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": null,
          "name": "annotation_set_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "exemplar_annotation_set_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "label_count",
          "type": "method"
        },
        {
          "doc": null,
          "name": "usergroup_count",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Related owner [users](#users) model",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "parent_label_scheme",
          "model": "label_scheme"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "annotation_sets",
          "model": "annotation_set"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "List of [groups](#groups) objects that contain this resource",
          "key": "usergroups",
          "model": "groups"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "label_scheme_files",
          "model": "label_scheme_file"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "children",
          "model": "label_scheme"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "labels",
          "model": "label"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "label_scheme_file",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Sequence of file operations performed at last save",
          "foreign_key": null,
          "name": "last_save",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the file (optional). Defaults to `basename` of either `file_url` or the path of the uploaded file",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The URL of the file to be loaded dynamically (if `data` field is not set)",
          "foreign_key": null,
          "name": "file_url",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": false
        },
        {
          "default": null,
          "doc": "The description of the file (optional)",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The raw file storage for the file. This is not directly accessible through the API",
          "foreign_key": null,
          "name": "_rawfiledata",
          "nullable": true,
          "primary_key": false,
          "type": "LargeBinary()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Whether or not the file is compressed or not. If so, it will be automatically decompressed upon access.",
          "foreign_key": null,
          "name": "iscompressed",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "label_scheme.id",
          "name": "label_scheme_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Label Scheme File resource. Files that can be used for batch update / creation of [label](#label) objects attached\n    to [label_scheme](#label_scheme) objects.\n    ",
      "endpoints": [
        {
          "description": "Create new [label_scheme_file](#label_scheme_file) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/label_scheme_file",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [label_scheme_file](#label_scheme_file) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/label_scheme_file/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [label_scheme_file](#label_scheme_file) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/label_scheme_file",
          "fields": [
            "description",
            "iscompressed",
            "label_scheme",
            "file_url",
            "label_scheme_id",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [label_scheme_file](#label_scheme_file) object with pk field matching param `id`",
          "endpoint": "/api/label_scheme_file/<id>",
          "fields": [
            "description",
            "iscompressed",
            "label_scheme",
            "file_url",
            "label_scheme_id",
            "id",
            "name",
            "last_save"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [label_scheme_file](#label_scheme_file) object with pk field matching param `id`",
          "endpoint": "/api/label_scheme_file/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Get the data for the file resource matching `fid`. This endpoint also provides options to manipulate, transform\n        and save data to the database. The querystring takes the following form:\n        ```\n        ?f={...}&save={...}&disposition=...&template=...\n        ```\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` is optional and defines the download type which can be `inline` (default, displays in\n        the browser) or `attachment` (triggers a download) ,\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `save` is a JSON dictionary that defines batch save operations. This can be used to save the file content or the\n        output of the operations in `f` to a related database model collection.\n\n        ",
          "endpoint": "/api/label_scheme_file/<int:fid>/data",
          "method": "GET"
        },
        {
          "description": "\n        Save file data to database. Use this if it is not possible to dynamically link the file using the `file_url` or\n        if the `file_url` is potentially unstable / ephemeral. This should be a multipart form post with `file`\n        parameter set to the uploaded file and all other fields as in the object definition below.\n        ",
          "endpoint": "/api/label_scheme_file/data",
          "method": "POST"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "data",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "label_scheme",
          "model": "label_scheme"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "label_tags",
      "columns": [
        {
          "default": null,
          "doc": null,
          "foreign_key": "label.id",
          "name": "label_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "tag.id",
          "name": "tag_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "assoc_created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Label tag associations. Links suggested [tag](#tag) objects to [label](#label) objects. Provides convenience for quickly\n    assigning tags to certain labels\n    ",
      "endpoints": [
        {
          "description": "Create new [label_tags](#label_tags) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/label_tags",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [label_tags](#label_tags) object with pk field matching param `label_id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/label_tags/<label_id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [label_tags](#label_tags) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/label_tags",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [label_tags](#label_tags) object with pk field matching param `label_id`",
          "endpoint": "/api/label_tags/<label_id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [label_tags](#label_tags) object with pk field matching param `label_id`",
          "endpoint": "/api/label_tags/<label_id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "label",
          "model": "label"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "tag",
          "model": "tag"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "maplayer",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "baseurl",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "layertype",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "properties",
          "nullable": true,
          "primary_key": false,
          "type": "JSON(astext_type=Text())",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "filters",
          "nullable": true,
          "primary_key": false,
          "type": "JSON(astext_type=Text())",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "is_active",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "disabled",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "maplayer_group.id",
          "name": "maplayer_group_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Map Layer resource: defines properties of additional map layers for integration into explore interface\n    ",
      "endpoints": [
        {
          "description": "Create new [maplayer](#maplayer) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/maplayer",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [maplayer](#maplayer) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/maplayer/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [maplayer](#maplayer) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/maplayer",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [maplayer](#maplayer) object with pk field matching param `id`",
          "endpoint": "/api/maplayer/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [maplayer](#maplayer) object with pk field matching param `id`",
          "endpoint": "/api/maplayer/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "maplayer_group",
          "model": "maplayer_group"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "maplayer_group",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "pane",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "zindex",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Map Layer Group resource: defines properties of additional map layer groups for integration into explore interface\n    ",
      "endpoints": [
        {
          "description": "Create new [maplayer_group](#maplayer_group) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/maplayer_group",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [maplayer_group](#maplayer_group) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/maplayer_group/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [maplayer_group](#maplayer_group) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/maplayer_group",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [maplayer_group](#maplayer_group) object with pk field matching param `id`",
          "endpoint": "/api/maplayer_group/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [maplayer_group](#maplayer_group) object with pk field matching param `id`",
          "endpoint": "/api/maplayer_group/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "maplayers",
          "model": "maplayer"
        }
      ]
    },
    {
      "association_proxies": [
        {
          "model": "media_collection",
          "name": "media_collections",
          "target_collection": "media_collection_media"
        }
      ],
      "collection": "media",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "path",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "path_thm",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": "True",
          "doc": null,
          "foreign_key": null,
          "name": "is_valid",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "deployment.id",
          "name": "deployment_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media_type.id",
          "name": "media_type_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp_start",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media.id",
          "name": "parent_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Media resource: a generic media object definition that can be used to link in media in a variety of formats,\n    including images, videos, photo-mosaics and other media formats. Note that at the moment only images and video\n    framegrabs have annotation support. Annotation viewers for video and mosaics coming soon.\n    ",
      "endpoints": [
        {
          "description": "Update single [media](#media) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/media/<id>",
          "method": "PATCH",
          "postprocessors": [
            {
              "doc": "Clears the request cache object for this resource (to cause cache refresh on next request)",
              "name": "_clear_cache"
            }
          ],
          "preprocessors": [
            {
              "doc": "Restrict request to object OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [media](#media) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/media",
          "fields": [
            "created_at",
            "timestamp_start",
            "is_valid",
            "key",
            "deployment",
            "deployment.id",
            "deployment.key",
            "campaign",
            "campaign.id",
            "campaign.key",
            "deployment_id",
            "data",
            "id",
            "media_type",
            "media_type.id",
            "media_type.name",
            "path_best",
            "path_best_thm",
            "event_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [media](#media) object with pk field matching param `id`",
          "endpoint": "/api/media/<id>",
          "fields": [
            "created_at",
            "timestamp_start",
            "is_valid",
            "key",
            "deployment",
            "deployment.id",
            "deployment.key",
            "campaign",
            "campaign.id",
            "campaign.key",
            "deployment_id",
            "data",
            "id",
            "media_type",
            "media_type.id",
            "media_type.name",
            "path_best",
            "path_best_thm",
            "event_count",
            "current_user_can_edit"
          ],
          "method": "GET",
          "postprocessors": [
            {
              "doc": null,
              "name": "get_single_postprocessor"
            }
          ],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [media](#media) object with pk field matching param `id`",
          "endpoint": "/api/media/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": null,
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": null,
          "endpoint": "/api/media/<int:media_id>/annotations/<int:annotation_set_id>",
          "method": "GET"
        },
        {
          "description": "\n        Media UPLOAD resource.\n\n        Used to upload Media to predefined location set out in server config file.\n\n        `file`: file data input containing image file to upload.\n        `json`: json string containing parameters for new [media](#media) item\n        ",
          "endpoint": "/api/media/save",
          "method": "POST"
        },
        {
          "description": "\n        In addition to the `MODEL COLUMNS` below, the JSON body can contain the following parameters:\n        `pose`: a dict containing parameters for a single [pose](#pose) including associated pose data,\n        `poses`: a list of dicts as above if linking multiple poses to a single media object (eg: video),\n        `media_type`: OPTIONAL (default=\"image\"), a string containing the [media_type](#media_type) name.\n\n        Here are some example payloads for creating [media](#media) objects:\n        ```\n        # example JSON payload for media item with a single pose (eg: still image)\n        {\n            \"pose\": {\"lat\":-35.53153264, \"lon\":150.43962917, \"alt\":3.558, \"dep\":28.85, \"data\":[\n                {\"name\":\"temperature\",\"value\":16.602},\n                {\"name\":\"salinity\",\"value\":35.260222}\n            ]},\n            \"key\": \"PR_20101117_002241_698_LC16\",\n            \"deployment_id\": 5,\n            \"timestamp_start\": \"2018-06-07T00:47:17.273514\"\n        }\n\n        # Same as above, but with dict data\n        {\n            \"pose\": {\"lat\":-35.53153264, \"lon\":150.43962917, \"alt\":3.558, \"dep\":28.85, \"data\":{\n                \"temperature\":16.602,\n                \"salinity\":35.260222\n            }},\n            \"key\": \"TEST_20101117_002241_698_LC16\",\n            \"deployment_id\": 13170,\n            \"timestamp_start\": \"2018-06-07T00:47:17.273514\"\n        }\n\n        # To add multiple poses to a media object (i.e. video)\n        {\n            \"poses\":\n                [{\n                    \"timestamp\": \"2018-06-07T00:47:17.273517\",\n                    \"lat\":-35.53153264,\n                    \"lon\":150.43962917,\n                    \"alt\":3.558,\n                    \"dep\":28.85,\n                    \"data\":{\n                        \"temperature\":16.602,\n                        \"salinity\":35.260222\n                    }\n                },{\n                    \"timestamp\": \"2018-06-07T00:47:18.273517\",\n                    \"lat\":-35.531532654,\n                    \"lon\":150.439629345,\n                    \"alt\":6.558,\n                    \"dep\":29.85,\n                    \"data\":{\n                        \"temperature\":16.602,\n                        \"salinity\":35.260222\n                    }\n                },{\n                    \"timestamp\": \"2018-06-07T00:47:19.273517\",\n                    \"lat\":-35.531534564,\n                    \"lon\":150.43962934,\n                    \"alt\":4.558,\n                    \"dep\":28.85,\n                    \"data\":{\n                        \"temperature\":16.60256,\n                        \"salinity\":35.260234\n                    }\n                }],\n            \"key\": \"KEY_OF_VIDEO_FILE_NAME\",\n            \"deployment_id\": 13170,\n            \"timestamp_start\": \"2018-06-07T00:47:17.273514\",\n            \"media_type\": \"rawvideo\"\n        }\n        ```\n        ",
          "endpoint": "/api/media",
          "method": "POST"
        },
        {
          "description": "\n        The list of [pose](#pose) for the [media](#media) item matching `id`. For still images, it will normally just\n        be a single [pose](#pose), but video-like [media_types](#media_type) can have more.\n        ",
          "endpoint": "/api/media/<int:id>/poses",
          "method": "GET"
        },
        {
          "description": "\n        Dynamically create and serve thumbnail.\n\n        If user is logged in, then they can request different sizes.\n        ",
          "endpoint": "/api/media/<int:id>/thumbnail",
          "method": "GET"
        },
        {
          "description": "Download media object with associated metadata as a zip file",
          "endpoint": "/api/media/<int:id>/download",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": null,
          "name": "geom",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not this has a parent",
          "name": "is_child",
          "type": "property"
        },
        {
          "args": [
            "annotation_set_id"
          ],
          "doc": "BOOL, whether or not the [media object](#media) contains unlabeled annotations from the\n        [annotation_set](annotation_set) with the id `annotation_set_id`",
          "name": "has_unlabeled_annotations",
          "type": "method"
        },
        {
          "args": [
            "annotation_set_id"
          ],
          "doc": "BOOL, whether or not the [media object](#media) contains points from the\n        [annotation_set](annotation_set) with the id `annotation_set_id`",
          "name": "has_points",
          "type": "method"
        },
        {
          "args": [
            "annotation_set_id"
          ],
          "doc": "BOOL, whether or not the [media object](#media) contains any annotations from the\n        [annotation_set](annotation_set) with the id `annotation_set_id`",
          "name": "has_annotations",
          "type": "method"
        },
        {
          "args": [
            "lat",
            "lon"
          ],
          "doc": "FLOAT, distance (in meters) of closest linked [pose](#pose) relative to `lat` and `lon` (which are both in decimal degrees)",
          "name": "distance",
          "type": "method"
        },
        {
          "args": [
            "ts"
          ],
          "doc": "Absolute difference in seconds of the in-situ timestamp and input `ts`, which is datetime string\n        eg: `\"2020-09-25T00:57:11.945009\"` (or in a format that is parsable by `dateutil.parser.parse`)",
          "name": "timestamp_proximity",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": "Whether or not the current user owns the deployment and can edit this media item",
          "name": "current_user_can_edit",
          "type": "method"
        },
        {
          "doc": null,
          "name": "event_log",
          "type": "method"
        },
        {
          "doc": null,
          "name": "color",
          "type": "property"
        },
        {
          "doc": "BOOL, whether or not the [media object](#media) contains any logged [deployment_events](#deployment_event)",
          "name": "event_count",
          "type": "property"
        },
        {
          "doc": null,
          "name": "path_best",
          "type": "property"
        },
        {
          "doc": null,
          "name": "path_best_thm",
          "type": "property"
        },
        {
          "doc": "Height of media item in pixels. Not implemented yet...",
          "name": "pixel_height",
          "type": "property"
        },
        {
          "doc": "Width of media item in pixels. Not implemented yet...",
          "name": "pixel_width",
          "type": "property"
        },
        {
          "doc": "\n        The first pose from related `poses` or if child media item, it gets the closest matching pose from the\n        `parent_media` item based on `timestamp_start`\n        ",
          "name": "pose",
          "type": "property"
        },
        {
          "doc": "LOCAL datetime, converted using `pose.lat`, `pose.lon` and `timestamp_start`",
          "name": "timestamp_start_local",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "deployment",
          "model": "deployment"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media_type",
          "model": "media_type"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "parent",
          "model": "media"
        },
        {
          "direction": "ONETOMANY",
          "doc": "List of [point](#point) objects",
          "key": "annotations",
          "model": "point"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "poses",
          "model": "pose"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "children",
          "model": "media"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "media_collection_media",
          "model": "media_collection_media"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "events",
          "model": "deployment_event"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "media_collection",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the `media_collection`",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": "A concise description of the `media_collection`",
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "A reference to the ID of a parent `media_collection`",
          "foreign_key": "media_collection.id",
          "name": "parent_collection_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "The creation date-time",
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foreign key reference for ID of related owner [users](#users) model",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Media Collection resource: a user-defined collection of [media](#media) objects grouped for further analysis.\n    Can be a subset of [media](#media) objects from one or more [deployments](#deployment)\n    ",
      "endpoints": [
        {
          "description": "Create new [media_collection](#media_collection) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/media_collection",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [media_collection](#media_collection) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/media_collection/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object edit permission from shared `usergroups`. Checks current_user has edit permission.",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [media_collection](#media_collection) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/media_collection",
          "fields": [
            "id",
            "name",
            "parent_collection_id",
            "description",
            "user",
            "created_at",
            "user.id",
            "user.first_name",
            "user.last_name",
            "user.username",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "usergroup_count",
            "annotation_set_count",
            "media_count"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [media_collection](#media_collection) object with pk field matching param `id`",
          "endpoint": "/api/media_collection/<id>",
          "fields": [
            "id",
            "name",
            "parent_collection_id",
            "description",
            "user",
            "created_at",
            "user.id",
            "user.first_name",
            "user.last_name",
            "user.username",
            "current_user_can_view",
            "current_user_is_owner",
            "current_user_is_member",
            "current_user_can_edit",
            "is_public",
            "usergroup_count",
            "annotation_set_count",
            "media_count",
            "data",
            "extent"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object view permission from shared `usergroups`. Checks current_user has view permission.",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [media_collection](#media_collection) object with pk field matching param `id`",
          "endpoint": "/api/media_collection/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Assert object delete permission from shared `usergroups`. Checks current user is owner and object is not\n        shared in a `usergroup`",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "\n        Add instance with ID of `instance_id` to the group with the ID `group_id`\n        ",
          "endpoint": "/api/media_collection/<int:instance_id>/group/<int:group_id>",
          "method": "POST"
        },
        {
          "description": "Remove resource with id `instance_id` from group with id `group_id`",
          "endpoint": "/api/media_collection/<int:instance_id>/group/<int:group_id>",
          "method": "DELETE"
        },
        {
          "description": "\n        Export [media](#media) collection from [media_collection](#media_collection) matching `id`.\n        Search queries are executed on the [media](#media) model.\n\n        \n        Querystring parameters are:\n\n        ```?q={...}&f={...}&disposition=...&template=...&include_columns=[...]```\n\n        Where `q` is a JSON search query (see [Making API search queries](#api_query)) on the collection model,\n        where `f` is a JSON dictionary containing a sequence of operations for transforming the data\n        (see [Data transformation API](#api_data_transform) for more info),\n        `disposition` defines the download type which can be `attachment` (default, triggers a download) or `inline` (displays in\n        the browser),\n        `template` is optional depending on the output of the steps in `f` and can be used to define the export format,\n        `include_columns` is a JSON list of column fields for the exported model.\n        Nested fields for related models delimited with a `.`\n        If `include_columns` is omitted, all allowed columns will be returned.\n\n        Metadata for the dataset is also returned in the response. Depending on the output\n        format, this could be as part of the response body in a `metadata` field (e.g., Json) or in the response headers with the key\n        `X-Content-Metadata` (e.g., CSV or HTML).\n    \n\n        Allowed columns include: `id`, `key`, `timestamp_start`, `path_best`,  `path_best_thm`, `pose.timestamp`, `pose.lat`,\n            `pose.lon`, `pose.alt`, `pose.dep`, `pose.data`, `pose.id`, `deployment.key`,\n            `deployment.campaign.key`, `deployment.id`, `deployment.campaign.id`, `event_log`\n\n        ```\n        # Example1:\n        /api/media_collection/1776/export?template=dataframe.csv&f={\"operations\": [{\"module\": \"pandas\", \"method\": \"json_normalize\"}]}\n        ```\n\n        NB: the UI contains an \"ADVANCED\" option which can help build more complex export queries.\n        ",
          "endpoint": "/api/media_collection/<int:id>/export",
          "method": "GET"
        },
        {
          "description": "\n        Get list of [media](#media) objects contained in the [media_collection](#media_collection) with an ID matching `media_collection_id`.\n        Accepts search query parameters. See [Making API search queries](#api_query) for instructions on making search queries\n        ",
          "endpoint": "/api/media_collection/<int:media_collection_id>/media",
          "method": "GET"
        },
        {
          "description": "\n        Add [media](#media) objects matching the search query defined in the json post parameter `q` to the [media_collection](#media_collection)\n        with an ID matching `media_collection_id`. `q` is a search query in the format defined in [Making API search queries](#api_query) section\n        and is sent as either a URL parameter or form post parameter.\n        Request returns the corresponding [media_collection](#media_collection).\n        ",
          "endpoint": "/api/media_collection/<int:media_collection_id>/media",
          "method": "POST"
        },
        {
          "description": "\n        Get the single [media](#media) object with the ID `media_id` from the [media_collection](#media_collection) with the ID `media_collection_id`\n        ",
          "endpoint": "/api/media_collection/<int:media_collection_id>/media/<int:media_id>",
          "method": "GET"
        },
        {
          "description": "\n        Add the [media](#media) object with the ID `media_id` to the [media_collection](#media_collection) with the ID `media_collection_id`\n        ",
          "endpoint": "/api/media_collection/<int:media_collection_id>/media/<int:media_id>",
          "method": "POST"
        },
        {
          "description": "\n        Remove the [media](#media) object with the ID `media_id` from the [media_collection](#media_collection) with the ID `media_collection_id`\n        ",
          "endpoint": "/api/media_collection/<int:media_collection_id>/media/<int:media_id>",
          "method": "DELETE"
        },
        {
          "description": "Get any shared `[group_dashboards](group_dashboard)` for this resource",
          "endpoint": "/api/media_collection/<int:id>/dashboards",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "Number of Media objects in this Media Collection",
          "name": "media_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Number of annotation_sets in this Media Collection",
          "name": "annotation_set_count",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not this object is public (i.e. shared in a public group)",
          "name": "is_public",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of this object",
          "name": "current_user_is_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member of a group that includes this object",
          "name": "current_user_is_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is a member with edit permission of a group that includes this object",
          "name": "current_user_is_edit_member",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user is the owner of a group that includes this object",
          "name": "current_user_is_group_owner",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether or not the current user has permission to view this object",
          "name": "current_user_can_view",
          "type": "property"
        },
        {
          "args": [],
          "doc": "Whether the current logged in user has edit permission (owner or edit_member)",
          "name": "current_user_can_edit",
          "type": "property"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of this object",
          "name": "user_is_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member of a group that includes this object",
          "name": "user_is_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is a member with edit permission of a group that includes this object",
          "name": "user_is_edit_member",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user is the owner of a group that includes this object",
          "name": "user_is_group_owner",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Returns true is user is owner, dataset belongs to a public group, user owns a group or dataset belongs to an\n        unrestricted group that user is a member of",
          "name": "user_can_view",
          "type": "method"
        },
        {
          "args": [
            "user_id"
          ],
          "doc": "Whether the specified user has edit permission (owner or edit_member)",
          "name": "user_can_edit",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": "\n        Compute spatial extent of Media Collection\n        :return: list with format [[SW_LAT, SW_LON],[NE_LAT,NE_LON]]\n        ",
          "name": "extent",
          "type": "method"
        },
        {
          "doc": null,
          "name": "usergroup_count",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "The parent `media_collection` instance",
          "key": "parent",
          "model": "media_collection"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "A list of `media` contained in this `media_collection`",
          "key": "media",
          "model": "media"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Related owner [users](#users) model",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "List of [groups](#groups) objects that contain this resource",
          "key": "usergroups",
          "model": "groups"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "annotation_sets",
          "model": "annotation_set"
        },
        {
          "direction": "ONETOMANY",
          "doc": "A list of childen `media_collections` that belong to this one",
          "key": "children",
          "model": "media_collection"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "media_collection_media",
          "model": "media_collection_media"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "media_collection_media",
      "columns": [
        {
          "default": null,
          "doc": null,
          "foreign_key": "media.id",
          "name": "media_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media_collection.id",
          "name": "media_collection_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Media Collection Media Associate resource: a model for associating a subset of [media](#media) objects to a\n    [media_collection](#media_collection)\n    ",
      "endpoints": [
        {
          "description": "Create new [media_collection_media](#media_collection_media) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/media_collection_media",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": null,
              "name": "edit_auth_preprocessor"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [media_collection_media](#media_collection_media) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/media_collection_media",
          "fields": [
            "created_at",
            "media_id",
            "media_collection_id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [media_collection_media](#media_collection_media) object with pk field matching param `media_collection_id`",
          "endpoint": "/api/media_collection_media/<media_collection_id>",
          "fields": [
            "created_at",
            "media_id",
            "media_collection_id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [media_collection_media](#media_collection_media) object with pk field matching param `media_collection_id`",
          "endpoint": "/api/media_collection_media/<media_collection_id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": null,
              "name": "edit_auth_preprocessor"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media",
          "model": "media"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media_collection",
          "model": "media_collection"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "media_type",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The name of the media type",
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        }
      ],
      "description": "\n    Media Type resource: a modifier denoting the type for a [media](#media) resource. This is associated with\n    ",
      "endpoints": [
        {
          "description": "Create new [media_type](#media_type) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/media_type",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [media_type](#media_type) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/media_type",
          "fields": [
            "id",
            "name"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [media_type](#media_type) object with pk field matching param `id`",
          "endpoint": "/api/media_type/<id>",
          "fields": [
            "id",
            "name"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [media_type](#media_type) object with pk field matching param `id`",
          "endpoint": "/api/media_type/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "media",
          "model": "media"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "platform",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "reference",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Platform resource: the equipment/method used to collect the imagery data (eg: a specific AUV, ROV or camera platform)\n    ",
      "endpoints": [
        {
          "description": "Create new [platform](#platform) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/platform",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [platform](#platform) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/platform/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [platform](#platform) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/platform",
          "fields": [
            "created_at",
            "description",
            "id",
            "name",
            "reference",
            "user_id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [platform](#platform) object with pk field matching param `id`",
          "endpoint": "/api/platform/<id>",
          "fields": [
            "created_at",
            "description",
            "id",
            "name",
            "reference",
            "user_id",
            "datasources",
            "data"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [platform](#platform) object with pk field matching param `id`",
          "endpoint": "/api/platform/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "current_user_is_owner",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "deployments",
          "model": "deployment"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "datasources",
          "model": "datasource"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "layers",
          "model": "platform_maplayer"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "platform_maplayer",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "baseurl",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=255)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "layertype",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "minzoom",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "properties",
          "nullable": true,
          "primary_key": false,
          "type": "JSON(astext_type=Text())",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "platform.id",
          "name": "platform_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Platform Map Layer resource: defines properties of additional map layers for each platform filtered by configurable parameters\n    ",
      "endpoints": [
        {
          "description": "Create new [platform_maplayer](#platform_maplayer) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/platform_maplayer",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [platform_maplayer](#platform_maplayer) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/platform_maplayer/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [platform_maplayer](#platform_maplayer) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/platform_maplayer",
          "fields": [
            "id",
            "name",
            "baseurl",
            "layertype",
            "minzoom",
            "properties",
            "platform",
            "platform.id",
            "platform.name",
            "platform.key",
            "platform.description"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [platform_maplayer](#platform_maplayer) object with pk field matching param `id`",
          "endpoint": "/api/platform_maplayer/<id>",
          "fields": [
            "id",
            "name",
            "baseurl",
            "layertype",
            "minzoom",
            "properties",
            "platform",
            "platform.id",
            "platform.name",
            "platform.key",
            "platform.description"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [platform_maplayer](#platform_maplayer) object with pk field matching param `id`",
          "endpoint": "/api/platform_maplayer/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "platform",
          "model": "platform"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "point",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "{}",
          "doc": "Text field containing JSON properties for this resource",
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": "X location of point as a proportion across the frame width (0-1.0, measured from the left, positive right) or `latitude` for map objects",
          "foreign_key": null,
          "name": "x",
          "nullable": true,
          "primary_key": false,
          "type": "Float(precision=53)",
          "unique": false
        },
        {
          "default": null,
          "doc": "Y location of point as a proportion across the frame height (0-1.0, measured from the top, positive down) or `longitude` for map objects",
          "foreign_key": null,
          "name": "y",
          "nullable": true,
          "primary_key": false,
          "type": "Float(precision=53)",
          "unique": false
        },
        {
          "default": null,
          "doc": "Number of seconds of annotation relative to `media.start_time` (eg: for video)",
          "foreign_key": null,
          "name": "t",
          "nullable": true,
          "primary_key": false,
          "type": "Float(precision=53)",
          "unique": false
        },
        {
          "default": null,
          "doc": "Foreign key `id` of [media](#media) object linked to [point](#point)",
          "foreign_key": "media.id",
          "name": "media_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": "Foreign key `id` of the parent/origin [annotation_set](#annotation_set). I.e.: the one linked to the initial creation of the [point](#point)",
          "foreign_key": "annotation_set.id",
          "name": "annotation_set_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        },
        {
          "default": "False",
          "doc": "Flag denoting whether the Point was manually created to target a specific object",
          "foreign_key": null,
          "name": "is_targeted",
          "nullable": true,
          "primary_key": false,
          "type": "BOOLEAN()",
          "unique": null
        }
      ],
      "description": "\n    Annotation Point resource: an annotatable object on a media frame, captures x,y,t and can have multiple\n    [annotations](#annotation) associated with it. A [point](#point) can also be associated with a bounding box,\n    polygon, pixel map, etc... Each [point](#point) can have one or more [annotations](#annotation).\n    ",
      "endpoints": [
        {
          "description": "Update single [point](#point) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/point/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [point](#point) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/point",
          "fields": [
            "media_id",
            "annotation_set_id",
            "t",
            "x",
            "y",
            "supplementary_annotations",
            "data",
            "id",
            "timestamp",
            "annotations",
            "annotations.id",
            "annotations.annotation_set_id",
            "updated_at",
            "is_targeted",
            "has_polygon"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "\n        Filter results based on permissions from parent [annotation_set](#annotation_set)\n        ",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [point](#point) object with pk field matching param `id`",
          "endpoint": "/api/point/<id>",
          "fields": [
            "media_id",
            "annotation_set_id",
            "t",
            "x",
            "y",
            "supplementary_annotations",
            "data",
            "id",
            "timestamp",
            "annotations",
            "annotations.id",
            "annotations.annotation_set_id",
            "updated_at",
            "is_targeted",
            "has_polygon"
          ],
          "method": "GET",
          "postprocessors": [
            {
              "doc": "Adds `annotations` and `supplementary_annotations` fields to the response",
              "name": "get_single_postprocessor"
            }
          ],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [point](#point) object with pk field matching param `id`",
          "endpoint": "/api/point/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Enforce implied permissions from parent [annotation_set](#annotation_set)",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Custom post endpoint",
          "endpoint": "/api/point",
          "method": "POST"
        },
        {
          "description": "\n        Dynamically create and serve thumbnail.\n\n        If user is logged in, then they can request different sizes.\n        ",
          "endpoint": "/api/point/<int:id>/thumbnail",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": "The in-situ timestamp for when the annotated object was captured/sampled in the media frame.\n        Returns `media.timestamp_start + t` if `t` is set, otherwise it just returns `media.timestamp_start` ",
          "name": "timestamp",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not the point has x-y coordinates. If `false`, it is a whole-frame annotation, not a point annotation",
          "name": "has_xy",
          "type": "property"
        },
        {
          "args": [],
          "doc": "BOOLEAN, whether or not the point has a polygon defined",
          "name": "has_polygon",
          "type": "property"
        },
        {
          "args": [
            "x",
            "y"
          ],
          "doc": "FLOAT, euclidean distance to `x` and `y` (which are proportions of the image width and height)",
          "name": "xy_distance",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": "Returns bbox size in format [left, top, right, bottom] in relative coordinates, normalized to [0,1]",
          "name": "bbox",
          "type": "method"
        },
        {
          "doc": "**Returns** list of dicts `[{annotation_id:...,label_id:...}, ...]`\n\n        **SETTER** used to set a label based on lookup condition / parameters during batch annotation importing.\n        Parameters are passed by scalar value with query string properties or by setting value as dict.\n        The property value can be `scalar`, `dict`, `list of dicts` or `list of scalars`.\n\n        **Examples**\n        ```\n        # using a query\n        point.annotation_label = {\"filters\":[{\"name\":...,\"op\":...,\"val\":...}],\"comment\":...,\"likelihood\":...,\"needs_review\":...}\n        # using the origin code for the label\n        point.annotation_label = {\"origin_code\":...,\"comment\":...,\"likelihood\":...,\"needs_review\":...}\n        # using the label UUID\n        point.annotation_label = {\"uuid\":...,\"comment\":...,\"likelihood\":...,\"needs_review\":...}\n        # using the label ID (fastest)\n        point.annotation_label = {\"id\":...,\"comment\":...,\"likelihood\":...,\"needs_review\":...}\n        # To set multiple annotation labels per point, formulate dicts as above but combine in a list:\n        point.annotation_label = [{...}, ...]\n        ```\n        where `comment`, `likelihood` and `needs_review` are optional. Label search can be done using `origin_code`,\n        `uuid`, `id` and/or defining `filters`, which is a list of filter objects for the [label](#label) resource.\n        See [Making API search queries](#api_query).\n\n        Coming soon: setting labels using semantic translation (or vocab elements)\n        ",
          "name": "annotation_label",
          "type": "property"
        },
        {
          "doc": "Use to convert between native normalised `x`, `y` and `polygon` to pixel coordinates from top left.\n\n        **Returns** `x`, `y` and `polygon` converted to `col`, `row` and `polygon` values in pixel coordinates from top\n        left of frame using the pixel width and height of the\n        associated [media](#media) object and are set by the model definition as per the `pixel_width`\n        and `pixel_height` properties defined in the [media](#media) object resource, but\n        can be overridden by url parameters: `&pixel_width=<int:width>&pixel_height=<int:height>`.\n\n        **SETTER** convert from pixel coordinates `col`, `row` and `polygon` to to native normalised coords.\n        As above, pixel with and height can be overridden by the url parameters:\n        `&pixel_width=<int:width>&pixel_height=<int:height>`, and in addition, they can be set by dict parameters\n        `width` and `height`. If no `row` or `col` are defined, a centroid point is automatically computed for the `polygon`.\n        See examples below.\n\n        **Examples**\n        ```\n        # Convert x and y pixels to proportions using url params\n        # URL QS params &pixel_width=<int:width>&pixel_height=<int:height>\n        point.pixels = {\"col\":...,\"row\":...}\n        # Convert x and y pixels to proportions using property imports for each row/entry\n        point.pixels = {\"col\":...,\"row\":...,\"width\":...,\"height\":...}\n        # As above, but include a polygon in pixel coordinates that also needs to be converted\n        point.pixels = {..., \"polygon\": [[p1x, p1y],...]}\n        ```\n        where `col` and `row` are the point coordinates in pixels from the top-left of the frame.\n        `polygon` is optional and defines a list of lists containing x-y coordinates of polygon in pixels from top-left\n        of the frame.\n        ",
          "name": "pixels",
          "type": "property"
        },
        {
          "doc": "List of lists containing coordinated of vertices for polygons. Coordinates are in proportions of the image (0-1.0).\n        For point annotations, measurements are relative to point's xy location. For whole-frame annotations, they are absolute.\n        When setting this property, it can be a list of lists or a JSON string which will automatically be converted to a list of lists.",
          "name": "polygon",
          "type": "property"
        },
        {
          "doc": "Get closest linked pose to timestamp",
          "name": "pose",
          "type": "property"
        },
        {
          "doc": "**Returns** `media.key`\n\n        **SETTER** used to link the [media](#media) object to the point annotation during batch annotation importing.\n        If the matched [media](#media) object is not already in the associated [media_collection](#media_collection),\n        it is added. Matching is done on `media.key` and optionally `deployment.key` or `deployment.id`. Matching on\n        `media.key` can be very slow, plus it is not always guaranteed to be unique, so it is highly recommended you\n        include deployment info. If multiple matches are found, it will raise an error.\n        Deployment info can be set as a dict property or as a query string parameter.\n\n        **Examples**\n        ```\n        # Set media key as a scalar and use deployment ID from query string\n        # URL QS params: &deployment_id=407\n        point.set_media = \"PR_20150301_220629_593_LC16\"\n        # Set media key as a scalar and use deployment key from query string\n        # URL QS params: &deployment_key=r20150301_211555_01_TF_ABCDE_South_West_Mew_Stone\n        point.set_media = \"PR_20150301_220629_593_LC16\"\n        # Set media key and deployment key as dict\n        point.set_media = {\"key\":\"PR_20150301_220629_593_LC16\", \"deployment_key\":\"r20150301_211555_01_TF_ABCDE_South_West_Mew_Stone\"}\n        ```\n        ",
          "name": "set_media",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "Related [media](#media) object",
          "key": "media",
          "model": "media"
        },
        {
          "direction": "MANYTOONE",
          "doc": "Parent/origin [annotation_set](#annotation_set) object",
          "key": "annotation_set",
          "model": "annotation_set"
        },
        {
          "direction": "ONETOMANY",
          "doc": "List of [annotation](#annotation) objects",
          "key": "annotations",
          "model": "annotation"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "pose",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "lat",
          "nullable": true,
          "primary_key": false,
          "type": "Float(precision=53)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "lon",
          "nullable": true,
          "primary_key": false,
          "type": "Float(precision=53)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "alt",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "dep",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "timestamp",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "media.id",
          "name": "media_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "geom",
          "nullable": true,
          "primary_key": false,
          "type": "Geometry(geometry_type='POINT', srid=4326, from_text='ST_GeomFromEWKT', name='geometry')",
          "unique": null
        }
      ],
      "description": "\n    Pose resource: associates nav / sensor data to a [media](#media) item.\n    ",
      "endpoints": [
        {
          "description": "Create new [pose](#pose) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/pose",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [pose](#pose) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/pose",
          "fields": [
            "id",
            "dep",
            "alt",
            "lat",
            "lon",
            "events",
            "timestamp",
            "media",
            "media.key",
            "media.id",
            "media.timestamp_start",
            "media.path_best_thm",
            "deployment",
            "campaign",
            "platform",
            "color",
            "media.path_best_thm",
            "data"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [pose](#pose) object with pk field matching param `id`",
          "endpoint": "/api/pose/<id>",
          "fields": [
            "id",
            "dep",
            "alt",
            "lat",
            "lon",
            "events",
            "timestamp",
            "media",
            "media.key",
            "media.id",
            "media.timestamp_start",
            "media.path_best_thm",
            "deployment",
            "campaign",
            "platform",
            "color",
            "media.path_best_thm",
            "data"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [pose](#pose) object with pk field matching param `id`",
          "endpoint": "/api/pose/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get stats for a pose. Accepts `q={}` filter parameters on pose object.\n        Returns a dictionary with the following keys: `dep_min`, `dep_max`, `dep_avg`, `alt_min`, `alt_max`, `alt_avg`, `lat_min`, `lat_max`, `lon_min`, `lon_max`.\n        If qs param `extended=true` is set, it also returns `count`, `ts_min`, `ts_max` and `media_count`.\n        ",
          "endpoint": "/api/pose/stats",
          "method": "GET"
        }
      ],
      "hybrid_properties": [
        {
          "args": [
            "lat",
            "lng"
          ],
          "doc": "FLOAT, distance (in meters) to `lat` and `lon` (which are both in decimal degrees)",
          "name": "distance",
          "type": "method"
        },
        {
          "args": [
            "lat",
            "lon"
          ],
          "doc": null,
          "name": "proximity",
          "type": "method"
        },
        {
          "args": [
            "ts"
          ],
          "doc": "Absolute difference in seconds of the in-situ timestamp and input `ts`, which is datetime string\n        eg: `\"2020-09-25T00:57:11.945009\"` (or in a format that is parsable by `dateutil.parser.parse`)",
          "name": "timestamp_proximity",
          "type": "method"
        }
      ],
      "methods": [
        {
          "doc": null,
          "name": "campaign",
          "type": "property"
        },
        {
          "doc": null,
          "name": "color",
          "type": "property"
        },
        {
          "doc": "Properties for related [pose](#pose) item including any linked [posedata](#posedata) fields",
          "name": "data",
          "type": "property"
        },
        {
          "doc": null,
          "name": "deployment",
          "type": "property"
        },
        {
          "doc": null,
          "name": "platform",
          "type": "property"
        },
        {
          "doc": "LOCAL datetime, converted using `lat`, `lon` and `timestamp`. SETTER converts Local to UTC",
          "name": "timestamp_local",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "media",
          "model": "media"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "_data",
          "model": "posedata"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "events",
          "model": "deployment_event"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "posedata",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "value",
          "nullable": true,
          "primary_key": false,
          "type": "Float()",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "pose.id",
          "name": "pose_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Pose Data resource: enables linking of name-value data to [pose](#pose) objects. This can be used to attach additional\n    sensor information to each [pose](#pose) object (and by proxy to each [media](#media) object)\n    ",
      "endpoints": [
        {
          "description": "Create new [posedata](#posedata) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/posedata",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [posedata](#posedata) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/posedata",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [posedata](#posedata) object with pk field matching param `id`",
          "endpoint": "/api/posedata/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [posedata](#posedata) object with pk field matching param `id`",
          "endpoint": "/api/posedata/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "pose",
          "model": "pose"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "roles",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        }
      ],
      "description": "\n    Not implemented yet. Not in use.\n    ",
      "endpoints": [
        {
          "description": "Create new [roles](#roles) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/roles",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [roles](#roles) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/roles/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [roles](#roles) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/roles",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [roles](#roles) object with pk field matching param `id`",
          "endpoint": "/api/roles/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [roles](#roles) object with pk field matching param `id`",
          "endpoint": "/api/roles/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": []
    },
    {
      "association_proxies": [
        {
          "model": "label",
          "name": "labels",
          "target_collection": "label_tags"
        }
      ],
      "collection": "tag",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "tag_type.id",
          "name": "type_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "tag.id",
          "name": "synonym_tag_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    Tag resource. Suggested tags can linked to class labels [label](#label) and tags can be assigned to annotations [annotation](#annotation)\n    ",
      "endpoints": [
        {
          "description": "Create new [tag](#tag) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/tag",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": null,
              "name": "post_preprocessor"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [tag](#tag) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/tag/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [tag](#tag) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/tag",
          "fields": [
            "user_id",
            "name",
            "type_id",
            "synonym_tag_id",
            "type",
            "id",
            "is_synonym",
            "type",
            "synonyms",
            "synonyms.name",
            "synonyms.id",
            "synonyms.user_id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [tag](#tag) object with pk field matching param `id`",
          "endpoint": "/api/tag/<id>",
          "fields": [
            "user_id",
            "name",
            "type_id",
            "synonym_tag_id",
            "type",
            "id",
            "is_synonym",
            "type",
            "synonyms",
            "synonyms.name",
            "synonyms.id",
            "synonyms.user_id"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [tag](#tag) object with pk field matching param `id`",
          "endpoint": "/api/tag/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [
        {
          "args": [],
          "doc": null,
          "name": "is_synonym",
          "type": "property"
        }
      ],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "type",
          "model": "tag_type"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "synonym_tag",
          "model": "tag"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "synonyms",
          "model": "tag"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "label_tags",
          "model": "label_tags"
        },
        {
          "direction": "ONETOMANY",
          "doc": "Collection of [annotation_tags](#annotation_tags) associations",
          "key": "annotation_tags",
          "model": "annotation_tags"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "tag_type",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        }
      ],
      "description": "\n    Tag Type resource. A modifier denoting the type for a [tag](#tag) resource.\n    ",
      "endpoints": [
        {
          "description": "Create new [tag_type](#tag_type) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/tag_type",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [tag_type](#tag_type) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/tag_type/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [tag_type](#tag_type) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/tag_type",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [tag_type](#tag_type) object with pk field matching param `id`",
          "endpoint": "/api/tag_type/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [tag_type](#tag_type) object with pk field matching param `id`",
          "endpoint": "/api/tag_type/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "tags",
          "model": "tag"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "usergroups",
      "columns": [
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "groups.id",
          "name": "group_id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "approved",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "can_edit",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "can_add_members",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "can_share_data",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "has_agreed",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "users.id",
          "name": "added_by_user_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    User / Group Association resource.\n    ",
      "endpoints": [
        {
          "description": "Get list of [usergroups](#usergroups) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/usergroups",
          "fields": [
            "created_at",
            "approved",
            "can_edit",
            "added_by_user",
            "added_by_user.id",
            "added_by_user.first_name",
            "added_by_user.last_name",
            "user",
            "user.id",
            "user.username",
            "user.created_at",
            "user.last_login",
            "user.first_name",
            "user.last_name",
            "user.active",
            "user.is_admin",
            "group",
            "group.id",
            "group.name",
            "can_add_members",
            "can_share_data",
            "has_agreed",
            "group.is_public",
            "group.is_restricted",
            "group.user_id",
            "group.requires_approval",
            "group.requires_agreement",
            "group.group_type_id",
            "group.groupinfo",
            "group.created_at"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [usergroups](#usergroups) object with pk field matching param `group_id`",
          "endpoint": "/api/usergroups/<group_id>",
          "fields": [
            "created_at",
            "approved",
            "can_edit",
            "added_by_user",
            "added_by_user.id",
            "added_by_user.first_name",
            "added_by_user.last_name",
            "user",
            "user.id",
            "user.username",
            "user.created_at",
            "user.last_login",
            "user.first_name",
            "user.last_name",
            "user.active",
            "user.is_admin",
            "group",
            "group.id",
            "group.name",
            "can_add_members",
            "can_share_data",
            "has_agreed",
            "group.is_public",
            "group.is_restricted",
            "group.user_id",
            "group.requires_approval",
            "group.requires_agreement",
            "group.group_type_id",
            "group.groupinfo",
            "group.created_at"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "added_by_user",
          "model": "users"
        },
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "group",
          "model": "groups"
        }
      ]
    },
    {
      "association_proxies": [
        {
          "model": "group",
          "name": "affiliations",
          "target_collection": "affiliations_usergroups"
        }
      ],
      "collection": "users",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "username",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "email",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "password",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": false,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "now()",
          "doc": null,
          "foreign_key": null,
          "name": "last_login",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "first_name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=30)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "last_name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=30)",
          "unique": null
        },
        {
          "default": "True",
          "doc": null,
          "foreign_key": null,
          "name": "active",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": "False",
          "doc": null,
          "foreign_key": null,
          "name": "is_admin",
          "nullable": true,
          "primary_key": false,
          "type": "Boolean()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "info",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "roles.id",
          "name": "role_id",
          "nullable": true,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "api_token",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=80)",
          "unique": true
        }
      ],
      "description": "\n    User resource: captures all user information which is linked to most objects and resources.\n    ",
      "endpoints": [
        {
          "description": "Get list of [users](#users) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/users",
          "fields": [
            "id",
            "user_created_at",
            "last_login",
            "first_name",
            "last_name",
            "username",
            "active",
            "info",
            "role",
            "affiliations",
            "affiliations.name",
            "affiliations.groupinfo",
            "affiliations.id",
            "affiliations_names"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [users](#users) object with pk field matching param `id`",
          "endpoint": "/api/users/<id>",
          "fields": [
            "id",
            "user_created_at",
            "last_login",
            "first_name",
            "last_name",
            "username",
            "active",
            "info",
            "role",
            "affiliations",
            "affiliations.name",
            "affiliations.groupinfo",
            "affiliations.id",
            "affiliations_names"
          ],
          "method": "GET",
          "postprocessors": [
            {
              "doc": null,
              "name": "get_single_postprocessor"
            }
          ],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [users](#users) object with pk field matching param `id`",
          "endpoint": "/api/users/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Manage API token",
          "endpoint": "/api/users/api_token",
          "method": "GET"
        },
        {
          "description": "Manage API token",
          "endpoint": "/api/users/api_token",
          "method": "PATCH"
        },
        {
          "description": "Manage API token",
          "endpoint": "/api/users/api_token",
          "method": "DELETE"
        },
        {
          "description": "Manage group membership",
          "endpoint": "/api/users/<int:user_id>/group/<int:group_id>",
          "method": "POST"
        },
        {
          "description": "Manage group membership",
          "endpoint": "/api/users/<int:user_id>/group/<int:group_id>",
          "method": "DELETE"
        },
        {
          "description": "Manage group membership",
          "endpoint": "/api/users/<int:user_id>/group/<int:group_id>",
          "method": "PATCH"
        },
        {
          "description": "\n        Log in. Requires form parameters `username` and `password`.\n        ",
          "endpoint": "/api/users/login",
          "method": "POST"
        },
        {
          "description": "\n        Log out the current session\n        ",
          "endpoint": "/api/users/login",
          "method": "DELETE"
        },
        {
          "description": "Get information about current logged in user",
          "endpoint": "/api/users/login",
          "method": "GET"
        },
        {
          "description": "Update user information",
          "endpoint": "/api/users",
          "method": "POST"
        },
        {
          "description": "Update user information",
          "endpoint": "/api/users/<int:user_id>",
          "method": "PATCH"
        },
        {
          "description": null,
          "endpoint": "/api/users/reset_password",
          "method": "POST"
        },
        {
          "description": null,
          "endpoint": "/api/users/reset_password",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/users/reset_password/<token>",
          "method": "POST"
        },
        {
          "description": null,
          "endpoint": "/api/users/reset_password/<token>",
          "method": "GET"
        },
        {
          "description": "\n        Send an email to the user. Requires json post body containing `message` and optionally `subject`. If no\n        `subject`, default subject will be \"User message from PROJECT_NAME\"\n        ",
          "endpoint": "/api/users/<int:user_id>/email",
          "method": "POST"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "affiliations_names",
          "type": "method"
        },
        {
          "doc": null,
          "name": "full_name",
          "type": "method"
        },
        {
          "doc": null,
          "name": "get_id",
          "type": "method"
        },
        {
          "doc": null,
          "name": "is_active",
          "type": "method"
        },
        {
          "doc": null,
          "name": "is_anonymous",
          "type": "method"
        },
        {
          "doc": null,
          "name": "is_authenticated",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "role",
          "model": "roles"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "affiliations_usergroups",
          "model": "usergroups"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "usergroups",
          "model": "usergroups"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "vocab_element",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=96)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "lineage",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "data",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "mapped_registries",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "parent_key",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=96)",
          "unique": null
        },
        {
          "default": null,
          "doc": "The `id` of the `vocab_registry`",
          "foreign_key": "vocab_registry.key",
          "name": "vocab_registry_key",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=96)",
          "unique": null
        },
        {
          "default": null,
          "doc": "The `id` of the user who created and owns this record",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "origin_updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        }
      ],
      "description": "\n    Vocab Element resource: locally cached version of element from [vocab_registry](#vocab_registry)\n    ",
      "endpoints": [
        {
          "description": "Create new [vocab_element](#vocab_element) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/vocab_element",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [vocab_element](#vocab_element) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/vocab_element/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [vocab_element](#vocab_element) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/vocab_element",
          "fields": [
            "id",
            "name",
            "key",
            "parent_key",
            "vocab_registry",
            "vocab_registry.key",
            "vocab_registry.vocab_element_key_name",
            "vocab_registry.name",
            "vocab_registry.description",
            "created_at",
            "updated_at",
            "user",
            "user.id",
            "lineage",
            "user.first_name",
            "mapped_registries",
            "user.last_name",
            "other_names",
            "other_names.id",
            "other_names.name",
            "origin_updated_at",
            "reference_url",
            "reference_url_parent"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [vocab_element](#vocab_element) object with pk field matching param `id`",
          "endpoint": "/api/vocab_element/<id>",
          "fields": [
            "id",
            "name",
            "key",
            "parent_key",
            "vocab_registry",
            "vocab_registry.key",
            "vocab_registry.vocab_element_key_name",
            "vocab_registry.name",
            "vocab_registry.description",
            "created_at",
            "updated_at",
            "user",
            "user.id",
            "lineage",
            "user.first_name",
            "mapped_registries",
            "user.last_name",
            "other_names",
            "other_names.id",
            "other_names.name",
            "origin_updated_at",
            "reference_url",
            "reference_url_parent",
            "data",
            "description",
            "mapped_labels"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [vocab_element](#vocab_element) object with pk field matching param `id`",
          "endpoint": "/api/vocab_element/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/<registry_key>/<element_key>",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/<registry_key>/<element_key>",
          "method": "POST"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/<registry_key>/<element_key>",
          "method": "PATCH"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/<registry_key>/<element_key>/label/<label_id>",
          "method": "POST"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/<registry_key>/<element_key>/label/<label_id>",
          "method": "DELETE"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_element/nested",
          "method": "GET"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "mapped_labels",
          "type": "method"
        },
        {
          "doc": null,
          "name": "reference_url",
          "type": "method"
        },
        {
          "doc": null,
          "name": "reference_url_parent",
          "type": "method"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "The `vocab_registry` that contains this `vocab_element`",
          "key": "vocab_registry",
          "model": "vocab_registry"
        },
        {
          "direction": "MANYTOONE",
          "doc": "The user who owns or created and owns this record",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "MANYTOMANY",
          "doc": "A list of `labels` linked to this `vocab_element`",
          "key": "labels",
          "model": "label"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "other_names",
          "model": "vocab_element_names"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "label_vocab_element",
          "model": "label_vocab_element"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "vocab_element_names",
      "columns": [
        {
          "default": null,
          "doc": "Primary key `id`",
          "foreign_key": null,
          "name": "id",
          "nullable": false,
          "primary_key": true,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": false
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": "vocab_element.id",
          "name": "vocab_element_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        }
      ],
      "description": "\n    VocabElement Names resource.\n    ",
      "endpoints": [
        {
          "description": "Create new [vocab_element_names](#vocab_element_names) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. ",
          "endpoint": "/api/vocab_element_names",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [vocab_element_names](#vocab_element_names) object with pk field matching param `id`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/vocab_element_names/<id>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [vocab_element_names](#vocab_element_names) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/vocab_element_names",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [vocab_element_names](#vocab_element_names) object with pk field matching param `id`",
          "endpoint": "/api/vocab_element_names/<id>",
          "fields": [],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [vocab_element_names](#vocab_element_names) object with pk field matching param `id`",
          "endpoint": "/api/vocab_element_names/<id>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        }
      ],
      "hybrid_properties": [],
      "methods": [],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": null,
          "key": "vocab_element",
          "model": "vocab_element"
        }
      ]
    },
    {
      "association_proxies": [],
      "collection": "vocab_registry",
      "columns": [
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "key",
          "nullable": false,
          "primary_key": true,
          "type": "String(length=96)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "name",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=128)",
          "unique": true
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "module",
          "nullable": false,
          "primary_key": false,
          "type": "String(length=96)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "module_kwargs",
          "nullable": true,
          "primary_key": false,
          "type": "JSON()",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "vocab_element_key_name",
          "nullable": true,
          "primary_key": false,
          "type": "String(length=96)",
          "unique": null
        },
        {
          "default": null,
          "doc": null,
          "foreign_key": null,
          "name": "description",
          "nullable": true,
          "primary_key": false,
          "type": "Text()",
          "unique": null
        },
        {
          "default": null,
          "doc": "The `id` of the user who created and owns this record",
          "foreign_key": "users.id",
          "name": "user_id",
          "nullable": false,
          "primary_key": false,
          "type": "Integer()",
          "unique": null
        },
        {
          "default": "function",
          "doc": null,
          "foreign_key": null,
          "name": "created_at",
          "nullable": true,
          "primary_key": false,
          "type": "DateTime()",
          "unique": null
        },
        {
          "default": "function",
          "doc": "Updated time (UTC)",
          "foreign_key": null,
          "name": "updated_at",
          "nullable": true,
          "primary_key": false,
          "type": "TIMESTAMP()",
          "unique": null
        }
      ],
      "description": "\n    Vacab Registry resource: defines a mapping to a vocab registry module and handles interactions with them.\n    ",
      "endpoints": [
        {
          "description": "Create new [vocab_registry](#vocab_registry) object. Expects JSON. Fields shown in `MODEL COLUMNS` below. A simple constructor that allows initialization from kwargs.\n\n    Sets attributes on the constructed instance using the names and\n    values in ``kwargs``.\n\n    Only keys that are present as\n    attributes of the instance's class are allowed. These could be,\n    for example, any mapped columns or relationships.\n    ",
          "endpoint": "/api/vocab_registry",
          "method": "POST",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to LOGGED IN users only",
              "name": "post_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Update single [vocab_registry](#vocab_registry) object with pk field matching param `key`. Expects JSON. Fields shown in `MODEL COLUMNS` below.",
          "endpoint": "/api/vocab_registry/<key>",
          "method": "PATCH",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "patch_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get list of [vocab_registry](#vocab_registry) objects matching API query. See [Making API search queries](#api_query) for instructions on making search queries",
          "endpoint": "/api/vocab_registry",
          "fields": [
            "key",
            "name",
            "description",
            "created_at",
            "updated_at",
            "user",
            "user.id",
            "user.first_name",
            "user.last_name",
            "vocab_element_key_name",
            "module",
            "module_kwargs",
            "registry_urls"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_many_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Get single [vocab_registry](#vocab_registry) object with pk field matching param `key`",
          "endpoint": "/api/vocab_registry/<key>",
          "fields": [
            "key",
            "name",
            "description",
            "created_at",
            "updated_at",
            "user",
            "user.id",
            "user.first_name",
            "user.last_name",
            "vocab_element_key_name",
            "module",
            "module_kwargs",
            "registry_urls"
          ],
          "method": "GET",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Allow all requests",
              "name": "get_single_auth_preprocessor"
            }
          ]
        },
        {
          "description": "Delete single [vocab_registry](#vocab_registry) object with pk field matching param `key`",
          "endpoint": "/api/vocab_registry/<key>",
          "method": "DELETE",
          "postprocessors": [],
          "preprocessors": [
            {
              "doc": "Restrict request to ADMIN user only",
              "name": "assert_current_user_is_admin"
            },
            {
              "doc": "Restrict request to OWNER only",
              "name": "delete_auth_preprocessor"
            }
          ]
        },
        {
          "description": null,
          "endpoint": "/api/vocab_registry/<key>/match",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_registry/<key>/get_element",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_registry/<key>/get_all_elements",
          "method": "GET"
        },
        {
          "description": null,
          "endpoint": "/api/vocab_registry/<key>/get_children",
          "method": "GET"
        }
      ],
      "hybrid_properties": [],
      "methods": [
        {
          "doc": null,
          "name": "registry_urls",
          "type": "method"
        },
        {
          "doc": null,
          "name": "registry_plugin",
          "type": "property"
        }
      ],
      "relations": [
        {
          "direction": "MANYTOONE",
          "doc": "The user who owns or created and owns this record",
          "key": "user",
          "model": "users"
        },
        {
          "direction": "ONETOMANY",
          "doc": null,
          "key": "vocab_elements",
          "model": "vocab_element"
        }
      ]
    }
  ]
}