2017-10-21 5 views
3

私はHTMLQuestionデータ構造とboto3のcreate_hit関数を使ってAmazonのMechanical Turksサービスに提出するためにXMLを構築しようとしています。ドキュメントによると、XMLはlike thisの形式にする必要があります。boto3のためのHTMLQuestion XMLの構築MTurk

クラスTurkTaskAssemblerを作成しました。このクラスにはxmlを生成し、このXMLをAPI経由でMechanical Turksプラットフォームに渡すメソッドがあります。私はAmazonとのコミュニケーションを処理するためにboto3ライブラリを使用します。

私はAPIを介してこのXMLを渡そうとするとき、私は、検証エラーが発生しますので、それはそうのように、私は生成が正しくフォーマットされていないんだXMLようだ:

>>> tta = TurkTaskAssembler("What color is the sky?") 
>>> response = tta.create_hit_task() 
>>> ParamValidationError: Parameter validation failed: Invalid type for parameter Question, value: <Element HTMLQuestion at 0x1135f68c0>, type: <type 'lxml.etree._Element'>, valid types: <type 'basestring'> 

私はその後、修正

>>> tta = TurkTaskAssembler("What color is the sky?") 
>>> tta.create_hit_task() 
>>> ClientError: An error occurred (ParameterValidationError) when calling the CreateHIT operation: There was an error parsing the XML question or answer data in your request. Please make sure the data is well-formed and validates against the appropriate schema. Details: cvc-elt.1.a: Cannot find the declaration of element 'HTMLQuestion'. (1508611228659 s) 

私は本当に私が間違ってやっているかわからないんだけど、非常に小さなXMLの経験を持っている:tostringメソッドを使用して文字列にXMLエンベロープを変換するが、これは別のエラーを生成するcreate_question_xml方法。ここで

は、関連するすべてのコードです:

import os 
import boto3 
from lxml.etree import Element, SubElement, CDATA, tostring 
from .settings import mturk_access_key_id, mturk_access_secret_key 

xml_schema_url = 'http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd' 


class TurkTaskAssembler(object): 

    def __init__(self, question): 
     self.client = boto3.client(
      service_name='mturk', 
      region_name='us-east-1', 
      endpoint_url='https://mturk-requester-sandbox.us-east-1.amazonaws.com', 
      aws_access_key_id=mturk_access_key_id, 
      aws_secret_access_key=mturk_access_secret_key 
     ) 
     self.question = question 

    def create_question_xml(self): 
     # questionFile = open(os.path.join(__location__, "question.xml"), "r") 
     # question = questionFile.read() 
     # return question 
     XHTML_NAMESPACE = xml_schema_url 
     XHTML = "{%s}" % XHTML_NAMESPACE 
     NSMAP = { 
      None : XHTML_NAMESPACE, 
      'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 
      '' 
      } 
     envelope = Element("HTMLQuestion", nsmap=NSMAP) 

     html = """ 
      <!DOCTYPE html> 
      <html> 
      <head> 
       <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/> 
       <script type='text/javascript' src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js'></script> 
      </head> 
      <body> 
       <form name='mturk_form' method='post' id='mturk_form' action='https://www.mturk.com/mturk/externalSubmit'> 
       <input type='hidden' value='' name='assignmentId' id='assignmentId'/> 
       <h1>Answer this question</h1> 
       <p>{question}</p> 
       <p><textarea name='comment' cols='80' rows='3'></textarea></p> 
       <p><input type='submit' id='submitButton' value='Submit' /></p></form> 
       <script language='Javascript'>turkSetAssignmentID();</script> 
      </body> 
      </html> 
      """.format(question=self.question) 

     html_content = SubElement(envelope, 'HTMLContent') 
     html_content.text = CDATA(html) 
     xml_meta = """<?xml version="1.1" encoding="utf-8"?>""" 
     return xml_meta + tostring(envelope, encoding='utf-8') 

    def create_hit_task(self): 
     response = self.client.create_hit(
      MaxAssignments=1, 
      AutoApprovalDelayInSeconds=10800, 
      LifetimeInSeconds=10800, 
      AssignmentDurationInSeconds=300, 
      Reward='0.05', 
      Title='a title', 
      Keywords='some keywords', 
      Description='a description', 
      Question=self.create_question_xml(), 
     ) 
     return response 

答えて

2

なぜ単純に(あなたが行ったように、しかし、コメントアウト)別のXMLファイル内のXMLデータを入れませんか?そうすれば、複数のモジュールと多くのコードを組み込む必要がなくなります。

<HTMLQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd"> 
    <HTMLContent><![CDATA[ 
<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/> 
    <script type='text/javascript' src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js'></script> 
</head> 
<body> 
    <form name='mturk_form' method='post' id='mturk_form' action='https://www.mturk.com/mturk/externalSubmit'> 
    <input type='hidden' value='' name='assignmentId' id='assignmentId'/> 
    <h1>Answer this question</h1> 
    <p>{question}</p> 
    <p><textarea name='comment' cols='80' rows='3'></textarea></p> 
    <p><input type='submit' id='submitButton' value='Submit' /></p></form> 
    <script language='Javascript'>turkSetAssignmentID();</script> 
</body> 
</html> 
]]> 
    </HTMLContent> 
    <FrameHeight>450</FrameHeight> 
</HTMLQuestion> 

次に、あなたのcreate_question_xml()機能に:

def create_question_xml(self): 
    question_file = open("question.xml", "r").read() 
    xml = question_file.format(question=self.question) 
    return xml 

あなたが必要とするすべてである必要があり、あなたがquestion.xmlを作成し、hereを説明したテンプレートを使用して

+0

これは素晴らしい提案です、ありがとうございます!完璧に動作します。 –

0

私はあなたが使用する3つの形式と混同していると思います。 私があなたから見たものはHTMLQuestionでした。 (他の2つはExternalQuestionQuestionFormDataです)。

HTMLQuestion形式で質問を維持するには、ドキュメントで提供されている単純な例を使用してください。これをXMLでラップする必要はありません。ここに固定機能があります:

def create_question_html(self): 
    # you can extract template into a file, 
    # as @Mangohero1 suggested which would simplify code a bit. 

    return """ 
    <HTMLQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd"> 
     <HTMLContent><![CDATA[ 
    <!DOCTYPE html> 
    <html> 
    <head> 
     <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/> 
     <script type='text/javascript' src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js'></script> 
    </head> 
    <body> 
     <form name='mturk_form' method='post' id='mturk_form' action='https://www.mturk.com/mturk/externalSubmit'> 
     <input type='hidden' value='' name='assignmentId' id='assignmentId'/> 
     <h1>{question}</h1> 
     <p><textarea name='comment' cols='80' rows='3'></textarea></p> 
     <p><input type='submit' id='submitButton' value='Submit' /></p></form> 
     <script language='Javascript'>turkSetAssignmentID();</script> 
    </body> 
    </html> 
    ]]> 
     </HTMLContent> 
     <FrameHeight>450</FrameHeight> 
    </HTMLQuestion> 
    """.format(question=self.question) 
関連する問題