Exposing Python Script as an API or Service - python-3.x

I am using Python for quite a while. I have integrated my python code with java UI as well and is working fine.
Now here comes the tricky part.
I need to expose my python script as an API so that it can be executed from anywhere (Any other suggestions to achieve this are also welcomed) without depending on one particular machine where the python scripts are present.
My initial basic code snippet is given below for your reference :
import .....
def main(id1, id2):
do something ........
call sub-function(id1, id2)
do something ........
if __name__ == '__main__':
id1 = sys.argv[1] #Getting first argument from Java UI.
id1 = sys.argv[1] #Getting first argument from Java UI.
main(id1, id2) #Calling Main function using two IDs as arguments.
This code is working fine as long as I point to the script path in my system from java. But I need to change this code structure to expose it as an API or Service. I do not have any idea on how to achieve this. With help of few articles, I tried my luck with Flask framework. But I am not sure how to call main function using flask by supplying arguments.
import .....
from flask import Flask
app = Flask(__name__)
#app.route("/")
def main():
do something ........
id1 = app.config.get['ID1']
id2 = app.config.get['ID2']
call sub-function(id1, id2)
do something ........
if __name__ == '__main__':
#For simplicity I supplied the arguments' values manually instead of getting it from java.
app.config['ID1'] = 101
app.config['ID2'] = 2
app.run(debug=True)
#Commented out calling main function since app.run() will take care
#main(id1, id2) #Calling Main function using two IDs as arguments.
When I execute this and goes to default web address (http://127.0.0.1:5000), I am getting the below error
TypeError: 'builtin_function_or_method' object is not subscriptable
Traceback (most recent call last) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1997, in call return self.wsgi_app(environ, start_response) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1985, in wsgi_app response = self.handle_exception(e) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1540, in handle_exception reraise(exc_type, exc_value, tb) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask_compat.py",
line 33, in reraise raise value File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1982, in wsgi_app response = self.full_dispatch_request() File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1614, in full_dispatch_request rv = self.handle_user_exception(e) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1517, in handle_user_exception reraise(exc_type, exc_value, tb) File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask_compat.py",
line 33, in reraise raise value File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1612, in full_dispatch_request rv = self.dispatch_request() File
"C:\Users\user_name\Anaconda3\lib\site-packages\flask\app.py", line
1598, in dispatch_request return
self.view_functionsrule.endpoint File
"C:\Users\user_name\Main_Script.py", line 29, in main id1 =
app.config.get['ID1'] TypeError: 'builtin_function_or_method' object
is not subscriptable The debugger caught an exception in your WSGI
application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you
can click on the "Traceback" headline. From the text traceback you can
also create a paste of it. For code execution mouse-over the frame you
want to debug and click on the console icon on the right side.
You can execute arbitrary Python code in the stack frames and there
are some extra helpers available for introspection:
dump() shows all variables in the frame dump(obj) dumps all that's
known about the object
Can anyone please let me know how to resolve this and how to execute this script from any machine by exposing it as an API or service.

As I understand you are looking to remotely call the Python function and pass arguments into it and get back the result.
For example:
#app.route('/<string:idOne>/<string:idTwo>')
def main(idOne,idTwo):
do something
return something
Now you can just make a HTTP GET request.
For example:
http://127.0.0.1:5000/myFirstArg/mySecondArg

Related

Python code for DynamoDB query is working on v3.6 but not working in python 2.7

I have a DynamoDB query with boto3 framework, which works on my local machine running Python 3.6, but not my server running Python 2.7.
The working code on my local machine:
dyndb = boto3.resource('dynamodb')
table = dyndb.Table('XXXXXXX')
response = table.query(
IndexName = "XXX-XXX-index",
ProjectionExpression = "AssessID,SNo,Details,Status,OTP",
KeyConditionExpression = Key('OTP').eq(otp))
The code running on server...
global user_otp
dyndb = boto3.resource('dynamodb')
table = dyndb.Table('XXXXXX')
otp = int(user_otp)
print("converting string otp to int otp") # it is printed on console
response = table.query(
IndexName = "XXX-XXX-index",
ProjectionExpression = "AssessID,SNo,Details,Status,OTP",
KeyConditionExpression = Key('OTP').eq(otp) & Key('SNo').between(1,5))
print ("response code is executing file") # it is not printed on console
When I print the output, the first print is shown but not the second print after the table query.
I am making this query on global index with OTP as partition key and SNo as sort key. I get results on my local machine with only the partition key, but not on my server, even using both the partition and sort key.
DynamoDB does not raise any exceptions. instead I am getting tornado websocket exception.
control coming to process and response function
user otp mentioned is 3086and its type <type 'int'>
converting string otp to int otp
ERROR:tornado.application:Exception in callback <functools.partial object at 0x7f33b6ce7890>
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/tornado/ioloop.py", line 758, in _run_callback
ret = callback()
File "/usr/lib64/python2.7/site-packages/tornado/stack_context.py", line 300, in null_wrapper
return fn(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/tornado/ioloop.py", line 779, in _discard_future_result
future.result()
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 261, in result
raise_exc_info(self._exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 1141, in run
yielded = self.gen.throw(*exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/websocket.py", line 888, in _receive_frame_loop
yield self._receive_frame()
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 1133, in run
value = future.result()
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 261, in result
raise_exc_info(self._exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 1147, in run
yielded = self.gen.send(value)
File "/usr/lib64/python2.7/site-packages/tornado/websocket.py", line 975, in _receive_frame
handled_future = self._handle_message(opcode, data)
File "/usr/lib64/python2.7/site-packages/tornado/websocket.py", line 1000, in _handle_message
return self._run_callback(self.handler.on_message, decoded)
File "/usr/lib64/python2.7/site-packages/tornado/websocket.py", line 548, in _run_callback
self.handler.log_exception(*sys.exc_info())
AttributeError: 'WebSocketClientConnection' object has no attribute 'log_exception'
I think "no attribute log_exception" was a bug in Tornado 5 that was fixed in Tornado 6. However, Tornado 6 only supports Python 3, so in Python 2 you get the older version.
There's also another error here, but you can't see what it is because Python 2's error handling is not as good as Python 3's. And the error apparently doesn't occur on Python 3. If you must continue to support Python 2, try adding a try/except block around the body of your on_message callback (or use the read_message interface instead of the on_message callback).

Cannot run bind() with ldap3 in python3

Below is my code to try and query my ldap server. However, for some reason, I cannot seem to make the bind command work to progress in my code. I continue to get the following message and am not sure what it means or how to fix it. I apologize about the error message formatting. I tried my best to make it as readable as possible.
Any help would be greatly appreciated!
>>> from ldap3 import Server, Connection, SUBTREE
>>> server = Server('<server_name>')
>>> conn = Connection(server, user='<username>', password='<password>')
>>> conn.open()
>>> conn.bind()
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/site-packages/ldap3/core/connection.py", line 427, in bind
response = self.post_send_single_response(self.send('bindRequest', request, controls))
File "/usr/lib/python3.5/site-packages/ldap3/strategy/sync.py", line 122, in post_send_single_response
responses, result = self.get_response(message_id)
File "/usr/lib/python3.5/site-packages/ldap3/strategy/base.py", line 298, in get_response
responses = self._get_response(message_id)
File "/usr/lib/python3.5/site-packages/ldap3/strategy/sync.py", line 168, in _get_response
dict_response = self.decode_response(ldap_resp)
File "/usr/lib/python3.5/site-packages/ldap3/strategy/base.py", line 403, in decode_response
result = bind_response_to_dict(component)
File "/usr/lib/python3.5/site-packages/ldap3/operation/bind.py", line 119, in bind_response_to_dict
'saslCreds': bytes(response['serverSaslCreds']) if response['serverSaslCreds'] is not None else None}
File "/usr/lib/python3.5/site-packages/pyasn1/type/univ.py", line 984, in bytes
return bytes(self._value)
File "/usr/lib/python3.5/site-packages/pyasn1/type/base.py", line 164, in plug
raise error.PyAsn1Error('Uninitialized ASN.1 value ("%s" attribute looked up)' % name)
pyasn1.error.PyAsn1Error: Uninitialized ASN.1 value ("len" attribute looked up)

Unable to use print_control_identifiers() for my desktop application in pywinauto

Hi I am unable to use the "print_control_identifiers()" for my desktop application.
I am using a) Python 3.5.3 (32 bit since my application I am automating is 32 bit)
b) Pywinauto 0.6.2.
My simple code is as follows:
`from pywinauto import Application
app = Application(backend="uia")
app = Application().start(r"C:\Program Files (x86)\Trane\TRACE 3D Plus\TRACE™ 3D Plus.exe")
app['TRACE™ 3D Plus'].print_control_identifiers()`
When I run the above command, I got the following in command prompt:
Traceback (most recent call last):
File "D:\Python\lib\site-packages\pywinauto\application.py", line 243, in __re
solve_control
criteria)
File "D:\Python\lib\site-packages\pywinauto\timings.py", line 424, in wait_until_passes
raise err
pywinauto.timings.TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "inspect.py", line 4, in <module>
app['TRACE\u2122 3D Plus'].print_control_identifiers()
File "D:\Python\lib\site-packages\pywinauto\application.py", line 573, in prin
t_control_identifiers
this_ctrl = self.__resolve_control(self.criteria)[-1]
File "D:\Python\lib\site-packages\pywinauto\application.py", line 246, in __re
solve_control
raise e.original_exception
File "D:\Python\lib\site-packages\pywinauto\timings.py", line 402, in wait_unt
il_passes
func_val = func(*args)
File "D:\Python\lib\site-packages\pywinauto\application.py", line 188, in __ge
t_ctrl
dialog = self.backend.generic_wrapper_class(findwindows.find_element(**crite
ria[0]))
File "D:\Python\lib\site-packages\pywinauto\findwindows.py", line 84, in find_
element
elements = find_elements(**kwargs)
File "D:\Python\lib\site-packages\pywinauto\findwindows.py", line 294, in find
_elements
elements = findbestmatch.find_best_control_matches(best_match, wrapped_elems
)
File "D:\Python\lib\site-packages\pywinauto\findbestmatch.py", line 534, in fi
nd_best_control_matches
raise MatchError(items = name_control_map.keys(), tofind = search_text)
pywinauto.findbestmatch.MatchError: Could not find 'TRACE\u2122 3D Plus' in 'dic
t_keys([])'
Can anyone tell me what the problem is and what I could do to resolve it ?
Thanks in advance !
Replace these commands
app = Application(backend="uia")
app = Application().start(r"C:\Program Files (x86)\Trane\TRACE 3D Plus\TRACE™ 3D Plus.exe")
with this one:
app = Application(backend="uia").start(r'"C:\Program Files (x86)\Trane\TRACE 3D Plus\TRACE™ 3D Plus.exe"')
Because you re-create app object with default backend="win32" if not using any argument. If it's hard to understand, I'd recommend to get a Python course first. Basic Python programming skills is necessary here to understand what's going on.

When using Flask with python 3 and SimpleITK 0.10.0 together, i am getting AttributeError: type object 'object' has no attribute '__getattr__'

When i run the code for Updating Tags in a DCM file using SimpleITK 0.10.0 in Python 3 (https://itk.org/SimpleITKDoxygen010/html/Python_2DicomModifyTags_8py-example.html) the code is working as explained.
the moment i introduce flask components in the code to create an API, i get
AttributeError: type object 'object' has no attribute '__getattr__'
error. The Code i have used is as below
from __future__ import print_function
import SimpleITK
from flask import Flask
import time
app = Flask(__name__)
#app.route('/fuse')
def fuse():
image = SimpleITK.ReadImage("CT/IMG-0002-000001.dcm")
mean_image = SimpleITK.BoxMean( image, [3,3,1])
all_keys = image.GetMetaDataKeys()
for key in all_keys:
mean_image.SetMetaData(key, image.GetMetaData(key))
mean_image.SetMetaData("0008|0008", "DERIVED\SECONDARY")
modification_time = time.strftime("%H%M%S")
modification_date = time.strftime("%Y%m%d")
mean_image.SetMetaData("0008|0031", modification_time)
mean_image.SetMetaData("0008|0021", modification_date)
print(mean_image.GetMetaData("0008|0031"))
return "finish"
the error i am getting is below
[2016-10-05 14:47:05,816] ERROR in app: Exception on /fuse [GET]
Traceback (most recent call last):
File "c:\python27\lib\site-packages\flask\app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "c:\python27\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "c:\python27\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "c:\python27\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "c:\python27\lib\site-packages\flask\app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "E:\ITK_EXP_10\exp2.py", line 24, in fuse
keyable(mean_image, image, key)
File "E:\ITK_EXP_10\exp2.py", line 12, in keyable
mean_image.SetMetaData(key, image.GetMetaData(key))
File "c:\python27\lib\site-packages\SimpleITK\SimpleITK.py", line 3579, in <lambda>
__getattr__ = lambda self, name: _swig_getattr(self, Image, name)
File "c:\python27\lib\site-packages\SimpleITK\SimpleITK.py", line 74, in _swig_getattr
return _swig_getattr_nondynamic(self, class_type, name, 0)
File "c:\python27\lib\site-packages\SimpleITK\SimpleITK.py", line 69, in _swig_getattr_nondynamic
return object.__getattr__(self, name)
AttributeError: type object 'object' has no attribute '__getattr__'
127.0.0.1 - - [05/Oct/2016 14:47:05] "GET /fuse HTTP/1.1" 500 -
127.0.0.1 - - [05/Oct/2016 14:47:05] "GET /favicon.ico HTTP/1.1" 404 -
i am a beginner in python coding, actually beginner in coding itself, can some one please help me fix this issue, or help me understand the issue so that i can fix it?
Thanks in advance
the issue was because of different versions of python running in pycharm and terminal. The terminal was running 2.7 and pycharm was 3.5. the lib was updated in 3.5. sorry for the confusion

Optional user input with timeout for Python 3

I am trying to make a code that will ask for a user input and if that input is not given in a set amount of time will assume a default value and continue through the rest of the code without requiring the user to hit enter. I am running in Python 3.5.1 on Windows 10.
I have looked through: Keyboard input with timeout in Python, How to set time limit on raw_input, Timeout on a function call, and Python 3 Timed Input black boxing the answers but none of the answers are suitable as they are not usable on Windows (principally use of signal.SIGALRM which is only available on linux), or require a user to hit enter in order to exit the input.
Based upon the above answers however i have attempted to scrap together a solution using multiprocessing which (as i think it should work) creates one process to ask for the input and creates another process to terminate the first process after the timeout period.
import multiprocessing
from time import time,sleep
def wait(secs):
if secs == 0:
return
end = time()+secs
current = time()
while end>current:
current = time()
sleep(.1)
return
def delay_terminate_process(process,delay):
wait(delay)
process.terminate()
process.join()
def ask_input(prompt,term_queue,out_queue):
command = input(prompt)
process = term_queue.get()
process.terminate()
process.join()
out_queue.put(command)
##### this doesn't even remotly work.....
def input_with_timeout(prompt,timeout=15.0):
print(prompt)
astring = 'no input'
out_queue = multiprocessing.Queue()
term_queue = multiprocessing.Queue()
worker1 = multiprocessing.Process(target=ask_input,args=(prompt,term_queue,out_queue))
worker2 = multiprocessing.Process(target=delay_terminate_process,args=(worker1,timeout))
worker1.daemon = True
worker2.daemon = True
term_queue.put(worker2)
print('Through overhead')
if __name__ == '__main__':
print('I am in if statement')
worker2.start()
worker1.start()
astring = out_queue.get()
else:
print('I have no clue what happened that would cause this to print....')
return
print('returning')
return astring
please = input_with_timeout('Does this work?',timeout=10)
But this fails miserably and yields:
Does this work?
Through overhead
I am in if statement
Traceback (most recent call last):
File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
obj = ForkingPickler.dumps(obj)
File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
File "C:\Anaconda3\lib\multiprocessing\queues.py", line 58, in __getstate__
context.assert_spawning(self)
File "C:\Anaconda3\lib\multiprocessing\context.py", line 347, in assert_spawning
' through inheritance' % type(obj).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance
Does this work?
Through overhead
I have no clue what happened that would cause this to print....
Does this work?Process Process-1:
Traceback (most recent call last):
File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
obj = ForkingPickler.dumps(obj)
File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
File "C:\Anaconda3\lib\multiprocessing\process.py", line 287, in __reduce__
'Pickling an AuthenticationString object is '
TypeError: Pickling an AuthenticationString object is disallowed for security reasons
Traceback (most recent call last):
File "C:\Anaconda3\lib\multiprocessing\process.py", line 254, in _bootstrap
self.run()
File "C:\Anaconda3\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "C:\Anaconda3\saved_programs\a_open_file4.py", line 20, in ask_input
command = input(prompt)
EOFError: EOF when reading a line
Does this work?
Through overhead
I have no clue what happened that would cause this to print....
Traceback (most recent call last):
File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
obj = ForkingPickler.dumps(obj)
File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
File "C:\Anaconda3\lib\multiprocessing\queues.py", line 58, in __getstate__
context.assert_spawning(self)
File "C:\Anaconda3\lib\multiprocessing\context.py", line 347, in assert_spawning
' through inheritance' % type(obj).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance
Process Process-2:
Traceback (most recent call last):
File "C:\Anaconda3\lib\multiprocessing\process.py", line 254, in _bootstrap
self.run()
File "C:\Anaconda3\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "C:\Anaconda3\saved_programs\a_open_file4.py", line 16, in delay_terminate_process
process.terminate()
File "C:\Anaconda3\lib\multiprocessing\process.py", line 113, in terminate
self._popen.terminate()
AttributeError: 'NoneType' object has no attribute 'terminate'
I really don't understand the multiprocessing module well and although I have read the official docs am unsure why this error occurred or why it appears to have ran through the function call 3 times in the process. Any help on how to either resolve the error or achieve an optional user input in a cleaner manner will be much appreciated by a noob programmer. Thanks!

Resources