Class: QnAMaker::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/qna_maker.rb,
lib/qna_maker/endpoints/train_kb.rb,
lib/qna_maker/endpoints/create_kb.rb,
lib/qna_maker/endpoints/delete_kb.rb,
lib/qna_maker/endpoints/update_kb.rb,
lib/qna_maker/endpoints/publish_kb.rb,
lib/qna_maker/endpoints/download_kb.rb,
lib/qna_maker/endpoints/generate_answer.rb,
lib/qna_maker/endpoints/update_alterations.rb,
lib/qna_maker/endpoints/download_alterations.rb

Overview

Client instance

Constant Summary collapse

BASE_URL =
'https://westus.api.cognitive.microsoft.com/QnAMaker/v2.0/knowledgebases'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(knowledgebase_id, subscription_key, data_extraction_results = []) ⇒ Client

<Description>

Parameters:

  • knowledgebase_id (String)

    this should be get from QnAMaker portal

  • subscription_key (String)

    QnAMaker::Client provides access to this API. Found in your QnAMaker Service accounts (qnamaker.ai

  • data_extraction_results (Array<Hash{String => String, String => String, String => String}>) (defaults to: [])

    ata extraction results.



45
46
47
48
49
50
# File 'lib/qna_maker.rb', line 45

def initialize(knowledgebase_id, subscription_key, data_extraction_results = [])
  @knowledgebase_id = knowledgebase_id
  @subscription_key = subscription_key
  @data_extraction_results = data_extraction_results
  @http = HTTP.headers('Ocp-Apim-Subscription-Key' => @subscription_key)
end

Instance Attribute Details

#data_extraction_resultsObject (readonly)

Returns the value of attribute data_extraction_results.



35
36
37
# File 'lib/qna_maker.rb', line 35

def data_extraction_results
  @data_extraction_results
end

#knowledgebase_idObject (readonly)

Returns the value of attribute knowledgebase_id.



29
30
31
# File 'lib/qna_maker.rb', line 29

def knowledgebase_id
  @knowledgebase_id
end

#subscription_keyObject (readonly)

Returns the value of attribute subscription_key.



32
33
34
# File 'lib/qna_maker.rb', line 32

def subscription_key
  @subscription_key
end

Class Method Details

.create_kb(name, subscription_key, qna_pairs = [], urls = []) ⇒ Client

Creates a new knowledge base.

and KB will be updated with new data. Max 5 urls per request.

Parameters:

  • name (String)

    friendly name for the knowledge base (Required)

  • subscription_key (String)

    Subscription key which provides access to this API. Found in your QnAMaker Service accounts (qnamaker.ai)

  • qna_pairs (Array<Array(String, String)>) (defaults to: [])

    list of question and answer pairs to be added to the knowledge base. Max 1000 Q-A pairs per request.

  • urls (Array<String>) (defaults to: [])

    list of URLs to be processed and indexed in the knowledge base. In case of existing URL, it will be fetched again

Returns:



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/qna_maker/endpoints/create_kb.rb', line 55

def self.create_kb(name, subscription_key, qna_pairs = [], urls = [])
  response = HTTP.headers('Ocp-Apim-Subscription-Key' => subscription_key).post(
    "#{BASE_URL}/create",
    json: {
      name: name,
      qnaPairs: qna_pairs.map { |pair| { question: pair[0], answer: pair[1] } },
      urls: urls
    }
  )

  case response.code
  when 201
    QnAMaker::Client.new(
      response.parse['kbId'],
      subscription_key,
      response.parse['dataExtractionResults']
    )
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

.delete_kb(knowledgebase_id, subscription_key) ⇒ nil

Deletes the specified knowledge base and all data associated with it.

Parameters:

  • knowledgebase_id (String)

    knowledge base identity

  • subscription_key (String)

    Subscription key which provides access to this API. Found in your QnAMaker Service accounts (qnamaker.ai)

Returns:

  • (nil)

    on success



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/qna_maker/endpoints/delete_kb.rb', line 40

def self.delete_kb(knowledgebase_id, subscription_key)
  response = HTTP.headers('Ocp-Apim-Subscription-Key' => subscription_key).delete(
    "#{BASE_URL}/#{knowledgebase_id}"
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 409
    raise ConflictError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

Instance Method Details

#create_kb(name, qna_pairs = [], urls = []) ⇒ Client

Creates a new knowledge base.

Parameters:

  • name (String)

    friendly name for the knowledge base (Required)

  • qna_pairs (Array<Array(String, String)>) (defaults to: [])

    list of question and answer pairs to be added to the knowledge base. Max 1000 Q-A pairs per request.

  • urls (Array<String>) (defaults to: [])

    list of URLs to be processed and indexed in the knowledge base. In case of existing URL, it will be fetched again and KB will be updated with new data. Max 5 urls per request.

Returns:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/qna_maker/endpoints/create_kb.rb', line 14

def create_kb(name, qna_pairs = [], urls = [])
  response = @http.post(
    "#{BASE_URL}/create",
    json: {
      name: name,
      qnaPairs: qna_pairs.map { |pair| { question: pair[0], answer: pair[1] } },
      urls: urls
    }
  )

  case response.code
  when 201
    QnAMaker::Client.new(
      response.parse['kbId'],
      @subscription_key,
      response.parse['dataExtractionResults']
    )
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#delete_kbnil

Deletes the current knowledge base and all data associated with it.

Returns:

  • (nil)

    on success



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/qna_maker/endpoints/delete_kb.rb', line 8

def delete_kb
  response = @http.delete(
    "#{BASE_URL}/#{knowledgebase_id}"
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 409
    raise ConflictError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#download_alterationsArray<Alteration>

Downloads all word alterations (synonyms) that have been automatically

mined or added by the user.

Returns:



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/qna_maker/endpoints/download_alterations.rb', line 9

def download_alterations
  response = @http.get(
    "#{BASE_URL}/#{@knowledgebase_id}/downloadAlterations"
  )

  case response.code
  when 200
    response.parse['wordAlterations'].map do |alteration|
      Alteration.new(
        alteration['word'].normalize,
        alteration['alterations'].map(&:normalize)
      )
    end
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#download_kbString

Downloads all the data associated with the specified knowledge base

Returns:

  • (String)

    SAS url (valid for 30 mins) to tsv file in blob storage



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/qna_maker/endpoints/download_kb.rb', line 8

def download_kb
  response = @http.get(
    "#{BASE_URL}/#{@knowledgebase_id}"
  )

  case response.code
  when 200
    response.parse
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message'].join(' ')
  when 404
    raise NotFoundError, response.parse['error']['message'].join(' ')
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#generate_answer(question, top = 1) ⇒ Array<Answer>

Returns the list of answers for the given question sorted in descending order of ranking score.

Parameters:

  • question (String)

    user question to be queried against your knowledge base.

  • top (Integer) (defaults to: 1)

    number of ranked results you want in the output.

Returns:

  • (Array<Answer>)

    list of answers for the user query sorted in decreasing order of ranking score.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/qna_maker/endpoints/generate_answer.rb', line 14

def generate_answer(question, top = 1)
  response = @http.post(
    "#{BASE_URL}/#{@knowledgebase_id}/generateAnswer",
    json: { question: question, top: top }
  )

  case response.code
  when 200
    response.parse['answers'].map do |answer|
      Answer.new(
        answer['answer'].normalize,
        answer['questions'].map(&:normalize),
        answer['score']
      )
    end
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise QuotaExceededError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 408
    raise OperationTimeOutError, response.parse['error']['message']
  when 429
    raise RateLimitExceededError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#publish_kbnil

Publish all unpublished in the knowledgebase to the prod endpoint

Returns:

  • (nil)

    on success



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/qna_maker/endpoints/publish_kb.rb', line 8

def publish_kb
  response = @http.put(
    "#{BASE_URL}/#{@knowledgebase_id}"
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 409
    raise ConflictError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#train_kb(feedback_records = []) ⇒ nil

The developer of the knowledge base service can use this API to submit user feedback for tuning question-answer matching. QnA Maker uses active learning to learn from the user utterances that come on a published Knowledge base service.

Parameters:

  • feedback_records (Array<Array(String, String, String, String)>) (defaults to: [])

    [user_id, user_question, kb_question, kb_answer]

Returns:

  • (nil)

    on success



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/qna_maker/endpoints/train_kb.rb', line 14

def train_kb(feedback_records = [])
  feedback_records = feedback_records.map do |record|
    { userId: record[0],
      userQuestion: record[1],
      kbQuestion: record[2],
      kbAnswer: record[3] }
  end
  response = @http.patch(
    "#{BASE_URL}/#{@knowledgebase_id}/train",
    json: { feedbackRecords: feedback_records }
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 408
    raise OperationTimeOutError, response.parse['error']['message']
  when 429
    raise RateLimitExceededError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#update_alterations(add = [], delete = []) ⇒ nil

Replaces word alterations (synonyms) for the KB with the give records.

Parameters:

  • add (Array(String, Array<String>)) (defaults to: [])

    word alterations to be added

  • delete (Array(String, Array<String>)) (defaults to: [])

    word alterations to be removed

Returns:

  • (nil)

    on success



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/qna_maker/endpoints/update_alterations.rb', line 11

def update_alterations(add = [], delete = [])
  response = @http.patch(
    "#{BASE_URL}/#{@knowledgebase_id}/updateAlterations",
    json: { add: add.map {|i| {word: i[0], alterations: i[1]} },
    delete: delete.map {|i| {word: i[0], alterations: i[1]} } }
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 409
    raise ConflictError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end

#update_kb(add: [], delete: [], add_urls: []) ⇒ nil

Add or delete QnA Pairs and / or URLs to an existing knowledge base.

Parameters:

  • add (Array<Array(String, String)>) (defaults to: [])

    [question, answer] data to be added to the knowledge base.

  • delete (Array<Array(String, String)>) (defaults to: [])

    [question, answer] data to be removed to the knowledge base.

  • add_urls (Array<String>) (defaults to: [])

    list of URLs to be processed and indexed in the knowledge base.

Returns:

  • (nil)

    on success



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/qna_maker/endpoints/update_kb.rb', line 12

def update_kb(add: [], delete: [], add_urls: [])
  response = @http.patch(
    "#{BASE_URL}/#{@knowledgebase_id}",
    json: {
      add: {
        qnaPairs: add.map { |pair| { question: pair[0], answer: pair[1] } },
        urls: add_urls
      },
      delete: { qnaPairs: delete.map { |pair| { question: pair[0], answer: pair[1] } } }
    }
  )

  case response.code
  when 204
    nil
  when 400
    raise BadArgumentError, response.parse['error']['message'].join(' ')
  when 401
    raise UnauthorizedError, response.parse['error']['message']
  when 403
    raise ForbiddenError, response.parse['error']['message']
  when 404
    raise NotFoundError, response.parse['error']['message']
  when 409
    raise ConflictError, response.parse['error']['message']
  else
    raise UnknownError, "Oh no! (#{response.code})"
  end
end