Soap get arguments with wrong order in twisted - python

Now i use twisted.soap to build my soap server, I'd like to build a function with plural arguments like this:
def soap_searchFlight(self,name=None,startpoint=None,destination=None):
d=Deferred()
d.addCallback(functions.searchFlight)
d.addErrback(functions.failure)
print "name"+name
print "startpoint"+startpoint
print "destination"+destination
requestdic={"name":name,"startpoint":startpoint,"destination":destination}
print requestdic
d.callback(requestdic)
return d.result
and I wrote a script to test :
import SOAPpy
import twisted
p = SOAPpy.SOAPProxy('http://localhost:7080/')
p.config.dumpSOAPOut=1
p.config.dumpSOAPIn=1
print p.searchFlight(name='3548',startpoint="北京飞机场",destination="上海飞机场")
It gives me back like this:
name上海飞机场
startpoint北京飞机场
destination3548
it looks like the args order are totally wrong so what happens and how can i ensure the right order ?

Without seeing functions.searchFlight, it's a little hard to tell, but it appears that you're passing a dict to in in a callback, then assuming that the items in the dict are in a particular order (they're not).
Change the signature of functions.searchFlight to take a tuple, and call it with a tuple in the order you want. (or pass in an ordered dict...or don't assume the dict's items are in the order that you created it in).

Related

Iterate over dictionary to get specific key's count

I am just a beginner in coding, trying to self teach python, then I got a lot of questions in my mind. so consider I have a main.py with a function def catch_urls(**kwargs): I will pass key:value arguments while running the file. My requirement here is there will be a bunch of arguments I pass to the function of which I need to find out the count of pattern matching keys- that means
main.py type=internal url1=google.com url2=yahoo.com timeout=10s url3=stackoverflow.com
Q1. How to get the count of how many url1, url2, url3, .... is given in arguments ? these url* count will vary on each runs then how to get the count of this pattern keys ? can we do something like psuedo code like count(url*)
Q2. Using **kwargs can I actually get these arguments passed into execution ? or do I need to use some library called "click" or so to get these arguments passed into my function ?
The arguments arrive as strings in sys.argv. So, given your example, sys.argv would be a list containing:
[
"main.py",
"type=internal",
"url1=google.com",
"url2=yahoo.com",
"timeout=10s",
"url3=stackoverflow,.com"
]
You can parse those yourself, or you can use the argparse module to parse them.
It's not usually productive to spent a lot of time optimizing code that only gets used once. You could certainly say:
cnt = sum(i.startswith("url") for i in sys.argv)
**kwargs is used for functions within a program. It's not involved in command line arguments.

Can you call/use a function returned from a list in Python?

I'm trying to store a function in a list, retrieve the function from the list later, and then call on that function. This is basically what I want to do, without any specifics. It doesn't show my purpose, but it's the same issue.
elements: list = [] # List meant to contain a tuple with the name of the item and the function of the item.
def quit_code():
exit()
element.append(("quit", quit_code))
Now, somewhere else in the code, I want to be able to use an if statement to check the name of the item and, if it's the right one at that time, run the function.
user_input = "quit" # For brevity, I'm just writing this. Let's just imagine the user actually typed this.
if elements[0][0] == user_input:
#This is the part I don't understand so I'm just going to make up some syntax.
run_method(elements[0][1])
The method run_method that I arbitrarily made is the issue. I need a way to run the method returned by elements[0][1], which is the quit_code method. I don't need an alternative solution to this example because I just made it up to display what I want to do. If I have a function or object that contains a function, how can I run that function.
(In the most simplified way I can word it) If I have object_a (for me it's a tuple) that contains str_1 and fun_b, how can I run fun_b from the object.
To expand on this a little more, the reason I can't just directly call the function is because in my program, the function gets put into the tuple via user input and is created locally and then stored in the tuple.
__list_of_stuff: list = []
def add_to_list(name, function):
__list_of_stuff.append((name, function))
And then somewhere else
def example_init_method():
def stop_code():
exit()
add_to_list("QUIT", stop_code())
Now notice that I can't access the stop_code method anywhere else in the code unless I use it through the __list_of_stuff object.
Finally, It would be nice to not have to make a function for the input. By this, I mean directly inserting code into the parameter without creating a local function like stop_code. I don't know how to do this though.
Python treats functions as first-class citizens. As such, you can do things like:
def some_function():
# do something
pass
x = some_function
x()
Since you are storing functions and binding each function with a word (key), the best approach would be a dictionary. Your example could be like this:
def quit_code():
exit()
operations = dict(quit=quit_code)
operations['quit']()
A dictionary relates a value with a key. The only rule is the key must be immutable. That means numbers, strings, tuples and other immutable objects.
To create a dictionary, you can use { and }. And to get a value by its key, use [ and ]:
my_dictionary = { 'a' : 1, 'b' : 10 }
print(my_dictionary['a']) # It will print 1
You can also create a dictionary with dict, like so:
my_dictionary = dict(a=1, b=10)
However this only works for string keys.
But considering you are using quit_code to encapsulate the exit call, why not using exit directly?
operations = dict(quit=exit)
operations['quit']()
If dictionaries aren't an option, you could still use lists and tuples:
operations = [('quit',exit)]
for key, fun in operations:
if key == 'quit':
fun()

Python ast - getting function parameters and processing them

I'm trying to use the ast module in Python to parse input code, but am struggling with a lot of the syntax of how to do so. For instance, I have the following code as a testing environment:
import ast
class NodeVisitor(ast.NodeVisitor):
def visit_Call(self, node):
for each in node.args:
print(ast.literal_eval(each))
self.generic_visit(node)
line = "circuit = QubitCircuit(3, True)"
tree = ast.parse(line)
print("VISITOR")
visitor = NodeVisitor()
visitor.visit(tree)
Output:
VISITOR
3
True
In this instance, and please correct me if I'm wrong, the visit_Call will be used if it's a function call? So I can get each argument, however there's no guarantee it will work like this as there are different arguments available to be provided. I understand that node.args is providing my arguments, but I'm not sure how to do things with them?
I guess what I'm asking is how do I check what the arguments are and do different things with them? I'd like to check, perhaps, that the first argument is an Int, and if so, run processInt(parameter) as an example.
The value each in your loop in the method will be assigned to the AST node for each of the arguments in each function call you visit. There are lots of different types of AST nodes, so by checking which kind you have, you may be able to learn things about the argument being passed in.
Note however that the AST is about syntax, not values. So if the function call was foo(bar), it's just going to tell you that the argument is a variable named bar, not what the value of that variable is (which it does not know). If the function call was foo(bar(baz)), it's going to show you that the argument is another function call. If you only need to handle calls with literals as their arguments, then you're probably going to be OK, you'll just look instances of AST.Num and similar.
If you want to check if the first argument is a number and process it if it is, you can do something like:
def visit_Call(self, node):
first_arg = node.args[0]
if isinstance(first_arg, ast.Num):
processInt(first_arg.n)
else:
pass # Do you want to do something on a bad argument? Raise an exception maybe?

tornado maps GET and POST arguments to lists. How can I disable this "feature"?

The HTTPRequest class in the tornado* web framework helpfully maps GET and POST arguments to lists. I understand why -- in case a given argument name is used multiple times. But for some RequestHandlers, this is a pain. For instance, if I want to pass a json object and parse it as-is on the server.
What's the most straightforward way to disable the map-to-list behavior so that I can send unaltered json to a tornado/cyclone server?
*Cyclone, actually, in case there's an implementation difference here.
Instead of accessing self.request.arguments directly you should use the accessor functions:
self.get_argument("ID", default=None, strip=False)
This returns a single item.
If you want to turn the arguments into a JSON object you can quite easily do so:
json.dumps({ k: self.get_argument(k) for k in self.request.arguments })
I'm going to go with "you're out of luck." You could re-write the class in question (looks like that would not be fun), but aside from that I don't see many options.
I would just use a dict comprehension.
{k:''.join(v) for k,v in self.request.arguments.iteritems()}

Using Deque.popleft as args for function

I am attempting to store a list of commands to send down a serial cable using deque in Python.
My function "send_command" accepts 3 values; The command, an int. pause and a boolean wait. its definition is as follows.
def send_command(self, command, pause=0, wait=False):
What I would like to do is, rather than calling this function like so:
send_command("A234", 5, True)
... or...
send_command("B4242")
I'd like to be able to store up commands inside a deque list and use the popleft function to then call my function. This would allow me to do things such as:
CommandList = deque((['A234', 5, True], ['B4242']))
...and use the deque.append() as a way to keep adding things to the list, which would then in turn be sent to my send_command function. I could then drop in and out of the list new commands when they are needed (or as quickly as the serial part of my code can do).
The part I'm struggling with is actually using the CommandList.popleft, or any part of the deque list as the args for my send_command function. It doesn't seem as straight forward as:
send_command(CommandList.popleft)
I'm sure it's something simple, but I cannot figure it out.
Can anyone help?
Thank-you kindly.
Andy
probably you need something like:
obj.send_command(*CommandList.popleft())
That is, call popleft and use the result as an argument list for send_command. self argument suggests this is a member function, so you need to call it on an object
Another way, as I wrote in the comment, is to store prepared functions with something like this:
def make_command(obj, *args, **kwargs):
def f():
obj.send_command(*args, **kwargs)
return f
Then you can do
queue.append(make_command(obj, 'ABC', whatever='else'))
and then execute:
command = queue.popleft()
command()
unbeli is right - you need the () to call the function, and you need * to unpack the arguments. However, there's no need for using deque when you can just do this:
commandlist = [['A234', 5, True], ['B4242'], ['A234', 0]]
for command in commandlist:
send_command(*command)
and that will work perfectly fine. For more info, see unpacking argument lists.
Queues are really only necessary if you're doing something in which you want to consume the values - say you want your commandlist to be empty when you're done. Of course you could also do the same thing with a list:
q = [1,2,3,4]
while q:
print q.pop(0)
print q
HTH
Have you tried:
send_command(CommandList.popleft()) # note the ()

Categories

Resources