~ubuntu-branches/ubuntu/karmic/python-boto/karmic

« back to all changes in this revision

Viewing changes to boto/mturk/connection.py

  • Committer: Bazaar Package Importer
  • Author(s): Eric Evans
  • Date: 2007-07-16 17:17:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070716171748-bsw9rlyu0yuui9lb
Tags: upstream-0.9b
ImportĀ upstreamĀ versionĀ 0.9b

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
 
2
#
 
3
# Permission is hereby granted, free of charge, to any person obtaining a
 
4
# copy of this software and associated documentation files (the
 
5
# "Software"), to deal in the Software without restriction, including
 
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
 
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
 
8
# persons to whom the Software is furnished to do so, subject to the fol-
 
9
# lowing conditions:
 
10
#
 
11
# The above copyright notice and this permission notice shall be included
 
12
# in all copies or substantial portions of the Software.
 
13
#
 
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
20
# IN THE SOFTWARE.
 
21
 
 
22
import urllib
 
23
import xml.sax
 
24
from boto import handler
 
25
from boto.mturk.price import Price
 
26
from boto.mturk.question import QuestionForm
 
27
import boto.mturk.notification
 
28
from boto.connection import AWSQueryConnection
 
29
from boto.exception import EC2ResponseError
 
30
from boto.resultset import ResultSet
 
31
 
 
32
class MTurkConnection(AWSQueryConnection):
 
33
    
 
34
    APIVersion = '2006-10-31'
 
35
    SignatureVersion = '1'
 
36
    
 
37
    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
 
38
                 is_secure=False, port=None, proxy=None, proxy_port=None,
 
39
                 host='mechanicalturk.amazonaws.com', debug=0,
 
40
                 https_connection_factory=None):
 
41
        AWSQueryConnection.__init__(self, aws_access_key_id,
 
42
                                    aws_secret_access_key,
 
43
                                    is_secure, port, proxy, proxy_port,
 
44
                                    host, debug, https_connection_factory)
 
45
    
 
46
    def get_account_balance(self):
 
47
        params = {}
 
48
        response = self.make_request('GetAccountBalance', params)
 
49
        body = response.read()
 
50
        if response.status == 200:
 
51
            rs = ResultSet([('AvailableBalance', Price),
 
52
                            ('OnHoldBalance', Price)])
 
53
            h = handler.XmlHandler(rs, self)
 
54
            xml.sax.parseString(body, h)
 
55
            return rs
 
56
        else:
 
57
            raise EC2ResponseError(response.status, response.reason, body)
 
58
    
 
59
    def register_hit_type(self, title, description, reward, duration,
 
60
                          keywords=None, approval_delay=None, qual_req=None):
 
61
        """
 
62
        Register a new HIT Type
 
63
        \ttitle, description are strings
 
64
        \treward is a Price object
 
65
        \tduration can be an integer or string
 
66
        """
 
67
        params = {'Title' : title,
 
68
                  'Description' : description,
 
69
                  'AssignmentDurationInSeconds' : duration}
 
70
        params.update(MTurkConnection.get_price_as_price(reward).get_as_params('Reward'))
 
71
        response = self.make_request('RegisterHITType', params)
 
72
        body = response.read()
 
73
        if response.status == 200:
 
74
            rs = ResultSet()
 
75
            h = handler.XmlHandler(rs, self)
 
76
            xml.sax.parseString(body, h)
 
77
            return rs.HITTypeId
 
78
        else:
 
79
            raise EC2ResponseError(response.status, response.reason, body)
 
80
    
 
81
    def set_email_notification(hit_type, email):
 
82
        """
 
83
        Performs a SetHITTypeNotification operation to set email notification for a specified HIT type
 
84
        """
 
85
        assert type(hit_type) is str, "hit_type argument should be a string."
 
86
        
 
87
        params = {'HITTypeId': hit_type}
 
88
        
 
89
        notification_params = {'Destination': email,
 
90
                               'Transport': 'Email',
 
91
                               'Version': boto.mturk.notification.NOTIFICATION_VERSION }
 
92
        
 
93
        # Set up dict of 'Notification.1.Transport' etc. values
 
94
        notification_rest_params = {}
 
95
        num = 1
 
96
        for key in notification_params:
 
97
            notification_rest_params['Notification.%d.%s' % (num, key)] = notification_params[key]
 
98
        
 
99
        # Update main params dict
 
100
        params.update(notification_rest_params)
 
101
        
 
102
        # Execute operation
 
103
        response = self.make_request('SetHITTypeNotification', params)
 
104
        body = response.read()
 
105
        
 
106
        # From the Developer Guide:
 
107
        # A successful request for the SetHITTypeNotification operation will return with no errors. The 
 
108
        # response will include a SetHITTypeNotificationResult element, which contains the Request (if 
 
109
        # the Request response group is specified). The operation returns no other data.
 
110
        
 
111
        if response.status == 200: # Is this the correct way to test if it worked?
 
112
            rs = ResultSet()
 
113
            h = handler.XmlHandler(rs, self)
 
114
            xml.sax.parseString(body, h)
 
115
            return rs.HITTypeId
 
116
        else:
 
117
            raise EC2ResponseError(response.status, response.reason, body)
 
118
    
 
119
    
 
120
    def create_hit(self, title=None, description=None, keywords=None, reward=0.00,
 
121
                   duration=60*60*24*7, approval_delay=None, qual_req=None, hit_type=None,
 
122
                   question=None, questions=None):
 
123
        """
 
124
        Creates a new HIT.
 
125
        Returns HITId as a string.
 
126
        See: http://docs.amazonwebservices.com/AWSMechanicalTurkRequester/2006-10-31/ApiReference_CreateHITOperation.html
 
127
        """
 
128
        
 
129
        # handle single or multiple questions
 
130
        if question is not None and questions is not None:
 
131
            raise ValueError("Must specify either question (single Question instance) or questions (list), but not both")
 
132
        if question is not None and questions is None:
 
133
            questions = [question]
 
134
        
 
135
        
 
136
        # Handle keywords
 
137
        final_keywords = MTurkConnection.get_keywords_as_string(keywords)
 
138
        
 
139
        # Handle price argument
 
140
        final_price = MTurkConnection.get_price_as_price(reward)
 
141
        
 
142
        # Set up QuestionForm data structure
 
143
        qf = QuestionForm(questions=questions)
 
144
        
 
145
        # Handle basic arguments and set up params dict
 
146
        params = {'Title': title,
 
147
                  'Description' : description,
 
148
                  'Keywords': final_keywords,
 
149
                  'AssignmentDurationInSeconds' : duration,
 
150
                  'Question': qf.get_as_xml() }
 
151
        
 
152
        if approval_delay is not None:
 
153
            params.update({'AutoApprovalDelayInSeconds': approval_delay })
 
154
        
 
155
        params.update(final_price.get_as_params('Reward'))
 
156
        
 
157
        # Handle optional hit_type argument
 
158
        if hit_type is not None:
 
159
            params.update({'HITTypeId': hit_type})
 
160
        
 
161
        # Submit
 
162
        response = self.make_request('CreateHIT', params)
 
163
        body = response.read()
 
164
        if response.status == 200:
 
165
            rs = ResultSet()
 
166
            h = handler.XmlHandler(rs, self)
 
167
            xml.sax.parseString(body, h)
 
168
            
 
169
            return rs.HITId
 
170
            #return rs # return entire ResultSet for testing purposes
 
171
        else:
 
172
            raise EC2ResponseError(response.status, response.reason, body)
 
173
    
 
174
    @staticmethod
 
175
    def get_keywords_as_string(keywords):
 
176
        """
 
177
        Returns a comma+space-separated string of keywords from either a list or a string
 
178
        """
 
179
        if type(keywords) is list:
 
180
            final_keywords = ', '.join(keywords)
 
181
        elif type(keywords) is str:
 
182
            final_keywords = keywords
 
183
        elif keywords is None:
 
184
            final_keywords = ""
 
185
        else:
 
186
            raise TypeError("keywords argument must be a string or a list of strings; got a %s" % type(keywords))
 
187
        return final_keywords
 
188
    
 
189
    @staticmethod
 
190
    def get_price_as_price(reward):
 
191
        """
 
192
        Returns a Price data structure from either a float or a Price
 
193
        """
 
194
        if isinstance(reward, Price):
 
195
            final_price = reward
 
196
        else:
 
197
            final_price = Price(reward)
 
198
        return final_price