openapi: 3.0.1
info:
  title: Delphi SLZ API Service
  version: 1.2.3
servers:
  - url: /v1
    description: API v1
tags:
  - name: Resources
    description: Resource-related components
  - name: Auth
    description: Authentication and authorization-related components
paths:
  /files:
    get:
      tags:
        - Resources
      summary: Return data for a specific reporting date
      operationId: slz_api_service.v1.views.files.FilesView.get
      security:
        - bearerAuth: ['read:files']
      parameters:
        - name: dsp
          description: 'The service provider data source.'
          in: query
          required: true
          schema:
            type: string
        - name: report_date
          description: 'The date of the report in the format `YYYY-MM-DD`'
          in: query
          required: true
          schema:
            type: string
            example: '2019-08-22'
        - name: report_licensor
          description: 'Licensor for the requested data'
          in: query
          required: true
          schema:
            type: string
        - name: report_type
          description: 'The type of the report'
          in: query
          required: true
          schema:
            type: string
            example: 'streams'
        - name: version
          description: 'The version number of the report'
          in: query
          required: true
          schema:
            type: string
            example: 'v1_1'
        - $ref: '#/components/parameters/limitParam'
        - $ref: '#/components/parameters/offsetParam'
      responses:
        200:
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FilesResponse'

        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'

  /oauth/token:
    post:
      tags:
        - Auth
      summary: 'get an access token to make authenticated requests'
      operationId: slz_api_service.v1.views.auth.OAuth2.post
      requestBody:
        description: 'access token request body'
        content:
          'application/json':
            schema:
              $ref: '#/components/schemas/authTokenRequestBody'
      responses:
        200:
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/authTokenResponseBody'
        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'

components:
  parameters:
    limitParam:
      in: query
      name: limit
      description: 'The maximum number of `items` to return in a single request.'
      example: 20
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 1000
    offsetParam:
      in: query
      name: offset
      description: 'The number of `items` to skip from the beginning for pagination purposes.'
      example: 0
      schema:
        type: integer
        format: int32
        minimum: 0

  responses:
    InvalidInput:
      description: Invalid Input Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/invalidInputResponseBody'
    Unauthorized:
      description: Unauthorized (AuthError) Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/unauthorizedResponseBody'
    InternalError:
      description: Internal Error Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/interalErrorResponseBody'

  securitySchemes:
    # Currently Swagger UI does not support the client_id and client_secret as POST body params to
    # the access token endpoint (only in the header). Since our implementation uses the body,
    # this section has been commented out.
    # This note is to save you the trouble of trying to make this work.
    #    oauth2Auth:
    #      type: oauth2
    #      flows:
    #        clientCredentials:
    #          tokenUrl: '/v1/oauth/token'
    #          scopes:
    #            read:files: 'Read data from the files resource'
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      x-bearerInfoFunc: slz_api_service.auth.resource_protector.ProxyResourceProtector.decode_token

  schemas:
    authTokenRequestBody:
      type: object
      properties:
        client_id:
          description: 'Required – `client_id` from identity provider credentials'
          type: string
          example: 'REPLACE_WITH_YOUR_CLIENT_ID'
        client_secret:
          description: 'Required – `client_secret` from identity provider credentials'
          type: string
          example: 'REPLACE_WITH_YOUR_CLIENT_SECRET'
        grant_type:
          description: '(optional) Defaults to `client_credentials` as the only currently supported method'
          type: string
          example: 'client_credentials'
    authTokenResponseBody:
      type: object
      properties:
        access_token:
          type: string
          example: 'EXAMPLE7J0JtkhGZzA6MscSiUH8qYwer...'
        scope:
          description: 'After authorizing, the available scopes are returned in a standard space deliminated format.'
          type: string
          example: 'read:files'
        expires_in:
          description: 'Length in seconds until token expiration.'
          type: number
          format: int32
          example: 86400
        expires_at:
          description: 'The timestamp of the token expiration in the (Unix) epoch format.'
          type: number
          format: int64
          example: 1569612083
        token_type:
          description: 'The token type, currently the only implementation is for `Bearer`.'
          type: string
          example: 'Bearer'
    invalidInputResponseBody:
      type: object
      description: InvalidInput Response Body
      properties:
        code:
          type: string
          example: invalid_input
        description:
          type: object
    unauthorizedResponseBody:
      type: object
      description: Unauthorized (AuthError) Response Body
      properties:
        code:
          type: string
          example: invalid_header
        description:
          type: string
          example: 'Unable to parse authentication token'
    interalErrorResponseBody:
      type: object
      description: Internal Error Response Body
      properties:
        code:
          type: string
          example: internal_error
        description:
          type: string
          example: 'The application encountered an internal error'

    ######################################
    # Response Objects
    ######################################

    FilesResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/File'
        count:
          description: 'The number of ``items`` returned in the response'
          type: integer
          format: int32
          example: 20
        status:
          type: string
          example: 'OK'
    File:
      type: object
      properties:
        file_size_bytes:
          type: integer
          description: size of the file in bytes
          example: 8192000
        uri:
          type: string
          format: uri
          description: S3 URI to the compressed file
          example: 's3://{bucket-name}/{dsp}/{report_type}/{version}/report_date={date}/report_licensor={report_licensor}/{filename}.{extension}'
