TypeError: scenario() - typeerror

_ ERROR collecting tests/step_defs/test_service.py _____________________________________________________________
tests\step_defs\test_service.py:19: in
scenarios('../features/service.feature', example_converters=dict(phrase=str))
C:\Users\User.virtualenvs\tau-pytest-bdd-chapter-6-o7uEFzv0\lib\site-packages\pytest_bdd\scenario.py:327: in scenarios
#scenario(feature.filename, scenario_name, **kwargs)
E TypeError: scenario() got an unexpected keyword argument 'example_converters'
I have this error running a test
here is the code
Shared Variables
DUCKDUCKGO_API = 'https://api.duckduckgo.com/'
Scenarios
scenarios('../features/service.feature', example_converters=dict(phrase=str))
Given Steps
#given('the DuckDuckGo API is queried with ""', target_fixture='ddg_response')
def ddg_response(phrase):
params = {'q': phrase, 'format': 'json'}
response = requests.get(DUCKDUCKGO_API, params=params)
return response
Then Steps
#then('the response contains results for ""')
def ddg_response_contents(ddg_response, phrase):
# A more comprehensive test would check 'RelatedTopics' for matching phrases
assert phrase.lower() == ddg_response.json()['Heading'].lower()
#then(parsers.parse('the response status code is "{code:d}"'))
def ddg_response_code(ddg_response, code):
assert ddg_response.status_code == code

Related

HTTP error 422 in authentication responses

I have get an error for response 422. May i know how can i resolve this?
class FormsAPI:
def __init__(self, key):
self.authorization_key = personal_forms_authorization_key
def getFormInformation(self, formID):
'''
Get forms details.
return: list_form details
'''
url = 'https://api.bentley.com/forms/'
print(url)
try:
params = {'id': formID
}
headers = {'Accept': 'application/vnd.bentley.itwin-platform.v1+json',
'Authorization': self.authorization_key}
response = requests.get(url, headers=headers, params=params)
print(response)
if(response.status_code == 200):
content = jsonParser(response.text)
list_FormDetails = content
return list_FormDetails
else:
return "error"
except Exception as e:
print(e)
list_FormDetails = FormsAPI.getFormInformation(formID)
See answer from laurynasr for same question at https://github.com/imodeljs/imodeljs/discussions/1626:
422 is returned from the Forms API, not as part of the authentication -- it means that the client provided some parameters that could not be processed. The response payload contains more details.

Karate framework variable usage

I have this steps:
...
Then status 200
And match response.requests[0].request.url == "/endpoint"
And json body = response.requests[0].request.body
And match body == { "something": "something"}
To simplify, I tried to put response.requests[0].request in a variable called request:
...
Then status 200
And def request = response.requests[0].request
And match request.url == "/endpoint"
And json body = request.body
And match body == { "something": "something"}
I'm having the following error:
'request' is not a variable, use the form '* request <expression>' instead
I read the documentation and the use of request seems to be fine:
Given def color = 'red '
And def num = 5
Then assert color + num == 'red 5'
What am I doing wrong?
Thanks in advance.
Just make this change:
* def req = response.requests[0].request
# other steps
* request req
We simply disallow def request (using request as a variable name) because a lot of newbie users get confused. The error message has worked 99.9% of the time for users to understand what the problem is, but I guess you fall in the 0.1% :)

apollo-upload-client and graphene-django

I have a question about using apollo-upload-client and graphene-django. Here I've discovered that apollo-upload-client adding operations to formData. But here graphene-django is only trying to get query parameter. And the question is, where and how it should be fixed?
If you're referring to the data that has a header like (when viewing the HTTP from Chrome tools):
Content-Disposition: form-data; name="operations"
and data like
{"operationName":"MyMutation","variables":{"myData"....}, "query":"mutation MyMutation"...},
the graphene-python library interprets this and assembles it into a query for you, inserting the variables and removing the file data from the query. If you are using Django, you can find all of the uploaded files in info.context.FILES when writing a mutation.
Here's my solution to support the latest apollo-upload-client (8.1). I recently had to revisit my Django code when I upgraded from apollo-upload-client 5.x to 8.x. Hope this helps.
Sorry I'm using an older graphene-django but hopefully you can update the mutation syntax to the latest.
Upload scalar type (passthrough, basically):
class Upload(Scalar):
'''A file upload'''
#staticmethod
def serialize(value):
raise Exception('File upload cannot be serialized')
#staticmethod
def parse_literal(node):
raise Exception('No such thing as a file upload literal')
#staticmethod
def parse_value(value):
return value
My upload mutation:
class UploadImage(relay.ClientIDMutation):
class Input:
image = graphene.Field(Upload, required=True)
success = graphene.Field(graphene.Boolean)
#classmethod
def mutate_and_get_payload(cls, input, context, info):
with NamedTemporaryFile(delete=False) as tmp:
for chunk in input['image'].chunks():
tmp.write(chunk)
image_file = tmp.name
# do something with image_file
return UploadImage(success=True)
The heavy lifting happens in a custom GraphQL view. Basically it injects the file object into the appropriate places in the variables map.
def maybe_int(s):
try:
return int(s)
except ValueError:
return s
class CustomGraphqlView(GraphQLView):
def parse_request_json(self, json_string):
try:
request_json = json.loads(json_string)
if self.batch:
assert isinstance(request_json,
list), ('Batch requests should receive a list, but received {}.').format(
repr(request_json))
assert len(request_json) > 0, ('Received an empty list in the batch request.')
else:
assert isinstance(request_json, dict), ('The received data is not a valid JSON query.')
return request_json
except AssertionError as e:
raise HttpError(HttpResponseBadRequest(str(e)))
except BaseException:
logger.exception('Invalid JSON')
raise HttpError(HttpResponseBadRequest('POST body sent invalid JSON.'))
def parse_body(self, request):
content_type = self.get_content_type(request)
if content_type == 'application/graphql':
return {'query': request.body.decode()}
elif content_type == 'application/json':
return self.parse_request_json(request.body.decode('utf-8'))
elif content_type in ['application/x-www-form-urlencoded', 'multipart/form-data']:
operations_json = request.POST.get('operations')
map_json = request.POST.get('map')
if operations_json and map_json:
operations = self.parse_request_json(operations_json)
map = self.parse_request_json(map_json)
for file_id, f in request.FILES.items():
for name in map[file_id]:
segments = [maybe_int(s) for s in name.split('.')]
cur = operations
while len(segments) > 1:
cur = cur[segments.pop(0)]
cur[segments.pop(0)] = f
logger.info('parse_body %s', operations)
return operations
else:
return request.POST
return {}

Posting another web query during render_GET or render_POST processing

I have a small web server written using Twisted. One of the things I want to do is have it return a result from another web server as the response to loading a page. That is, the response to render_GET() at server A (via http://A.com/resource) should be the content of a different URL at server B (via http://B.com/resource2). The content returned by server B is dynamic, so I can't just cache it.
Right now, server A can render pages just fine, it just can't render this remote resource. I've tried with Agent(), but I can't seem to get the response from B let alone forward it to A. I know that somewhere I have to take that request from the render_GET and later write() and finish() it. That's done in the cbBody callback, which get called but can't get to the original request to populate it.
Here's a piece of the code for server A's resource handler:
def render_GET(self,request):
# try with canned content just to test the whole thing
bmpServer = BMPServer(ServerBURL,
"xyzzy",
"plugh")
d= bmpServer.postNotification({"a":123},request)
print "Deferred", d
return NOT_DONE_YET
And this is the other code at server A:
theRequest = None
def cbRequest(response,args):
print "response called"
print response
print args
print 'Response version:', response.version
print 'Response code:', response.code
print 'Response phrase:', response.phrase
print 'Response headers:'
print pformat(list(response.headers.getAllRawHeaders()))
d = readBody(response)
d.addCallback(cbBody)
return d
def cbBody(body):
print "Response body:"
print body
theRequest.write(body)
theRequest.finish()
theRequest = None
def cbError(failure):
print type(failure.value), failure # catch error here
print failure.value.reasons[0].printTraceback()
class BMPServer(object):
def __init__(self,url,arg1,arg2):
self.url = url
self.arg1 = arg1
self.arg2 = arg2
def postNotification(self,message,request):
theRequest = request
bmpMessage = {'arg1':self.token,
'arg2':self.appID,
'message':message}
print "Sending request to %s"%self.url
print "Create agent"
agent = Agent(reactor)
print "create request deferred"
print "url = %s" % self.url
d = agent.request('POST', self.url,
Headers({'User-Agent': ['Twisted Web Client Example']}),
MessageProducer(bmpMessage))
print "adding callback"
d.addCallbacks(cbRequest,cbError)
print "returning deferred"
return d
When I run this as a standalone code (outside of the resource, using react() for example), it works fine. However, when I try to include it as shown above it just never seems to receive the data. I've got WireShark running so I can see the response is being returned from Server B, but the data never shows up in cbRequest().
For example, here's the output I see:
Sending request to http://localhost:8888/postMGCMNotificationService
Create agent
create request deferred
url = http://serverB:8888/postService
Message producer: body = {"arg2": "plugh", "arg1": "xyzzy", "message": {"a": 1}}
adding callback
returning deferred
testAgent: returning deferred
<Deferred at 0x10b54d290>
Writing body now
response called
<twisted.web._newclient.Response object at 0x1080753d0>
Response version: ('HTTP', 1, 1)
Response code: 200
Response phrase: OK
Response headers:
Response body:
{"result": false}
^CUnhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/Twisted-13.1.0_r39314-py2.7-macosx-10.8-intel.egg/twisted/web/_newclient.py", line 1151, in _bodyDataFinished_CONNECTED
self._bodyProtocol.connectionLost(reason)
File "/Library/Python/2.7/site-packages/Twisted-13.1.0_r39314-py2.7-macosx-10.8-intel.egg/twisted/web/client.py", line 1793, in connectionLost
self.deferred.callback(b''.join(self.dataBuffer))
File "/Library/Python/2.7/site-packages/Twisted-13.1.0_r39314-py2.7-macosx-10.8-intel.egg/twisted/internet/defer.py", line 382, in callback
self._startRunCallbacks(result)
File "/Library/Python/2.7/site-packages/Twisted-13.1.0_r39314-py2.7-macosx-10.8-intel.egg/twisted/internet/defer.py", line 490, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/Library/Python/2.7/site-packages/Twisted-13.1.0_r39314-py2.7-macosx-10.8-intel.egg/twisted/internet/defer.py", line 577, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "AServer.py", line 85, in cbBody
print theRequest
exceptions.UnboundLocalError: local variable 'theRequest' referenced before assignment
Looking at this a little more, it seems that if I could figure out a way to get the request over to cbBody() this would all work just fine.
You can pass extra arguments to callbacks on a Deferred:
d.addCallback(f, x)
When d fires, the result is f(result of d, x). You can pass as many positional or keyword arguments as you like this way. See the API documentation for Deferred for more details.

A WSGI replacement for CGIXMLRPCRequestHandler?

It is well understood that forking a process for running Python, as CGI does, is slower than embedding Python, as WSGI does. I would like to implement an XML-RPC interface using the SimpleXMLRPCServer included in the standard Python library and I already have an implementation that works via CGI. I believe there should be a faster way. I'd like to try WSGI but first I need a request handler for WSGI and there does not appear to be one in SimpleXMLRPCServer already. Am I all wet or is there no equivalent of this in the standard library under Python 2.6, 2.7, 3.x?
Here is my initial implementation of a WSGI replacement for CGIXMLRPCRequestHandler:
from xmlrpclib import SimpleXMLRPCDispatcher
class WSGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
"""Simple handler for XML-RPC data passed through WSGI."""
def __init__(self, allow_none = False, encoding = None):
SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
def __call__(self, environ, start_response):
"""Parse and handle a single XML-RPC request"""
result = []
method = environ['REQUEST_METHOD']
headers = [('Content-type', 'text/html')]
if method != 'POST':
# Default implementation indicates an error because XML-RPC uses the POST method.
code = 400
message, explain = BaseHTTPServer.BaseHTTPRequestHandler.responses[code]
status = '%d %s' % (code, message)
if method == 'HEAD':
response = ''
else:
response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % {'code' : code, 'message' : message, 'explain' : explain}
else:
# Dispatch XML-RPC to implementation
status = '200 OK'
request = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
response = self._marshaled_dispatch(request)
length = len(response)
if length > 0:
result = [response]
headers.append(('Content-length', str(length)))
start_response(status, headers)
return result
Take a look at this Hope it'll help.