openapi: 3.0.0
info:
  version: 'v.2.1.2'
  title: 'Luna-Sender API'
  description: 'VisionLabs Luna-Sender API'


servers:
- description: SwaggerHub API Auto Mocking
  url: https://virtserver.swaggerhub.com/visionlabs/luna-sender/v.2.1.2

components:
  headers:
    application_json:
      schema:
        type: string
        enum:
        - application/json
      required: true
      description: content type is application/json

    text_plain:
      schema:
        type: string
        enum:
        - text/plain
      required: true
      description: content type is text/plain

    image_jpeg:
      schema:
        type: string
        enum:
        - image/jpeg
      description: content type is image/jpeg
      required: true

    luna_request_id:
      schema:
        type: string
        format: timestamp,uuid
        example: 1536751345,8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a
        pattern: ^[0-9]{10},[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
      description: request id. Helps to uniquely identify messages that correspond to particular requests, in system logs.
      required: true

    docs_content_type:
      schema:
        type: string
        enum:
          - application/x-yaml
          - text/html
      required: true
      description: Type of receiving data

    text_html:
      schema:
        type: string
        enum:
          - text/html
      required: true
      description: Content type is text/html
  parameters:
    luna_request_id:
      in: header
      schema:
        type: string
        format: timestamp,uuid
        example: 1536751345,8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a
        pattern: ^[0-9]{10},[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
      description: |
        external request id. Helps to uniquely identify messages that correspond to particular requests, in system logs.
        If it was not set, system will set it in default format ("timestamp,UUID"). It will be returned with response.
      name: Luna-Request-Id

    gender:
      in: query
      name: gender
      schema:
        type: integer
        enum: [0, 1]
      description: Gender. 1 - male, 0 - female.
      example: 1

    ethnic_groups:
      in: query
      name: ethnic_groups
      schema:
        type: string
        format: list of integer (1, 2, 3, 4)
      description: |
        comma-separated list of dominant ethnic group. Each event from result will contain one of the given ethnic groups.

        | ethnicity   | value |
        |-----------------|---|
        | AfricanAmerican | 1 |
        | Indian          | 2 |
        | Asian           | 3 |
        | Caucasian       | 4 |

      example: "1,2"

    tags:
      in: query
      name: tags
      schema:
        type: array
        items:
          $ref: '#/components/schemas/tag'
        minItems: 0
      explode: false
      description: |
        A comma-separated list of tags. Each event from result will contain all of the given tags.
        Each tag can be at most 36 characters.
      example:
        - tag_1
        - tag_2

    cities:
      in: query
      name: cities
      schema:
        type: string
      description: Comma-separated list of cities. Each event from result will contain one of the given cities in location.
      example: "moscow,New-York"

    areas:
      in: query
      name: areas
      schema:
        type: string
      description: Comma-separated list of areas. Each event from result will contain one of the given areas in location.
      example: "CAO,central park"

    districts:
      in: query
      name: districts
      schema:
        type: string
      description: Comma-separated list of districts. Each event from result will contain one of the given districts in location.
      example: "mitino,central park"

    streets:
      in: query
      name: streets
      schema:
        type: string
      description: |
        Comma-separated list of streets. Each event from result will contain one of the given streets  in location.
      example: "arbat,schepkina"

    house_numbers:
      in: query
      name: house_numbers
      schema:
        type: string
      description: |
        Comma-separated list of house numbers. Each event from result will contain one of the given house numbers
        in location.
      example: "1,1/2str3"

    age__lt:
      in: query
      name: age__lt
      schema:
        type: integer
      description: age upper excluded bound.
      example: 50

    age__gte:
      in: query
      name: age__gte
      schema:
        type: integer
      description: age lower included bound.
      example: 50

    sources:
      in: query
      name: sources
      schema:
        type: string
      description: Comma-separated list of sources. Each event from result will contain one of the given sources.
      example: "cam1,cam2"

    matching_candidates_labels:
      in: query
      name: matching_candidates_labels
      schema:
        type: string
      description: Matching candidates labels. Each event from result will contain one or more given labels.
      example: "matching_label"

    object_similarity__gte:
      in: query
      name: object_similarity__gte
      schema:
        type: number
      description: Similar object similarity lower included bound (boudary for top matching candidate).
      example: 0.5

    object_similarity__lt:
      in: query
      name: object_similarity__lt
      schema:
        type: number
      description: Top similar object similarity upper excluded bound (boudary for top matching candidate).
      example: 0.5

    applicationJsonContent:
      in: header
      name: Content-Type
      schema:
        type: string
        enum:
        - application/json
      description: content type is application/json.

    score_threshold:
      in: query
      name: score_threshold
      schema:
        $ref: '#/components/schemas/score_threshold'
      description: |
        descriptor quality score threshold. All the attributes with quality score below the threshold will be
        ignored (and not stored in the DB). The function will proceed as usual with all the remaining descriptors
        (if left).

    handler_ids:
      in: query
      name: handler_ids
      schema:
        type: string
        format: list of uuid.
      example: '8950722f-3fd4-4223-b48f-03f95f0e8dfb,346a5645-ec89-4806-820a-dbcb6e0dc38'
      description: a list of comma-separated handler ids.

    required_luna_account_id:
      in: header
      name: Luna-Account-Id
      required: true
      schema:
        type: string
        format: uuid
        example: 8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a
        pattern: ^[0-9]{10},[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
      description: account id. Specify an account id to be noticed about events in the account.

    accept_docs_handler:
      in: header
      name: Accept
      schema:
        $ref: '#/components/schemas/accept_docs_handler'
      required: true
      description: acceptable type of receiving data
  schemas:
    Error:
      type: object
      properties:
        error_code:
          type: integer
          description: error code.
        desc:
          type: string
          description: short error description.
        detail:
          type: string
          description: error details.
      required:
      - error_code
      - detail
      - desc
      example:
        error_code: 1
        detail: internal server error
        desc: internal server error

    account_id:
      allOf:
        - $ref: '#/components/schemas/uuid'
        - description: id of the luna account.

    sample_id:
      allOf:
        - $ref: '#/components/schemas/uuid'
        - description: sample id.
      example: "b668c4a5-2191-476e-a261-3b4f9ce2e25e"

    uuid:
      type: string
      format: uuid
      pattern: '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'
      example: 557d54ec-29ad-4f3c-93b4-c9092ef12515

    number01:
      type: number
      minimum: 0
      maximum: 1

    face_id:
      allOf:
      - $ref: '#/components/schemas/uuid'
      - type: string
        description: face id

    event_id:
      allOf:
      - $ref: '#/components/schemas/uuid'
      - type: string
        description: event id

    track_id:
      description: event track id
      type: string
      pattern: '^[a-zA-Z0-9_\-](1, 36)$'
      example: "useful_track_id_number_1"

    list_id:
      allOf:
      - $ref: '#/components/schemas/uuid'
      - type: string
        description: list id

    age:
      type: integer
      minimum: 0
      maximum: 100
      description: age
      example: 50

    gender:
      type: integer
      enum: [0, 1]
      description: gender, 0 - female, 1 - male

    mask_enum:
      type: integer
      enum: [1, 2, 3]

      description: |
        predominant mask.

        | masks      | value |
        |----------------|---|
        | missing        | 1 |
        | medical_mask   | 2 |
        | occluded       | 3 |


    tags:
      description: list of tags.
      type: array
      items:
        $ref: '#/components/schemas/tag'
      example: ['tag1', 'tag2']
      minItems: 1
      maxItems: 1000

    emotion:
       type: integer
       enum: [1,2,3,4,5,6,7]
       description: |
         Emotions enum.

         | emotions    | value |
         |-----------------|---|
         | anger           | 1 |
         | disgust         | 2 |
         | fear            | 3 |
         | happiness       | 4 |
         | neutral         | 5 |
         | sadness         | 6 |
         | surprise        | 7 |

    ethnic_group:
      type: integer
      enum: [1,2,3,4]

      description: |
        Ethnic group.

        | ethnicity   | value |
        |-----------------|---|
        | AfricanAmerican | 1 |
        | Indian          | 2 |
        | Asian           | 3 |
        | Caucasian       | 4 |


    mask_estimations:
      type: object
      description: raw mask estimations
      properties:
        medical_mask:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: The probability that the `medical mask` exists on the face and is worn properly
        missing:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: The probability that the `medical mask` doesn't exist on the face
        occluded:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: The probability that the face is occluded by other object (not by `medical mask`)
      required: [medical_mask, missing, occluded]

    mask_predominant:
      type: string
      enum: [medical_mask, missing, occluded]
      description: most likely mask state

    masks:
      type: object
      description: estimated face mask state
      properties:
        estimations:
          $ref: '#/components/schemas/mask_estimations'
        predominant_mask:
          $ref: '#/components/schemas/mask_predominant'
      required: [estimations, predominant_mask]

    top_match_face:
      type: object
      properties:
        label:
          $ref: '#/components/schemas/top_matching_candidates_label'
        similarity:
          description: similarity to the most similar face.
          type: number
          example: 0.7
        face_id:
          $ref: '#/components/schemas/face_id'
      required: [label, similarity, face_id]

    top_match_event:
      type: object
      properties:
        label:
          $ref: '#/components/schemas/top_matching_candidates_label'
        similarity:
          description: similarity to the most similar event.
          type: number
          example: 0.7
        event_id:
          $ref: '#/components/schemas/event_id'
      required: [label, similarity, event_id]

    face_candidates_in_target_match_result:
      type: array
      items:
        type: object
        properties:
          face_id:
            allOf:
              - $ref: '#/components/schemas/face_id'
            nullable: True
          external_id:
            nullable: true
            allOf:
              - $ref: '#/components/schemas/face_external_id'
          user_data:
            allOf:
              - $ref: '#/components/schemas/face_user_data'
            nullable: True
          create_time:
            allOf:
              - $ref: "#/components/schemas/time"
              - description: time of the face creation.
            nullable: True
        required: [face_id, external_id, user_data, create_time]
      minItems: 0

    event_candidates_in_target_match_result:
      type: array
      items:
        type: object
        properties:
          event_id:
            allOf:
              - $ref: '#/components/schemas/event_id'
            nullable: True
          external_id:
            allOf:
              - $ref: '#/components/schemas/event_external_id'
            nullable: True
          handler_id:
            allOf:
              - $ref: '#/components/schemas/handler_id'
            nullable: True
          source:
            allOf:
              - $ref: '#/components/schemas/source'
            nullable: True
          user_data:
            allOf:
              - $ref: '#/components/schemas/event_user_data'
            nullable: True
          create_time:
            allOf:
              - $ref: "#/components/schemas/time"
              - description: time of the event creation.
            nullable: True
        required: [event_id, external_id, handler_id, source, user_data, create_time]
      minItems: 0

    avatar:
      type: string
      format: uri
      default: ""
      description: avatar for the face, references to a sample or a user-defined reference.

    score_threshold:
      type: number
      minimum: 0
      maximum: 1
      example: 0.99
      default: 0
      description: |
        descriptor quality score threshold. All the attributes with quality score below the threshold will be
        ignored (and not stored in the DB). The function will proceed as usual with all the remaining descriptors
        (if left).

    int_version:
      type: integer
      minimum: 0

    version:
      type: object
      properties:
        api:
          allOf:
          - $ref: '#/components/schemas/int_version'
          - description: an api version of service.
        major:
          allOf:
          - $ref: '#/components/schemas/int_version'
          - description: a major version of service.
        minor:
          allOf:
          - $ref: '#/components/schemas/int_version'
          - description: a minor version of service.
        patch:
          allOf:
          - $ref: '#/components/schemas/int_version'
          - description: a patch version of service.
      required: [api, major, minor, patch]

      example:
        api: 1
        major: 0
        minor: 0
        patch: 0

    lists:
      type: array
      items:
        $ref: '#/components/schemas/list_id'
      minItems: 0
      description: list of luna lists, which contain the face.

    time:
      type: string
      format: date-time
      example: "2018-08-11T09:11:41.674Z"
      description: time in format RFC 3339

    handler_id:
      allOf:
        - $ref: '#/components/schemas/uuid'
        - description: handler id.
        - example: "b668c4a5-2191-476e-a261-3b4f9ce2e25e"

    longitude:
      type: number
      minimum: -180
      maximum: 180
      description: longitude in degrees
      example: 36.616

    latitude:
      type: number
      minimum: -90
      maximum: 90
      description: latitude in degrees
      example: 55.752

    geo_position:
      type: object
      description: geo position specified by geographic coordinates - longitude and latitude.
      properties:
        longitude:
          $ref: '#/components/schemas/longitude'
        latitude:
          $ref: '#/components/schemas/latitude'
      required: [longitude, latitude]
      nullable: true

    source:
      description: additional information that user provides with event.
      type: string
      example: "3rd Avenue"

    location:
      type: object
      properties:
        city:
          type: string
          description: city where event is incidented.
          nullable: true
          example: "Moscow"
        area:
          type: string
          description: area where event is incidented.
          nullable: true
          example: "CAO"
        district:
          type: string
          description: district where event is incidented.
          nullable: true
          example: "mitino"
        street:
          type: string
          description: street where event is incidented.
          nullable: true
          example: "schepkina"
        house_number:
          type: string
          description: house number where event is incidented.
          nullable: true
          example: "1/2str3"
        geo_position:
          allOf:
          - $ref: '#/components/schemas/geo_position'
          - nullable: true
      required: [city, area, district, street, house_number, geo_position]

    event_from_ws:
      type: object
      description: event format from handler.
      properties:
        body_attributes:
          type: object
          description: Body attributes extracted from samples.
          nullable: true
          properties:
            score:
              type: number
              minimum: 0
              maximum: 1
              description: Quality of body descriptor.
            samples:
              type: array
              items:
                $ref: '#/components/schemas/uuid'
              minItems: 0
              example: ['a3e8716f-70dc-42ad-8428-7a552e800a37']
              description: resource for attributes.
          required: [score, samples]
        face_attributes:
          allOf:
          - description: extracted attributes from samples.
          - $ref: '#/components/schemas/Attribute'
          - nullable: true
        source:
          type: string
          description: additional information that user provides with event.
          nullable: true
          example: "3rd Avenue"
        user_data:
          $ref: '#/components/schemas/event_user_data'
        external_id:
          $ref: '#/components/schemas/event_external_id'
        tags:
          description: tag array.
          type: array
          items:
            $ref: '#/components/schemas/tag'
          example: ['tag1', 'tag2']
          nullable: true
        location:
          $ref: '#/components/schemas/location'
        face:
          type: object
          nullable: true
          properties:
            face_id:
              $ref: '#/components/schemas/face_id'
            external_id:
              $ref: '#/components/schemas/face_external_id'
            user_data:
              $ref: '#/components/schemas/face_user_data'
            avatar:
              type: string
              format: uri
              default: ""
              description: avatar for the face, references to a sample or a user-defined reference.
            lists:
              $ref: '#/components/schemas/lists'
            event_id:
              allOf:
              - type: string
                description: event id associated with the face creation.
              - $ref: '#/components/schemas/uuid'
            url:
              $ref: '#/components/schemas/url'
          required: [face_id, external_id, user_data, avatar, lists, event_id, url]
          example:
            external_id: 2xQ2gprbMUePw1s9gw9fvA==
            face_id: 426542d6-5509-4e5b-8a01-e2abd5c0a8c6
            user_data: fox1991
            url: /2/faces/426542d6-5509-4e5b-8a01-e2abd5c0a8c6
            lists: ["429b0e78-4616-426a-b57f-02baa72d638d", '6d037c33-31ec-4d73-b3b3-ec80b09446c2']
            avatar: 'https://st.kp.yandex.net/images/actor_iphone/iphone360_460188.jpg'
            event_id: f9687459-986b-406d-9c1f-0d6289be5256
        event_id:
          allOf:
          - type: string
            description: Event id.
          - $ref: '#/components/schemas/uuid'
        url:
          type: string
          format: uri
          example: /0/events/24d405ce-bc56-4bf7-98e1-bdc962b4cf34
          description: location of event.
          nullable: true
        matches:
          $ref: '#/components/schemas/Matches'
        detections:
          type: array
          description: all detections which was generated the event.
          items:
            type: object
            properties:
              filename:
                type: string
                example: "penelope.jpeg"
              samples:
                type: object
                properties:
                  face:
                    allOf:
                      - $ref: '#/components/schemas/Face_Detection'
                      - nullable: True
                  body:
                    allOf:
                      - $ref: '#/components/schemas/Body_Detection'
                      - nullable: True
                required: [face, body]
              detect_time:
                $ref: '#/components/schemas/detect_time'
              image_origin:
                $ref: '#/components/schemas/image_origin'
            required: [filename, samples, detect_time, image_origin]
        track_id:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/track_id'
      required: [matches, url, event_id, face, tags, source, face_attributes, body_attributes, samples,
                 detections, user_data, location, track_id, external_id]

    emotions_estimations:
      type: object
      properties:
        anger:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: anger probability.
        disgust:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: disgust probability.
        fear:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: fear probability.
        happiness:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: happiness probability.
        neutral:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: neutral face probability.
        sadness:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: sadness probability.
        surprise:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: surprise probability.
      required: [surprise, sadness, neutral, happiness, fear, disgust, anger]
      description: emotion classifier response.

    emotions:
      type: object
      properties:
        estimations:
          allOf:
          - $ref: '#/components/schemas/emotions_estimations'
          - description: emotion classifier response.
        predominant_emotion:
          type: string
          description: name of predominant emotion.
          enum: [surprise, sadness, neutral, happiness, fear, disgust, anger]
      required: [estimations, predominant_emotion]

    landmark:
      type: array
      items:
        type: integer
      description: |
        key point coordinates. First element is `x` coordinate, second is `y`.
      minItems: 2
      maxItems: 2
      example: [12, 13]

    landmarks5:
      type: array
      items:
        $ref: '#/components/schemas/landmark'
      description: array of 5 landmarks.
      minItems: 5
      maxItems: 5
      example:
      - - 23
        - 72
      - - 82
        - 71
      - - 42
        - 114
      - - 29
        - 140
      - - 79
        - 138

    landmarks68:
      description: array of 68 landmarks.
      type: array
      items:
        $ref: '#/components/schemas/landmark'
      minItems: 68
      maxItems: 68

    landmarks34:
      description: array of 34 landmarks.
      type: array
      items:
        $ref: '#/components/schemas/landmark'
      minItems: 34
      maxItems: 34

    mouth_attributes:
      description: mouth attributes.
      type: object
      properties:
        score:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: mouth detection confidence (always 1).
        smile:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: smile probability.
        opened:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: opened mouth probability.
        occluded:
          allOf:
          - $ref: '#/components/schemas/number01'
          description: occlusion probability.
      required: [score, smile, occluded, opened]
    eye_attributes:
      description: eye attributes.
      type: object
      properties:
        state:
          type: string
          enum: [open, closed, occluded]
          description: eye state.
        iris_landmarks:
          allOf:
          - $ref: '#/components/schemas/landmarks34'
          - description: iris landmarks.
      required: [state, iris_landmarks]

    eyes_attributes:
      description: eyes attributes.
      type: object
      properties:
        left_eye:
          allOf:
          - $ref: '#/components/schemas/eye_attributes'
          - description: left eye attributes.
        right_eye:
          allOf:
          - $ref: '#/components/schemas/eye_attributes'
          - description: right eye attributes.
      required: [left_eye, right_eye]

    head_pose:
      description: head pose.
      type: object
      properties:
        yaw:
          type: number
          description: yaw angle in degrees.
        pitch:
          type: number
          description: pitch angle in degrees.
        roll:
          type: number
          description: roll angle in degrees.
      required: [yaw, pitch, roll]

    eye_gaze:
      type: object
      properties:
        yaw:
          type: number
          description: yaw angle in degrees.
        pitch:
          type: number
          description: pitch angle in degrees.
      required: [yaw, pitch]

    gaze:
      description: gaze direction.
      type: object
      properties:
        left_eye:
          allOf:
          - $ref: '#/components/schemas/eye_gaze'
          - description: left eye estimation.
        right_eye:
          allOf:
          - $ref: '#/components/schemas/eye_gaze'
          - description: right eye estimation.
      required: [left_eye, right_eye]

    attributes:
      description: face attributes.
      type: object
      properties:
        mouth_attributes:
          allOf:
          - $ref: '#/components/schemas/mouth_attributes'
          - description: optional mouth attributes.
        eyes_attributes:
          allOf:
          - $ref: '#/components/schemas/eyes_attributes'
          - description: optional eye attributes.
        emotions:
          allOf:
          - $ref: '#/components/schemas/emotions'
          - description: face emotions estimation.
        mask:
          allOf:
            - $ref: '#/components/schemas/masks'
            - description: face mask estimation.
        head_pose:
          allOf:
          - $ref: '#/components/schemas/head_pose'
          - description: head pose estimation.
        gaze:
          allOf:
          - $ref: '#/components/schemas/gaze'
          - description: gaze estimation.
      example:
        mouth_attributes:
          occluded: 0.0
          score: 0.999999165534973
          smile: 0.0
        emotions:
          estimations:
            anger: 0.00894705578684807
            disgust: 0.00000965219624049496
            fear: 0.00121302821207792
            happiness: 0.00129503419157118
            neutral: 0.986027479171753
            sadness: 0.00187553185969591
            surprise: 0.000632198702078313
          predominant_emotion: "neutral"
        mask:
          estimations:
            medical_mask: 0.7108324766
            missing: 0.0700698048
            occluded: 0.2190976739
          predominant_mask: "medical_mask"

        head_pose:
          pitch: 18.6827487945557
          roll: -10.3542232513428
          yaw: 15.4102487564087
        gaze:
          left_eye:
            pitch: 9.26744079589844
            yaw: -19.4657287597656
          right_eye:
            pitch: 10.7074518203735
            yaw: -14.6733160018921

    rect:
      description: bounding rectangle.
      type: object
      properties:
        height:
          type: integer
          description: rectangle height.
          format: int32
          example: 200
        width:
          type: integer
          description: rectangle width.
          format: int32
          example: 100
        x:
          type: integer
          description: top left corner "x" coordinate.
          format: int32
          example: 17
        y:
          type: integer
          description: top left corner "y" coordinate.
          format: int32
          example: 10
      required: [height, width, x, y]
      example:
        height: 240
        width: 209
        x: 170
        y: 198

    quality:
      description: |
        image quality. Estimation of image visual properties.
      type: object
      properties:
        dark:
          type: number
          description: low value means underlit face area (i.e. due to backlight, poor lighting, sensor underexposure).
          maximum: 1
          minimum: 0
        light:
          type: number
          description: low value means overexposed face area (i.e. overbright lighting, sensor overexposure).
          maximum: 1
          minimum: 0
        saturation:
          type: number
          description: low value means low saturation (e.g. grayscale images).
          maximum: 1
          minimum: 0
        blurriness:
          type: number
          description: low value means blurred image (e.g. due to depth of field or motion blur). High value means sharp image.
          maximum: 1
          minimum: 0
      required: [blurriness, saturation, light, dark]
      example:
        light: 0.87
        dark: 0.13
        saturation: 0.93
        blurriness: 0.2

    detect_time:
      allOf:
        - $ref: "#/components/schemas/time"
        - description: detection time
      example: "2018-08-11T09:11:41.674Z"

    image_origin:
      type: string
      maxLength: 256
      description: the image url - source of the detection
      nullable: true
      example: "/6/images/b668c4a5-2191-476e-a261-3b4f9ce2e25e"

    Body_Detection:
      type: object
      properties:
        sample_id:
          allOf:
          - $ref: '#/components/schemas/uuid'
          nullable: true
        detection:
          type: object
          properties:
            rect:
              allOf:
              - $ref: '#/components/schemas/rect'
              - description: Body detection bounding box.
          required: [rect]
        url:
          type: string
          format: uri
          example: /0/samples/a16c8b6c-2818-4bae-9fd5-65acc8d4bb5c
          nullable: true
      required: [detection, sample_id, url]

    Face_Detection:
      type: object
      properties:
        sample_id:
          allOf:
          - $ref: '#/components/schemas/sample_id'
          nullable: true
        detection:
          type: object
          properties:
            attributes:
              allOf:
              - $ref: '#/components/schemas/attributes'
              - description: face attributes estimation.
            quality:
              allOf:
              - $ref: '#/components/schemas/quality'
              - description: image quality estimation for this face detection region.
            rect:
              allOf:
              - $ref: '#/components/schemas/rect'
              - description: face detection bounding box.
            landmarks5:
              allOf:
              - $ref: '#/components/schemas/landmarks5'
              - description: facial landmarks.
            landmarks68:
              allOf:
              - $ref: '#/components/schemas/landmarks68'
              - description: facial landmarks.
        url:
          type: string
          format: uri
          example: /0/samples/a16c8b6c-2818-4bae-9fd5-65acc8d4bb5c
          nullable: true
      required: [detection, sample_id, url]

    ethnicities_estimations:
      type: object
      description: ethnicity classifier response.
      properties:
        asian:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: Asian ethnicity probability.
        indian:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: Indian ethnicity probability.
        caucasian:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: Caucasian ethnicity probability.
        african_american:
          type: number
          format: double
          maximum: 1
          minimum: 0
          description: African American ethnicity probability.
      required: [african_american, caucasian, indian, asian]

    ethnicities:
      description: estimated ethnicities.
      type: object
      properties:
        estimations:
          allOf:
          - $ref: '#/components/schemas/ethnicities_estimations'
          - description: ethnicity classifier response.
        predominant_ethnicity:
          type: string
          description: name of predominant ethnicity.
      required: [estimations, predominant_ethnicity]
      example:
        estimations:
          african_american: 1.92238889737406e-12
          asian: 0.954671621322632
          caucasian: 0.045328326523304
          indian: 7.65100649502415e-10
        predominant_ethnicity: "asian"

    Attribute:
      type: object
      properties:
        attribute_id:
          allOf:
          - $ref: '#/components/schemas/uuid'
          nullable: true
        basic_attributes:
          type: object
          properties:
            age:
              $ref: '#/components/schemas/age'
            gender:
              $ref: '#/components/schemas/gender'
            ethnicities:
              $ref: '#/components/schemas/ethnicities'
          required: [age, gender, ethnicities]
        score:
          type: number
          minimum: 0
          maximum: 1
          description: face descriptor quality score.
        url:
          type: string
          format: uri
          example: /0/attributes/24d405ce-bc56-4bf7-98e1-bdc962b4cf34
          description: location of attributes.
          nullable: true
        samples:
          type: array
          items:
            $ref: '#/components/schemas/uuid'
          minItems: 0
          example: ['a3e8716f-70dc-42ad-8428-7a552e800a37']
          description: resource for attributes.
      required: [attribute_id, url, samples]

    similarity:
      type: number
      description: face similarity
      minimum: 0
      maximum: 1

    url:
      type: string
      description: face url

    event_user_data:
      description: user data associated with face
      type: string
      maxLength: 128
      default: ""
      example: "some event"

    face_user_data:
      type: string
      maxLength: 128
      default: ""
      description: user data associated with face
      example: "face of person"

    face_external_id:
      description: user-defined external id of a face
      type: string
      example: "external id"
      maxLength: 36
      default: ""

    event_external_id:
      description: user-defined external id of an event
      type: string
      example: "external id"
      maxLength: 36
      default: ""

    detection:
      type: object
      description: detection
      properties:
        rect:
          type: object
          description: detection rectangle
          properties:
            x:
              type: integer
              description: detection rectangle x coordinate
            y:
              type: integer
              description: detection rectangle y coordinate
            width:
              type: integer
              description: detection rectangle width
            height:
              type: integer
              description: detection rectangle height
          required: [ x, y, width, height ]
      required: [ rect ]

    face_candidate:
      type: object
      properties:
        face_id:
          $ref: '#/components/schemas/face_id'
        account_id:
          $ref: '#/components/schemas/account_id'
        external_id:
          $ref: '#/components/schemas/face_external_id'
        user_data:
          $ref: '#/components/schemas/face_user_data'
        create_time:
          allOf:
            - $ref: "#/components/schemas/time"
            - description: time of the face creation.
        avatar:
          $ref: '#/components/schemas/avatar'
        lists:
          $ref: '#/components/schemas/lists'
        event_id:
          allOf:
            - $ref: '#/components/schemas/event_id'
            - description: event id associated with the face creation.
            - nullable: true
      example:
        face_id: 426542d6-5509-4e5b-8a01-e2abd5c0a8c6
        external_id: 2xQ2gprbMUePw1s9gw9fvA==
        user_data: fox1991
        create_time: "2018-08-11T09:11:41.674Z"
        lists: ["429b0e78-4616-426a-b57f-02baa72d638d", '6d037c33-31ec-4d73-b3b3-ec80b09446c2']
        avatar: 'https://st.kp.yandex.net/images/actor_iphone/iphone360_460188.jpg'
        event_id: f9687459-986b-406d-9c1f-0d6289be5256

    event_candidate:
      type: object
      properties:
        create_time:
          allOf:
            - $ref: '#/components/schemas/time'
            - description: event creation time
        event_id:
          allOf:
            - $ref: '#/components/schemas/event_id'
            - description: event id.
        handler_id:
          allOf:
            - $ref: '#/components/schemas/handler_id'
            - description: id of the handler, which gave birth to the event.
        account_id:
          $ref: '#/components/schemas/account_id'
        external_id:
          $ref: '#/components/schemas/event_external_id'
        track_id:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/track_id'
        source:
          allOf:
            - $ref: '#/components/schemas/source'
            - nullable: true
        top_match:
          nullable: true
          description: top match result from handler match policy
          oneOf:
            - $ref: '#/components/schemas/top_match_face'
            - $ref: '#/components/schemas/top_match_event'
        match_result:
          description: object that contains match result.
          type: array
          nullable: true
          items:
            type: object
            properties:
              label:
                $ref: '#/components/schemas/top_matching_candidates_label'
              candidates:
                oneOf:
                  - $ref: '#/components/schemas/face_candidates_in_target_match_result'
                  - $ref: '#/components/schemas/event_candidates_in_target_match_result'
            required: [label, candidates]
        face_detections:
          description: List of all face detections and corresponding sample ids
          type: array
          items:
            type: object
            properties:
              sample_id:
                $ref: '#/components/schemas/sample_id'
              detection:
                $ref: '#/components/schemas/detection'
              detect_time:
                $ref: '#/components/schemas/detect_time'
              image_origin:
                $ref: '#/components/schemas/image_origin'
            required: [sample_id, detection, detect_time, image_origin]
        body_detections:
          description: List of all body detections and corresponding sample ids
          type: array
          items:
            type: object
            properties:
              sample_id:
                $ref: '#/components/schemas/sample_id'
              detection:
                $ref: '#/components/schemas/detection'
              detect_time:
                $ref: '#/components/schemas/detect_time'
              image_origin:
                $ref: '#/components/schemas/image_origin'
            required: [ sample_id, detection, detect_time, image_origin ]
        face_id:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/face_id'
        attach_result:
          description: contains attached lists ids.
          type: array
          items:
            allOf:
              - type: string
                nullable: true
              - $ref: '#/components/schemas/list_id'
        gender:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/gender'
        age:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/age'
        emotion:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/emotion'
        mask:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/mask_enum'
        ethnic_group:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/ethnic_group'
        tags:
          allOf:
            - nullable: true
            - $ref: '#/components/schemas/tags'
        user_data:
          $ref: '#/components/schemas/event_user_data'
        location:
          $ref: '#/components/schemas/location'

    face_match_candidate:
      type: object
      properties:
        face:
          $ref: '#/components/schemas/face_candidate'
        similarity:
          $ref: '#/components/schemas/similarity'
      required: [face, similarity]

    event_match_candidate:
      type: object
      properties:
        event:
          $ref: '#/components/schemas/event_candidate'
        similarity:
          allOf:
            - $ref: '#/components/schemas/similarity'
          description: event similarity
      required: [event, similarity]

    top_matching_candidates_label:
      type: string
      maxLength: 36
      example: "matching_label"

    match_candidates_faces:
      type: object
      properties:
        label:
          $ref: '#/components/schemas/top_matching_candidates_label'
        candidates:
          type: array
          description: list of faces candidates
          items:
            $ref: '#/components/schemas/face_match_candidate'
      required: [label, candidates]

    match_candidates_events:
      type: object
      properties:
        label:
          $ref: '#/components/schemas/top_matching_candidates_label'
        candidates:
          type: array
          description: list of events candidates
          items:
            $ref: '#/components/schemas/event_match_candidate'
      required: [label, candidates]

    match_candidates:
      oneOf:
        - $ref: '#/components/schemas/match_candidates_faces'
        - $ref: '#/components/schemas/match_candidates_events'

    Matches:
      type: array
      description: matches list
      items:
        $ref: '#/components/schemas/match_candidates'
      example:
        [{
           label: good guys,
           candidates: [{
                          face:{
                            face_id: 426542d6-5509-4e5b-8a01-e2abd5c0a8c6,
                            external_id: 2xQ2gprbMUePw1s9gw9fvA==,
                            user_data: fox1991,
                            create_time: "2018-08-11T09:11:41.674Z",
                            lists: ["429b0e78-4616-426a-b57f-02baa72d638d", '6d037c33-31ec-4d73-b3b3-ec80b09446c2'],
                            avatar: 'https://st.kp.yandex.net/images/actor_iphone/iphone360_460188.jpg',
                            event_id: f9687459-986b-406d-9c1f-0d6289be5256
                          },
                        similarity: 0.5
                        }]},
         {
           label: bad guys,
           candidates: [{
                          event:{
                            event_id: 426542d6-5509-4e5b-8a01-e2abd5c0a8c7,
                            external_id: 2xQ2gprbMUePw1s9gw9fvA==,
                            user_data: fox1991,
                            create_time: "2018-08-11T09:11:41.674Z",
                            handler_id: 426542d6-5509-4e5b-8a01-e2abd5c0a8c7,
                            source: 426542d6-5509-4e5b-8a01-e2abd5c0a8c7
                          },
                        similarity: 0.3
                        }]}]

    Message_from_ws:
      type: object
      properties:
        event:
          $ref: '#/components/schemas/event_from_ws'
        handler_id:
          allOf:
          - $ref: '#/components/schemas/uuid'
          - description: id of the handler, which has produced the event.
        event-time:
          description: event time
          type: string
          format: date-time
        Luna-Request-id:
          type: string
          format: timestamp,uuid
          example: 1536751345,8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a
          pattern: ^[0-9]{10},[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
          description: id of the request, which gave birth to the event.
      required: [event, handler_id, event-time, Luna-Request-id]
      description: example message that will be send by websocket

    accept_docs_handler:
      type: string
      enum: [application/x-yaml, text/html]

    tag:
      type: string
      example: "good"
      maxLength: 36
  responses:
    internal_server_error:
      description: internal server error.
      headers:
        Content-Type:
          $ref: '#/components/headers/application_json'
        Luna-Request-Id:
          $ref: '#/components/headers/luna_request_id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
paths:
  /version:
    get:
      tags:
      - version

      summary: get version
      description: get versions of services
      operationId: getVersion

      parameters:
      - $ref: '#/components/parameters/luna_request_id'
      responses:
        200:
          description: OK
          headers:
            Content-Type:
              $ref: '#/components/headers/application_json'
            Luna-Request-Id:
              $ref: '#/components/headers/luna_request_id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/version'
        500:
          $ref: '#/components/responses/internal_server_error'
  /2/ws:
    get:
      tags:
      - ws
      summary: ws handshake
      description: |
        ws handshake
        > ### Attention!
        > **Subscription to events occurs via [WebSocket](https://en.wikipedia.org/wiki/WebSocket).**
        > Messages sent by ws you can view in callback section.
        > Connection supports [autoping](https://tools.ietf.org/html/rfc6455#section-5.5.2).
      operationId: wsHandshake
      parameters:
      - $ref: '#/components/parameters/required_luna_account_id'
      - $ref: '#/components/parameters/luna_request_id'
      - $ref: '#/components/parameters/sources'
      - $ref: '#/components/parameters/matching_candidates_labels'
      - $ref: '#/components/parameters/object_similarity__gte'
      - $ref: '#/components/parameters/object_similarity__lt'
      - $ref: '#/components/parameters/age__lt'
      - $ref: '#/components/parameters/age__gte'
      - $ref: '#/components/parameters/gender'
      - $ref: '#/components/parameters/ethnic_groups'
      - $ref: '#/components/parameters/tags'
      - $ref: '#/components/parameters/cities'
      - $ref: '#/components/parameters/areas'
      - $ref: '#/components/parameters/districts'
      - $ref: '#/components/parameters/streets'
      - $ref: '#/components/parameters/house_numbers'
      - $ref: '#/components/parameters/handler_ids'

      responses:
        101:
          description: Success handshake
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message_from_ws'
        400:
          description: Bad request
          headers:
            Content-Type:
              $ref: '#/components/headers/application_json'
            Luna-Request-Id:
              $ref: '#/components/headers/luna_request_id'
          content:
            application/json:
              schema:
                oneOf:
                - $ref: '#/components/schemas/Error'
              examples:
                bad_query:
                  value:
                    error_code: 12012
                    desc: Bad/incomplete input data
                    detail: Bad query parameters 'estimate_quality'
        500:
          $ref: '#/components/responses/internal_server_error'
      callbacks:
        wsConnection:
          '':
            post:
              responses:
                200:
                  description: OK
                  content:
                    application/json:
                      schema:
                        $ref: '#/components/schemas/Message_from_ws'
      x-codeSamples:
        - lang: python
          label: sync with luna3
          source: |
            from luna3.sender.wsclient import LunaWSClient

            senderAPI = LunaWSClient(origin="http://127.0.0.1:5080", api=2, accountId="8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a")
            # Note filtering by gender!
            with senderAPI.connect(gender=1) as ws:
                for _ in range(3):
                    resp = ws.recv()
                    print(resp)

        - lang: python
          label: async with luna3
          source: |
            import asyncio
            from luna3.sender.wsclient import LunaWSClient

            async def main():
                senderAPI = LunaWSClient(origin="http://127.0.0.1:5080", api=2, accountId="8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a")
                # Note filtering by gender!
                async with senderAPI.connect(gender=1, asyncRequest=True) as ws:
                    count = 0
                    async for resp in ws:
                        count += 1
                        print(resp.data)
                        if count > 2:
                            await ws.close()
                            raise SystemExit(0)


            asyncio.run(main())

        - lang: python
          label: async with websockets library
          source: |
            import asyncio
            import websockets

            async def main():
                uri = "ws://127.0.0.1:5080/2/ws?gender=1"  # Note filtering by gender!
                headers = {"Luna-Account-Id": "fe2f19a5-0df0-4a75-9d5c-212f7193684a"}
                async with websockets.connect(uri, extra_headers=headers) as websocket:
                    while True:
                        data = await websocket.recv()
                        print(data)


            asyncio.run(main())

        - lang: bash
          label: using curl
          source: |
            curl -i -N \
              -H "Connection: Upgrade" \
              -H "Upgrade: websocket" \
              -H "Sec-WebSocket-Version: 13" \
              -H "Sec-WebSocket-Key: YWFhYWFhYWFhYWFhYWFhYQ==" \
              -H "Luna-Account-Id: 8b8b5937-2e9c-4e8b-a7a7-5caf86621b5a" \
              http://127.0.0.1:5080/2/ws
  /2/docs/spec:
    get:
      tags:
        - documents
      summary: get openapi documentation
      description: |
        Get service OpenApi documentation. If *Accept* request header is of type `application/x-yaml`,
        returns documentation in `yaml` format or returns `html` documentation, if *Accept-Type* is `text/html`
      operationId: getSpec

      parameters:
        - $ref: '#/components/parameters/luna_request_id'
        - $ref: '#/components/parameters/accept_docs_handler'
      responses:
        200:
          description: OK
          headers:
            Content-Type:
              $ref: '#/components/headers/docs_content_type'
            Luna-Request-Id:
              $ref: '#/components/headers/luna_request_id'
          content:
            application/x-yaml:
              schema:
                type: string
                description: yaml format documentation
            text/html:
              schema:
                type: string
                description: html format documentation
        415:
          description: Unsupported Media Type
          headers:
            Content-Type:
              $ref: '#/components/headers/application_json'
            Luna-Request-Id:
              $ref: '#/components/headers/luna_request_id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                unsupported_media_type:
                  value:
                    error_code: 12024
                    detail: 'Bad/incomplete input data'
                    desc: "Unsupported media type"
        500:
          $ref: '#/components/responses/internal_server_error'
  /2/docs/dev:
    get:
      tags:
        - documents
      summary: get development manual
      description: |
        Get sphinx documentation - *Development Manual*. After the request you will be redirected to the page `/docs/dev/index.html`
      operationId: getDevManual

      parameters:
        - $ref: '#/components/parameters/luna_request_id'
      responses:
        200:
          description: OK
          headers:
            Content-Type:
              $ref: '#/components/headers/text_html'
            Luna-Request-Id:
              $ref: '#/components/headers/luna_request_id'
          content:
            text/html:
              schema:
                type: string
                description: html format documentation
        500:
          $ref: '#/components/responses/internal_server_error'
