I have a code that tries to open the SAP GUI application and after putting the user's credentials, it runs a transaction and downloads the .xlsx file on the local.
In the second part of the code which is the exact .vbs script that I recorded in SAP GUI and pasted in Spyder.
I get a syntax error at the line if not IsObject(application) Then, how to solve it?
NB: I tried to use the same indentation as I used in Spyder after several edits.
< Importing the Libraries >
import win32com.client
import sys
import subprocess
import time
##This function will Login to SAP from the SAP Logon window
def saplogin():
try:
path = r"C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
subprocess.Popen(path)
time.sleep(10)
SapGuiAuto = win32com.client.GetObject('SAPGUI')
if not type(SapGuiAuto) == win32com.client.CDispatch:
return
application = SapGuiAuto.GetScriptingEngine
if not type(application) == win32com.client.CDispatch:
SapGuiAuto = None
return
connection = application.OpenConnection("=PR1 [Assembly & Test] router 1", True)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return
session = connection.Children(0)
if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "UName"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "Pass"
session.findById("wnd[0]").sendVKey(0)
##This part is the SAP .vbs script which is recorded in the SAP and pasted here as-is: **>
if not IsObject(application) Then ##here I get the invalid syntax error.
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End if
if not IsObject(connection) Then
Set connection = application.Children(0)
End if
if not IsObject(session) Then
Set session = connection.Children(0)
End if
if IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End if
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").text = "SPT52"
session.findById("wnd[0]/tbar[0]/btn[0]").press
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/chkP_17REQS").selected = false
session.findById("wnd[0]/usr/chkP_18REQS").selected = false
session.findById("wnd[0]/usr/chkP_10REQS").selected = false
session.findById("wnd[0]/usr/chkP_ENGINE").selected = false
session.findById("wnd[0]/usr/chkP_DETAIL").selected = false
session.findById("wnd[0]/usr/radRB_FILE").select
session.findById("wnd[0]/usr/ctxtP_PLANT").text = "0010"
session.findById("wnd[0]/usr/ctxtPD_SEL-LOW").text = "86A"
session.findById("wnd[0]/usr/txtP_FDAY2").text = "0"
session.findById("wnd[0]/usr/txtP_WEEK2").text = "52"
session.findById("wnd[0]/usr/txtP_MONTH2").text = "0"
session.findById("wnd[0]/usr/txtP_FDAY2").setFocus
session.findById("wnd[0]/usr/txtP_FDAY2").caretPosition = 3
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[1]/usr/ctxtDY_PATH").setFocus
session.findById("wnd[1]/usr/ctxtDY_PATH").caretPosition = 0
session.findById("wnd[1]").sendVKey 4
session.findById("wnd[2]").close
session.findById("wnd[1]/usr/ctxtDY_PATH").text = "C:\Users\Documents\SAP\SAP GUI\"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").text = "SP032.xls"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").setFocus
session.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 8
session.findById("wnd[1]/tbar[0]/btn[11]").press
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[0]/tbar[0]/btn[3]").press
except:
print(sys.exc_info()[0])
finally:
session = None
connection = None
application = None
SapGuiAuto = None
saplogin()
I did the changes after Sandra Rossi's comment as following but get a new error:
import win32com.client
import sys
import subprocess
import time
This function will Login to SAP from the SAP Logon window
try:
path = r"C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
subprocess.Popen(path)
time.sleep(2)
SapGuiAuto = win32com.client.GetObject('SAPGUI')
if not type(SapGuiAuto) == win32com.client.CDispatch:
return
application = SapGuiAuto.GetScriptingEngine
if not type(application) == win32com.client.CDispatch:
SapGuiAuto = None
return
connection = application.OpenConnection("=PR1 [Assembly & Test] router 1", True)
if not type(connection) == win32com.client.CDispatch:
application = None
SapGuiAuto = None
return
session = connection.Children(0)
if not type(session) == win32com.client.CDispatch:
connection = None
application = None
SapGuiAuto = None
return
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "Uname"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "Pass"
session.findById("wnd[0]").sendVKey(0)
session.findById("wnd[0]").resizeWorkingPane (98,16,False)
session.findById("wnd[0]/tbar[0]/okcd").text = "SP032"
session.findById("wnd[0]").sendVKey (0)
session.findById("wnd[0]/usr/radP_MATL").select
session.findById("wnd[0]/usr/chkP_LTPC").selected = False
session.findById("wnd[0]/usr/ctxtS_FEVOR-LOW").text = "86A"
session.findById("wnd[0]/usr/radP_SORT3").setFocus
session.findById("wnd[0]/usr/radP_SORT3").select
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/usr").verticalScrollbar.position = 1
session.findById("wnd[0]/usr").verticalScrollbar.position = 2
session.findById("wnd[0]/usr").verticalScrollbar.position = 3
session.findById("wnd[0]/mbar/menu[0]/menu[1]/menu[2]").select
session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[1,0]").select
session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[1,0]").setFocus
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ctxtDY_PATH").text = "D:\86A"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").text = "SP032.txt"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 9
session.findById("wnd[1]/tbar[0]/btn[11]").press
session.findById("wnd[0]/tbar[0]/btn[3]").press
session.findById("wnd[0]/tbar[0]/btn[3]").press
saplogin()
IndentationError: unexpected unindent
Note: As I mentioned in my comments I did a lot of modification but after last one still the weird error comes back as **IndentationError: unexpected unindent
Some simple code like method call or attribute initialization has the same syntax in VBScript and Python but the rest is not compatible.
For instance, you have to make these adaptations (taken from Stefan Schnell blog post):
Python (the equivalent VBScript code is commented out):
#session.findById("wnd[0]").resizeWorkingPane 173, 36, 0
session.findById("wnd[0]").resizeWorkingPane(173, 36, 0)
#session.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
session.findById("wnd[0]/tbar[0]/okcd").text = "/nse16"
#session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey(0)
#session.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
session.findById("wnd[0]/usr/ctxtDATABROWSE-TABLENAME").text = "TADIR"
#session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey(0)
#session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/tbar[1]/btn[8]").press()
Now it seems that the part of code which has not a valid Python syntax is not even needed because you already initialized the variables! These are the following lines to be removed from your script:
if not IsObject(application) Then ##here I get the invalid syntax error.
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End if
if not IsObject(connection) Then
Set connection = application.Children(0)
End if
if not IsObject(session) Then
Set session = connection.Children(0)
End if
if IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End if
Concerning the indentation issue, there are many questions and answers in StackOverflow.
Related
I am starting SAP GUI through subprocess. However, I need it to start in administrator mode. What do I need to change in the code?
path = r"C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
subprocess.Popen(path)
time.sleep(3)
SapGuiAuto = win32com.client.GetObject("SAPGUI")
if not type(SapGuiAuto) == win32com.client.CDispatch:
print('return')
application = SapGuiAuto.GetScriptingEngine
connection = application.OpenConnection("ECC QAS", True)
time.sleep(3)
session = connection.Children(0)
try:
session.findById("wnd[0]/usr/txtRSYST-MANDT").text = "300"
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = 'USER' #USUARIO
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = 'PASSWORD' #SENHA
session.findById("wnd[0]/usr/txtRSYST-LANGU").text = 'PT' #IDIOMA
session.findById("wnd[0]").sendVKey(0) #ENTER
except:
print(sys.exc_info()[0])
So my project is that I need to send a jpg image from one computer to another computer in the same network. To send the data I split the data into chunks of at least 9999 bytes and then I create a length header that tells the length of the data and I attach it to the start of the massage. here is the code:
the protocol:
import os.path
LENGTH_FIELD_SIZE = 4
PORT = 8820
COMANDS_LIST = "TAKE_SCREENSHOT\nSEND_PHOTO\nDIR\nDELETE\nCOPY\nEXECUTE\nEXIT".split("\n")
def check_cmd(data):
"""
Check if the command is defined in the protocol, including all parameters
For example, DELETE c:\work\file.txt is good, but DELETE alone is not
"""
command = ""
file_location =""
splited_data = data.split(maxsplit=1)
if len(splited_data) == 2:
command, file_location = splited_data
return (command in COMANDS_LIST) and (file_location is not None)
elif len(splited_data) == 1:
command = splited_data[0]
return command in ["TAKE_SCREENSHOT","EXIT","SEND_PHOTO"]
return False
# (3)
def create_msg(data):
"""
Create a valid protocol message, with length field
"""
data_len = len(str(data))
if data_len > 9999 or data_len == 0:
print(f"data len is bigger then 9999 or is 0, data len = {data_len} ")
return False
len_field = str(data_len).zfill(4)
# (4)
print(len_field)
return True ,f"{len_field}{data}"
def get_msg(my_socket):
"""
Extract message from protocol, without the length field
If length field does not include a number, returns False, "Error"
"""
lenght_field = ""
data = ""
try:
while len(lenght_field) < 4:
lenght_field += my_socket.recv(4).decode()
except RuntimeError as exc_run:
return False, "header wasnt sent properly"
if not lenght_field.isdigit():
return False, "error, length header is not valid"
lenght_field = lenght_field.lstrip("0")
while len(data) < int(lenght_field):
data += my_socket.recv(int(lenght_field)).decode()
return True, data
now the protocol works fine when I use the same computer for both server and client and when I debug get_msg on the other computer. when I'm not, it seems that the problem is that the part that recv the header will recv something else after a few successful recv and return an error message.
here are the server parts:
import socket
import pyautogui as pyautogui
import protocol
import glob
import os.path
import shutil
import subprocess
import base64
IP = "0.0.0.0"
PORT = 8820
PHOTO_PATH = r"C:\Users\Innon\Pictures\Screenshots\screenShot.jpg"# The path + filename where the screenshot at the server should be saved
def check_client_request(cmd):
"""
Break cmd to command and parameters
Check if the command and params are good.
For example, the filename to be copied actually exists
Returns:
valid: True/False
command: The requested cmd (ex. "DIR")
params: List of the cmd params (ex. ["c:\\cyber"])
"""
# Use protocol.check_cmd first
cmd_arr = cmd.split(maxsplit=1)
command = cmd_arr[0]
file_location = None
if len(cmd_arr) == 2:
file_location = cmd_arr[1]
if file_location == None:
return protocol.check_cmd(cmd) ,command, file_location
else:
file_location = tuple(str(file_location).split())
if (os.path.exists(file_location[0])):
return protocol.check_cmd(cmd) , command , file_location
return False , command , file_location
# Then make sure the params are valid
# (6)
def handle_client_request(command,params):
"""Create the response to the client, given the command is legal and params are OK
For example, return the list of filenames in a directory
Note: in case of SEND_PHOTO, only the length of the file will be sent
Returns:
response: the requested data
"""
# (7)
response = "no server response"
if command == "DIR":
response = glob.glob(f"{params[0]}\\*.*" )
if command == "DELETE":
os.remove(params[0])
response = f"{params[0]} was deleted"
if command == "COPY":
try:
shutil.copy(params[0],params[1])
response = f"{params[0]} was copyed to {params[1]}"
except FileNotFoundError as ex1:
response = ex1
except IndexError as ex2:
response = ex2
if command == "EXECUTE":
subprocess.call(params[0])
response = f"{params[0]} was executed"
if command == "TAKE_SCREENSHOT":
#todo find a way to know and create the locatipn of screen shot to be saved
myScreenshot = pyautogui.screenshot()
myScreenshot.save(PHOTO_PATH)
response = f"screen shot have been taken and been saved at {PHOTO_PATH}"
if command == "SEND_PHOTO":
with open(PHOTO_PATH, "rb") as file:
file_data = base64.b64encode(file.read()).decode()
print(file_data)
is_vaild_response, img_length = protocol.create_msg(len(file_data))
print(img_length)
img_data = ""
if not is_vaild_response:
response = "img length data isnt valid"
return response
while len(file_data) > 0:
chunk_data = file_data[:9999]
is_vaild_response, data = protocol.create_msg(chunk_data)
if not is_vaild_response:
response = "img data isnt valid"
return response
img_data += data
file_data = file_data[9999:]
response = f"{img_length}{img_data}"
return response
def main():
# open socket with client
server_socket = socket.socket()
server_socket.bind((IP,PORT))
server_socket.listen(1)
# (1)
client_socket, addr = server_socket.accept()
# handle requests until user asks to exit
while True:
# Check if protocol is OK, e.g. length field OK
valid_protocol, cmd = protocol.get_msg(client_socket)
print(f"got message {valid_protocol}")
if valid_protocol:
# Check if params are good, e.g. correct number of params, file name exists
valid_cmd, command, params = check_client_request(cmd)
print(f"check_client_request {valid_cmd}")
if valid_cmd:
# (6)
if command == 'EXIT':
break
if command == 'SEND_PHOTO':
data = handle_client_request(command, params)
client_socket.sendall(data.encode())
continue
# prepare a response using "handle_client_request"
data = handle_client_request(command,params)
# add length field using "create_msg"
is_vaild_response , response = protocol.create_msg(data)
print(f"creat_msg {is_vaild_response}")
# send to client
if is_vaild_response:
client_socket.sendall(response.encode())
else:
# prepare proper error to client
resp = 'Bad command or parameters'
is_vaild_response , response = protocol.create_msg(resp)
# send to client
client_socket.sendall(response.encode())
else:
# prepare proper error to client
resp = 'Packet not according to protocol'
is_vaild_response, response = protocol.create_msg(resp)
#send to client
client_socket.sendall(response.encode())
# Attempt to clean garbage from socket
client_socket.recv(1024)
# close sockets
resp = "Closing connection"
print(resp)
is_vaild_response, response = protocol.create_msg(resp)
client_socket.sendall(response.encode())
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()
and the client:
import socket
import base64
import protocol
IP = "127.0.0.1"
SAVED_PHOTO_LOCATION = r'C:\Users\Innon\Pictures\Saved Pictures\screenShot.jpg' # The path + filename where the copy of the screenshot at the client should be saved
def handle_server_response(my_socket, cmd):
"""
Receive the response from the server and handle it, according to the request
For example, DIR should result in printing the contents to the screen,
Note- special attention should be given to SEND_PHOTO as it requires and extra receive
"""
# (8) treat all responses except SEND_PHOTO
if "SEND_PHOTO" not in cmd:
vaild_data, data = protocol.get_msg(my_socket)
if vaild_data:
return data
# (10) treat SEND_PHOTO
else:
pic_data = ""
vaild_pick_len, pic_len = protocol.get_msg(my_socket)
if pic_len.isdigit() == False:
print(f"picture length is not valid. got massage: {pic_len}")
return
with open(SAVED_PHOTO_LOCATION, "wb") as file:
while len(pic_data) < int(pic_len):
vaild_data, data = protocol.get_msg(my_socket)
if not vaild_data:
return f"img data isnt valid. {data}"
pic_data += data
print(pic_data)
file.write(base64.b64decode(pic_data.encode()))
return "img was recived succesfully "
def main():
# open socket with the server
my_socket = socket.socket()
my_socket.connect((IP,8820))
# (2)
# print instructions
print('Welcome to remote computer application. Available commands are:\n')
print('TAKE_SCREENSHOT\nSEND_PHOTO\nDIR\nDELETE\nCOPY\nEXECUTE\nEXIT')
# loop until user requested to exit
while True:
cmd = input("Please enter command:\n")
if protocol.check_cmd(cmd):
valid_pack , packet = protocol.create_msg(cmd)
if valid_pack:
my_socket.sendall(packet.encode())
print(handle_server_response(my_socket, cmd))
if cmd == 'EXIT':
break
else:
print("Not a valid command, or missing parameters\n")
my_socket.close()
if __name__ == '__main__':
main()
here is how the problem looks like:thi is how it looks
here is how to needs look like:
the right way
thank you.
the solution was to change get_msg function in the protocol:
while len(data) < int(lenght_field):
data += my_socket.recv(int(lenght_field) - len(data)).decode()
instead of:
while len(data) < int(lenght_field):
data += my_socket.recv(int(lenght_field)).decode()
I am trying to run Bloomberg example code on my machine. I have created teamviewer VPN to machine where Bloomberg Terminal is installed. I have also disable firewall for both machine.
Bloomberg Terminal is up and logged in.
Code :
# import blpapi
# options = blpapi.SessionOptions()
# options.setServerHost('7.220.156.135')
# options.setServerPort(8194)
# session = blpapi.Session(options)
#
# session.start()
# ContributionsMktdataExample.py
import blpapi
import time
from optparse import OptionParser, OptionValueError
import datetime
import threading
TOKEN_SUCCESS = blpapi.Name("TokenGenerationSuccess")
TOKEN_FAILURE = blpapi.Name("TokenGenerationFailure")
AUTHORIZATION_SUCCESS = blpapi.Name("AuthorizationSuccess")
TOKEN = blpapi.Name("token")
MARKET_DATA = blpapi.Name("MarketData")
SESSION_TERMINATED = blpapi.Name("SessionTerminated")
g_running = True
g_mutex = threading.Lock()
class AuthorizationStatus:
WAITING = 1
AUTHORIZED = 2
FAILED = 3
__metaclass__ = blpapi.utils.MetaClassForClassesWithEnums
g_authorizationStatus = dict()
class MyStream(object):
def __init__(self, id=""):
self.id = id
class MyEventHandler(object):
def processEvent(self, event, session):
global g_running
for msg in event:
print msg
if event.eventType() == blpapi.Event.SESSION_STATUS:
if msg.messageType() == SESSION_TERMINATED:
g_running = False
continue
cids = msg.correlationIds()
with g_mutex:
for cid in cids:
if cid in g_authorizationStatus:
if msg.messageType() == AUTHORIZATION_SUCCESS:
g_authorizationStatus[cid] = \
AuthorizationStatus.AUTHORIZED
else:
g_authorizationStatus[cid] = \
AuthorizationStatus.FAILED
def authOptionCallback(option, opt, value, parser):
vals = value.split('=', 1)
if value == "user":
parser.values.auth = "AuthenticationType=OS_LOGON"
elif value == "none":
parser.values.auth = None
elif vals[0] == "app" and len(vals) == 2:
parser.values.auth = "AuthenticationMode=APPLICATION_ONLY;" \
"ApplicationAuthenticationType=APPNAME_AND_KEY;" \
"ApplicationName=" + vals[1]
elif vals[0] == "userapp" and len(vals) == 2:
parser.values.auth = "AuthenticationMode=USER_AND_APPLICATION;" \
"AuthenticationType=OS_LOGON;" \
"ApplicationAuthenticationType=APPNAME_AND_KEY;" \
"ApplicationName=" + vals[1]
elif vals[0] == "dir" and len(vals) == 2:
parser.values.auth = "AuthenticationType=DIRECTORY_SERVICE;" \
"DirSvcPropertyName=" + vals[1]
else:
raise OptionValueError("Invalid auth option '%s'" % value)
def parseCmdLine():
parser = OptionParser(description="Market data contribution.")
parser.add_option("-a",
"--ip",
dest="hosts",
help="server name or IP (default: localhost)",
metavar="ipAddress",
action="append",
default=[])
parser.add_option("-p",
dest="port",
type="int",
help="server port (default: %default)",
metavar="tcpPort",
default=8194)
parser.add_option("-s",
dest="service",
help="service name (default: %default)",
metavar="service",
default="//blp/mpfbapi")
parser.add_option("-t",
dest="topic",
help="topic (default: %default)",
metavar="topic",
default="/ticker/AUDEUR Curncy")
parser.add_option("--auth",
dest="auth",
help="authentication option: "
"user|none|app=<app>|userapp=<app>|dir=<property>"
" (default: %default)",
metavar="option",
action="callback",
callback=authOptionCallback,
type="string",
default="user")
(options, args) = parser.parse_args()
if not options.hosts:
options.hosts = ["localhost"]
return options
def authorize(authService, identity, session, cid):
with g_mutex:
g_authorizationStatus[cid] = AuthorizationStatus.WAITING
tokenEventQueue = blpapi.EventQueue()
# Generate token
session.generateToken(eventQueue=tokenEventQueue)
# Process related response
ev = tokenEventQueue.nextEvent()
token = None
if ev.eventType() == blpapi.Event.TOKEN_STATUS or \
ev.eventType() == blpapi.Event.REQUEST_STATUS:
for msg in ev:
print msg
if msg.messageType() == TOKEN_SUCCESS:
token = msg.getElementAsString(TOKEN)
elif msg.messageType() == TOKEN_FAILURE:
break
if not token:
print "Failed to get token"
return False
# Create and fill the authorithation request
authRequest = authService.createAuthorizationRequest()
authRequest.set(TOKEN, token)
# Send authorithation request to "fill" the Identity
session.sendAuthorizationRequest(authRequest, identity, cid)
# Process related responses
startTime = datetime.datetime.today()
WAIT_TIME_SECONDS = datetime.timedelta(seconds=10)
while True:
with g_mutex:
if AuthorizationStatus.WAITING != g_authorizationStatus[cid]:
return AuthorizationStatus.AUTHORIZED == \
g_authorizationStatus[cid]
endTime = datetime.datetime.today()
if endTime - startTime > WAIT_TIME_SECONDS:
return False
time.sleep(1)
def main():
options = parseCmdLine()
# Fill SessionOptions
sessionOptions = blpapi.SessionOptions()
for idx, host in enumerate(options.hosts):
sessionOptions.setServerAddress(host, options.port, idx)
sessionOptions.setAuthenticationOptions(options.auth)
sessionOptions.setAutoRestartOnDisconnection(True)
sessionOptions.setNumStartAttempts(len(options.hosts))
myEventHandler = MyEventHandler()
# Create a Session
session = blpapi.ProviderSession(sessionOptions,
myEventHandler.processEvent)
# Start a Session
if not session.start():
print "Failed to start session."
return
providerIdentity = session.createIdentity()
if options.auth:
isAuthorized = False
authServiceName = "//blp/apiauth"
if session.openService(authServiceName):
authService = session.getService(authServiceName)
isAuthorized = authorize(
authService, providerIdentity, session,
blpapi.CorrelationId("auth"))
if not isAuthorized:
print "No authorization"
return
topicList = blpapi.TopicList()
topicList.add(options.service + options.topic,
blpapi.CorrelationId(MyStream(options.topic)))
# Create topics
session.createTopics(topicList,
blpapi.ProviderSession.AUTO_REGISTER_SERVICES,
providerIdentity)
# createTopics() is synchronous, topicList will be updated
# with the results of topic creation (resolution will happen
# under the covers)
streams = []
for i in xrange(topicList.size()):
stream = topicList.correlationIdAt(i).value()
status = topicList.statusAt(i)
topicString = topicList.topicStringAt(i)
if (status == blpapi.TopicList.CREATED):
stream.topic = session.getTopic(topicList.messageAt(i))
streams.append(stream)
else:
print "Stream '%s': topic not resolved, status = %d" % (
stream.id, status)
service = session.getService(options.service)
try:
# Now we will start publishing
value = 1
while streams and g_running:
event = service.createPublishEvent()
eventFormatter = blpapi.EventFormatter(event)
for stream in streams:
value += 1
eventFormatter.appendMessage(MARKET_DATA, stream.topic)
eventFormatter.setElement("BID", 0.5 * value)
eventFormatter.setElement("ASK", value)
for msg in event:
print msg
session.publish(event)
time.sleep(10)
finally:
# Stop the session
session.stop()
if __name__ == "__main__":
print "ContributionsMktdataExample"
try:
main()
except KeyboardInterrupt:
print "Ctrl+C pressed. Stopping..."
__copyright__ = """
Copyright 2012. Bloomberg Finance L.P.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above
copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
Exception :
ContributionsMktdataExample
23MAY2016_15:50:15.552 6836:4756 ERROR blpapi_platformtransporttcp.cpp:671 blpapi.session.transporttcp.{1}.<7.220.156.135:8194> Connection failed
23MAY2016_15:50:15.552 6836:4756 WARN blpapi_platformcontroller.cpp:371 blpapi.session.platformcontroller.{1} Platform: 0 failed 1 consecutive connect attempts, stopped trying to reconnect.
23MAY2016_15:50:15.552 6836:5612 ERROR blpapi_providersessionimpl.cpp:642 blpapi.providersession.{1} Failed to start provider session: rc=9
Failed to start session.
cmd command :
python main.py --ip=7.220.156.135 --auth=none
It sounds like you're trying to use Desktop APIv3 to get data to your machine from a machine where the Terminal is running. This isn't supported. If you're using Desktop API you can only connect to localhost. The only cases where you can connect to another machine to get Bloomberg data is when using Sever API or B-PIPE.
Even if this were supported, The Desktop API contract states that you can't send Bloomberg data to a different computer.
my script is a server that listens to clients requests and send responses. It handles requests by threading:
class Server:
def __init__(self):
self.host = ''
self.port = 50000
self.backlog = 5
self.size = 1024
self.server = None
self.threads = []
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host,self.port))
self.server.listen(5)
except socket.error, (value,message):
if self.server:
self.server.close()
print "Could not open socket: " + message
sys.exit(1)
def run(self):
self.open_socket()
input = [self.server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == self.server:
# handle the server socket
c = Client(self.server.accept())
c.start()
self.threads.append(c)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
# close all threads
self.server.close()
for c in self.threads:
c.join()
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
def run(self):
running = 1
while running:
data = self.client.recv(self.size)
if data:
data2 = data.split()
if data2[0] == 'Hello':
status = 'Hello'
#fetch from database users by location
reply= '6'
if data2[0] == 'Index':
status = 'Index'
#fetch from database users by location
reply='I'
db = MySQLdb.connect(host="localhost", # your host, usually localhost
user="root", # your username
passwd="Rambo_9134", # your password
db="secure_login") # name of the data base
# you must create a Cursor object. It will let
# you execute all the queries you need
cur = db.cursor()
# Use all the SQL you like
cur.execute("SELECT ml.member,m.username FROM locations l JOIN memberlocation ml ON(l.id = ml.location) JOIN members m ON(m.id = ml.member) where l.id = 1;")
# print all the first cell of all the rows
data = []
for row in cur.fetchall() :
print row[1]
data.append({row[0]:row[1]})
print 'JSON', json.dumps(data)
reply = data
self.client.send(json.dumps(reply))
else:
self.client.close()
running = 0
if __name__ == "__main__":
s = Server()
s.run()
this script runs perfectly but it stops when i press enter. I have tried many alternatives: deamon, nohup, ... i couldn't make it run as a service in the background. i think this is a programming issue
how can i make this script run in the background as a service ?
For a quick and easy way in a test/dev environment you can use screen.
screen -S mySessionName
This starts a new screen session with the name mySessionName and attaches to that session. Inside this session you can now run your code.
Use Ctrl+A, D to detach from that session. Your code will continue to run.
To reattach to that session use:
screen -r mySessionName
To show all sessions use:
screen -ls
In a production environment however you should be looking at supervisor. This serverfault question might help.
Make a PHP or HTML script devoted solely to running that python program. Then, run that PHP/HTML script on the server and you're good :).
I have created my own CGI python server script (that serves on port 8000) by following a tutorial. The server works beautifully if I want to generate web pages from python scripts, or serve a native HTML page BUT it doesn't work for when I make an AJAX POST request?
If I make an AJAX request to the python file aaa.py (using the javascript below) my server prints out the following error text:
Code 501, message can only POST to to CGI scripts
"POST /aaa.py HTTP/1.1" 501 -
What do you think I need to do to allow my python cgi server to allow/handle AJAX requests?
My CGI server:
__version__ = "0.4"
__all__ = ["CGIHTTPRequestHandler"]
import os
import sys
import urllib
import BaseHTTPServer
import SimpleHTTPServer
import select
class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""Complete HTTP server with GET, HEAD and POST commands.
GET and HEAD also support running CGI scripts.
The POST command is *only* implemented for CGI scripts.
"""
# Determine platform specifics
have_fork = hasattr(os, 'fork')
have_popen2 = hasattr(os, 'popen2')
have_popen3 = hasattr(os, 'popen3')
# pretend we don't have these to force execution in process
have_fork = 0
# Make rfile unbuffered -- we need to read one line and then pass
# the rest to a subprocess, so we can't use buffered input.
rbufsize = 0
def do_POST(self):
"""Serve a POST request.
This is only implemented for CGI scripts.
"""
if self.is_cgi():
self.run_cgi()
else:
self.send_error(501, "Can only POST to CGI scripts")
def send_head(self):
"""Version of send_head that support CGI scripts"""
if self.is_cgi():
return self.run_cgi()
else:
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
def is_cgi(self):
"""Test whether self.path corresponds to a CGI script.
Return a tuple (dir, rest) if self.path requires running a
CGI script, None if not. Note that rest begins with a
slash if it is not empty.
The default implementation tests whether the path
begins with one of the strings in the list
self.cgi_directories (and the next character is a '/'
or the end of the string).
"""
path = self.path
for x in self.cgi_directories:
i = len(x)
if path[:i] == x and (not path[i:] or path[i] == '/'):
self.cgi_info = path[:i], path[i+1:]
return True
return False
cgi_directories = ['/cgi-bin', '/htbin']
def is_executable(self, path):
"""Test whether argument path is an executable file."""
return executable(path)
def is_python(self, path):
"""Test whether argument path is a Python script."""
head, tail = os.path.splitext(path)
return tail.lower() in (".py", ".pyw")
def run_cgi(self):
"""Execute a CGI script."""
dir, rest = self.cgi_info
i = rest.rfind('?')
if i >= 0:
rest, query = rest[:i], rest[i+1:]
else:
query = ''
# i = rest.find('/')
# if i >= 0:
# script, rest = rest[:i], rest[i:]
# else:
# script, rest = rest, ''
script = rest
scriptname = dir + '/' + script
scriptfile = self.translate_path(scriptname)
if not os.path.exists(scriptfile):
self.send_error(404, "No such CGI script (%s)" % `scriptname`)
return
if not os.path.isfile(scriptfile):
self.send_error(403, "CGI script is not a plain file (%s)" %
`scriptname`)
return
ispy = self.is_python(scriptname)
if not ispy:
if not (self.have_fork or self.have_popen2 or self.have_popen3):
self.send_error(403, "CGI script is not a Python script (%s)" %
`scriptname`)
return
if not self.is_executable(scriptfile):
self.send_error(403, "CGI script is not executable (%s)" %
`scriptname`)
return
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
# XXX Much of the following could be prepared ahead of time!
env = {}
env['SERVER_SOFTWARE'] = self.version_string()
env['SERVER_NAME'] = self.server.server_name
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
env['SERVER_PROTOCOL'] = self.protocol_version
env['SERVER_PORT'] = str(self.server.server_port)
env['REQUEST_METHOD'] = self.command
uqrest = urllib.unquote(rest)
env['PATH_INFO'] = uqrest
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
env['SCRIPT_NAME'] = scriptname
if query:
env['QUERY_STRING'] = query
host = self.address_string()
if host != self.client_address[0]:
env['REMOTE_HOST'] = host
env['REMOTE_ADDR'] = self.client_address[0]
# XXX AUTH_TYPE
# XXX REMOTE_USER
# XXX REMOTE_IDENT
if self.headers.typeheader is None:
env['CONTENT_TYPE'] = self.headers.type
else:
env['CONTENT_TYPE'] = self.headers.typeheader
length = self.headers.getheader('content-length')
if length:
env['CONTENT_LENGTH'] = length
accept = []
for line in self.headers.getallmatchingheaders('accept'):
if line[:1] in "\t\n\r ":
accept.append(line.strip())
else:
accept = accept + line[7:].split(',')
env['HTTP_ACCEPT'] = ','.join(accept)
ua = self.headers.getheader('user-agent')
if ua:
env['HTTP_USER_AGENT'] = ua
co = filter(None, self.headers.getheaders('cookie'))
if co:
env['HTTP_COOKIE'] = ', '.join(co)
# XXX Other HTTP_* headers
if not self.have_fork:
# Since we're setting the env in the parent, provide empty
# values to override previously set values
for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
'HTTP_USER_AGENT'):
###, 'HTTP_COOKIE' -- removed by S.
env.setdefault(k, "")
# for key in env.keys():
# print key + " '" + env[key] + "'"
os.environ.update(env)
self.send_response(200, "Script output follows")
decoded_query = query.replace('+', ' ')
if self.have_fork:
# Unix -- fork as we should
args = [script]
if '=' not in decoded_query:
args.append(decoded_query)
nobody = nobody_uid()
self.wfile.flush() # Always flush before forking
pid = os.fork()
if pid != 0:
# Parent
pid, sts = os.waitpid(pid, 0)
# throw away additional data [see bug #427345]
while select.select([self.rfile], [], [], 0)[0]:
if not self.rfile.read(1):
break
if sts:
self.log_error("CGI script exit status %#x", sts)
return
# Child
try:
try:
os.setuid(nobody)
except os.error:
pass
os.dup2(self.rfile.fileno(), 0)
os.dup2(self.wfile.fileno(), 1)
os.execve(scriptfile, args, os.environ)
except:
self.server.handle_error(self.request, self.client_address)
os._exit(127)
elif self.have_popen2 or self.have_popen3:
# Windows -- use popen2 or popen3 to create a subprocess
import shutil
if self.have_popen3:
popenx = os.popen3
else:
popenx = os.popen2
cmdline = scriptfile
if self.is_python(scriptfile):
interp = sys.executable
if interp.lower().endswith("w.exe"):
# On Windows, use python.exe, not pythonw.exe
interp = interp[:-5] + interp[-4:]
cmdline = "%s -u \"%s\"" % (interp, cmdline)
if '=' not in query and '"' not in query:
cmdline = '%s "%s"' % (cmdline, query)
self.log_message("command: %s", cmdline)
try:
nbytes = int(length)
except (TypeError, ValueError):
nbytes = 0
files = popenx(cmdline, 'b')
fi = files[0]
fo = files[1]
if self.have_popen3:
fe = files[2]
if self.command.lower() == "post" and nbytes > 0:
data = self.rfile.read(nbytes)
fi.write(data)
# throw away additional data [see bug #427345]
while select.select([self.rfile._sock], [], [], 0)[0]:
if not self.rfile._sock.recv(1):
break
fi.close()
shutil.copyfileobj(fo, self.wfile)
if self.have_popen3:
errors = fe.read()
fe.close()
if errors:
self.log_error('%s', errors)
sts = fo.close()
if sts:
self.log_error("CGI script exit status %#x", sts)
else:
self.log_message("CGI script exited OK")
else:
# Other O.S. -- execute script in this process
save_argv = sys.argv
save_stdin = sys.stdin
save_stdout = sys.stdout
save_stderr = sys.stderr
try:
try:
sys.argv = [scriptfile]
if '=' not in decoded_query:
sys.argv.append(decoded_query)
sys.stdout = self.wfile
sys.stdin = self.rfile
execfile(scriptfile, {"__name__": "__main__"})
finally:
sys.argv = save_argv
sys.stdin = save_stdin
sys.stdout = save_stdout
sys.stderr = save_stderr
except SystemExit, sts:
self.log_error("CGI script exit status %s", str(sts))
else:
self.log_message("CGI script exited OK")
nobody = None
def nobody_uid():
"""Internal routine to get nobody's uid"""
global nobody
if nobody:
return nobody
try:
import pwd
except ImportError:
return -1
try:
nobody = pwd.getpwnam('nobody')[2]
except KeyError:
nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
return nobody
def executable(path):
"""Test for executable file."""
try:
st = os.stat(path)
except os.error:
return False
return st.st_mode & 0111 != 0
def test(HandlerClass = CGIHTTPRequestHandler,
ServerClass = BaseHTTPServer.HTTPServer):
SimpleHTTPServer.test(HandlerClass, ServerClass)
if __name__ == '__main__':
test()
Code in aaa.py:
#!/usr/bin/env python
import cgitb; cgitb.enable()
import cgi
import os
print "Content-Type: text/html\n"
input_data = cgi.FieldStorage()
print "hello"
My AJAX/ Javascript:
function onTest( dest, params )
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById( "bb" ).innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("POST",dest,true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send( params );
}
when you use the python http cgi server, cgi scripts have to be under the subdir (from you server script ) /cgi-bin