Python suds Exchange Web Service getting empty service attribute - python

I finally got my EWS client to not give me 401 errors but I don't know if that actually means anything. Now when I instantiate the suds Client object, it's got an empty service attribute.
from suds.transport.https import *
from suds.client import Client
from os import environ
import sys
def first(car=None, *cdr):
return car
def cleaned(lines):
return map(str.strip, lines)
def getauth(f=open("%s/.ews/auth"%(environ.get("HOME")), "rt")):
return first(cleaned(f.readlines()), f.close())
def serviceURI():
return "https://%s/ews/Services.wsdl"%(environ.get("WEBMAIL"))
def auth():
def nclnt(tx):
return Client(serviceURI(), transport=tx)
def ntauth(username, password):
'''Authenticate with NTLM and return the Client object.'''
return nclnt(WindowsHttpAuthenticated(username=username,
password=password))
def webauth(username, password):
'''Use standard web authentication.'''
return nclnt(HttpAuthenticated(username=username,
password=password))
def authWith(method):
return method(*getauth())
return authWith(ntauth if "ntlm" in sys.argv else webauth)
def main():
def _go(client):
print client
print client.last_received
print dir(client.service)
return 0
return _go(auth())
if __name__=="__main__":
main()
And when I run this:
[ishpeck#slcyoshimitsu random_scripts]$ python ews.py ntlm
Suds ( https://fedorahosted.org/suds/ ) version: 0.4 GA build: R699-20100913
<bound method Client.last_received of <suds.client.Client object at 0x17ea6d0>>
Traceback (most recent call last):
File "ews.py", line 42, in <module>
main()
File "ews.py", line 39, in main
return _go(auth())
File "ews.py", line 37, in _go
print dir(client.service)
File "/usr/lib/python2.7/site-packages/suds/client.py", line 296, in __getattr__
port = self.__find(0)
File "/usr/lib/python2.7/site-packages/suds/client.py", line 331, in __find
raise Exception, 'No services defined'
Exception: No services defined
[ishpeck#slcyoshimitsu random_scripts]$ python ews.py
Suds ( https://fedorahosted.org/suds/ ) version: 0.4 GA build: R699-20100913
<bound method Client.last_received of <suds.client.Client object at 0x136c6d0>>
Traceback (most recent call last):
File "ews.py", line 42, in <module>
main()
File "ews.py", line 39, in main
return _go(auth())
File "ews.py", line 37, in _go
print dir(client.service)
File "/usr/lib/python2.7/site-packages/suds/client.py", line 296, in __getattr__
port = self.__find(0)
File "/usr/lib/python2.7/site-packages/suds/client.py", line 331, in __find
raise Exception, 'No services defined'
Exception: No services defined
I'm noticing a lot of people complaining about having problems with this very thing but haven't found anybody who claims to have gotten it working.

your "print client" line didn't return anything, so I suspect it had a problem with the wsdl.
Turn on some debugging to see what's going on..
import logging
logging.basicConfig(level=logging.DEBUG, filename="suds.log")
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG)
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)

Related

Flask app_context() used in threaded class but query doesn't work

I want to create a threaded class where I can do a polymorphic query to my DB to get the current subscriptions to an alarm notification. However the tests don't work when using pytest (but they work when using built in testing from VS Code) and in the dev environment there are some errors as well.
I have gone through quite a few answers on SO but most of the time people were not putting their app in the arguments of the threaded class. In some answers ._get_current_object() is appended to the app but this results in another error (see below).
I've been at this for a few days so if you have any suggestions, please let me know...
Threaded class:
class SubscriptionMapper(Thread):
instance = None
def __init__(self, app):
super().__init__()
self._app = app
try:
self.alarms = self._read_config()
...
def _read_config(self):
with self._app.app_context():
subscriptions = with_polymorphic(Subscription, "*").query.all()
print(subscriptions)
...
#staticmethod
def get_instance(app):
if SubscriptionMapper.instance is None:
SubscriptionMapper.instance = SubscriptionMapper(app)
return SubscriptionMapper.instance
#staticmethod
def get_alarm_description(app, alarm_uuid):
m = SubscriptionMapper.get_instance(app)
alarm_uuid = str(alarm_uuid)
return m.alarms.get(alarm_uuid, None)
Error in dev environment:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/flask/app/notification/subscriptions.py", line 103, in run
self._read_config()
File "/flask/app/notification/subscriptions.py", line 119, in _read_config
with self._app.app_context():
File "/flask/venv/lib/python3.9/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/flask/venv/lib/python3.9/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/flask/venv/lib/python3.9/site-packages/flask/globals.py", line 52, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
One of the tests which isn't working properly:
#pytest.fixture(scope='function')
def setup_subscription(db):
am = Alarm(
)
sub = Subscription(
alarm=am
)
db.session.add_all((am, sub))
db.session.commit()
yield am
def test_get_alarm_description(self, app, setup_subscription):
am = setup_subscription
assert SubscriptionMapper.get_alarm_description(
app, f'{am.uuid}') == 'Testproject - MON-1 - Verplaatsing in x (± 20.0 mm)'
Conftest.py
#pytest.fixture(scope='function')
def app() -> Flask:
app = create_app(config_name='unittest')
with app.app_context():
yield app
#pytest.fixture(scope='function')
def db(app: pytest.fixture) -> database:
flask_migrate.upgrade()
yield database
database.session.remove()
database.drop_all()
database.engine.execute(
'DROP TABLE IF EXISTS alembic_version;'
)
When executing the test by running pytest tests/test_notification_subscriptions.py the test fails with the following error
self = <tests.test_notification_subscriptions.TestSubscriptionMapper object at 0x0000024819B83FA0>, app = <Flask 'app'>, setup_subscription = <Alarm 6dcc5b00-9037-4c98-beae-91319423c7d6>
def test_get_alarm_description(self, app, setup_subscription):
am = setup_subscription
> assert SubscriptionMapper.get_alarm_description(
app, f'{am.uuid}') == 'Testproject - MON-1 - Verplaatsing in x (± 20.0 mm)'
E AssertionError: assert None == 'Testproject - MON-1 - Verplaatsing in x (± 20.0 mm)'
However when running the test from the built in testing tool in VS Code the test succeeds but prints an error in the Python Test Log output screen after succeeding.
======================= 1 passed, 35 warnings in 13.14s =======================
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\Jan-P\miniconda3\envs\MeMo_AlarmService\lib\site-packages\sqlalchemy\engine\base.py", line 1276, in _execute_context
self.dialect.do_execute(
File "C:\Users\Jan-P\miniconda3\envs\MeMo_AlarmService\lib\site-packages\sqlalchemy\engine\default.py", line 608, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: tbl_subscription
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Jan-P\miniconda3\envs\MeMo_AlarmService\lib\threading.py", line 954, in _bootstrap_inner
self.run()
File "c:\Users\Jan-P\Repos\MEMO\alarmservice\app\notification\subscriptions.py", line 106, in run
self._read_config()
File "c:\Users\Jan-P\Repos\MEMO\alarmservice\app\notification\subscriptions.py", line 123, in _read_config
subscriptions = with_polymorphic(Subscription, "*").query.all()
...
When adding ._get_current_object() to the get_instance function both types of tests result in the following error AttributeError: 'Flask' object has no attribute '_get_current_object'
#staticmethod
def get_instance(app):
if SubscriptionMapper.instance is None:
SubscriptionMapper.instance = SubscriptionMapper(app._get_current_object())
return SubscriptionMapper.instance

TypeError during the call python grpc method without arguments using google/protobuf/empty.proto

I have a proto scheme like this:
import "google/protobuf/empty.proto";
...
service NodeInfoService {
rpc NodeConfig (google.protobuf.Empty) returns (NodeConfigResponse);
}
Using grpc_tools I got classes and now, when I'm trying to send request from py client, but catching the error in "stub.NodeConfig()" call.
Even If I call it like "stub.NodeConfig({})" or "stub.NodeConfig("")" I have the same TypeError. Full code of client:
import grpc
import logging
from util import node_info_service_pb2_grpc
from util import node_info_service_pb2
def run():
with grpc.insecure_channel('ip:port') as channel:
stub = node_info_service_pb2_grpc.NodeInfoServiceStub(channel)
response = stub.NodeConfig(node_info_service_pb2.google_dot_protobuf_dot_empty__pb2.Empty)
print("Echo client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
Error:
ERROR:grpc._common:Exception serializing message!
Traceback (most recent call last):
File "/Users/user/p/p/venv/lib/python3.8/site-packages/grpc/_common.py", line 86, in _transform
return transformer(message)
TypeError: descriptor 'SerializeToString' for 'google.protobuf.pyext._message.CMessage' objects doesn't apply to a 'GeneratedProtocolMessageType' object
Traceback (most recent call last):
File "/Users/user/p/scripts/grpc/protobuf/client.py", line 15, in <module>
run()
File "/Users/user/p/scripts/grpc/protobuf/client.py", line 9, in run
response = stub.NodeConfig(node_info_service_pb2.google_dot_protobuf_dot_empty__pb2.Empty)
File "/Users/user/p/p/venv/lib/python3.8/site-packages/grpc/_channel.py", line 921, in __call__
state, call, = self._blocking(request, timeout, metadata, credentials,
File "/Users/user/p/p/venv/lib/python3.8/site-packages/grpc/_channel.py", line 901, in _blocking
raise rendezvous # pylint: disable-msg=raising-bad-type
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.INTERNAL
details = "Exception serializing request!"
debug_error_string = "None"
Solution:
empty = node_info_service_pb2.google_dot_protobuf_dot_empty__pb2.Empty()
response = stub.NodeConfig(empty)

Error when trying to use zeep to connect to Netsuite

I'm writing a Python application that is to connect to Netsuite (WSDL) and then INSERT data into the table. I'm trying to use zeep to connect to our Netsuite server and I get this error:
python3.6 /xxx/python-netsuite/netsuite/client.py
Traceback (most recent call last):
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 565, in _get_component
return items[qname]
KeyError: <lxml.etree.QName object at 0x10e9bd850>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/xxx/python-netsuite/netsuite/client.py", line 2, in <module>
from netsuite.service import (client,
File "/xxx/python-netsuite/netsuite/service.py", line 13, in <module>
Passport = model('ns1:Passport')
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/client.py", line 263, in get_type
return self.wsdl.types.get_type(name)
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 140, in get_type
return self._get_instance(qname, 'get_type', 'type')
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 243, in _get_instance
raise last_exception
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 239, in _get_instance
return method(qname)
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 523, in get_type
return self._get_component(qname, self._types, 'type')
File "/xxx/.virtualenvs/for-netsuite/lib/python3.6/site-packages/zeep/xsd/schema.py", line 580, in _get_component
location=self._location)
zeep.exceptions.LookupError: No type 'Passport' in namespace
urn:types.core_2017_1.platform.webservices.netsuite.com. Available types are:
{urn:types.core_2017_1.platform.webservices.netsuite.com}RecordType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchRecordType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}GetAllRecordType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}GetCustomizationType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}InitializeType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}InitializeRefType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}InitializeAuxRefType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}DeletedRecordType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}AsyncStatusType,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchStringFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchLongFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchTextNumberFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchDoubleFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchDateFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchEnumMultiSelectFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchMultiSelectFieldOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SearchDate,
{urn:types.core_2017_1.platform.webservices.netsuite.com}DurationUnit,
{urn:types.core_2017_1.platform.webservices.netsuite.com}CalendarEventAttendeeResponse,
{urn:types.core_2017_1.platform.webservices.netsuite.com}GetSelectValueFilterOperator,
{urn:types.core_2017_1.platform.webservices.netsuite.com}SignatureAlgorithm
Process finished with exit code 1
This is my client.py
import ns_config
from netsuite.service import (client,
RecordRef,
ApplicationInfo,
Passport)
def make_passport():
role = RecordRef(internalId=ns_config.NS_ROLE)
return Passport(email=ns_config.NS_EMAIL,
password=ns_config.NS_PASSWORD,
account=ns_config.NS_ACCOUNT,
role=role)
def login():
app_info = ApplicationInfo(applicationId=ns_config.NS_APPID)
passport = make_passport()
login = client.service.login(passport=passport, _soapheaders={'applicationInfo': app_info})
print('Login Response: ', login.status)
return client, app_info
passport = make_passport()
client, app_info = login()
The WSDL_URL is this: https://webservices.sandbox.netsuite.com/wsdl/v2017_1_0/netsuite.wsdl. Which is the version of Netsuite that we have.
Can anyone tell me what I'm doing wrong?
I believe the correct namespace for Passport is:
urn:core_2017_1.platform.webservices.netsuite.com
not the one in your error message:
urn:types.core_2017_1.platform.webservices.netsuite.com
I'm new to zeep and netsuite, but I have noticed that so far, wherever the type of a parameter or header is known, I can just pass a plain dict with string keys and string or nested dict values, and zeep will turn it into the correct typed xml, without me having to give namespaces or instantiate and link up xsd objects. Might help simplify your code.

Bottle GET request is broken with certain strings when running with paste server

I have a problem similar to this one:
Python bottle: UTF8 path string invalid when using app.mount()
When I try to GET /languages/Inglês I receive the error below (notice the accent "ê"). When passing [az] strings it works fine.
Critical error while processing request: /languages/Inglês
I tried the fix mentioned on the link above without success.
Working example:
from bottle import route, run, debug
#route('/languages/<name>')
def hello(name):
return name
if __name__ == '__main__':
debug(False)
#run(reloader=False, port = 8080) # works
run(server='paste', port = 8080) # fails
Running with server='paste' causes the crash, but using the Bottle server it runs OK. The problem seems to happen at the bottle._handle() method, where a UnicodeError is thrown (bottle.py line 844):
def _handle(self, environ):
path = environ['bottle.raw_path'] = environ['PATH_INFO']
if py3k:
try:
environ['PATH_INFO'] = path.encode('latin1').decode('utf8')
except UnicodeError:
return HTTPError(400, 'Invalid path string. Expected UTF-8')
I'm using Python 3.6.2, Bottle v0.12.13 and Paste 2.0.3 on a Windows 10 machine. What's going on? Is that a problem with Bottle or Paste?
Note: I've already solved my problem by refactoring all the code to use integer IDs instead of names. But I still would like to learn more about this.
Stack trace:
Critical error while processing request: /hello/inglês
Error:
RuntimeError('Request context not initialized.',)
Traceback:
Traceback (most recent call last):
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 1661, in fget
try: return ls.var
AttributeError: '_thread._local' object has no attribute 'var'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 954, in wsgi
out = self._cast(self._handle(environ))
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 907, in _cast
out = self.error_handler.get(out.status_code, self.default_error_handler)(out)
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 842, in default_error_handler
return tob(template(ERROR_PAGE_TEMPLATE, e=res))
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 3619, in template
return TEMPLATES[tplid].render(kwargs)
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 3409, in render
self.execute(stdout, env)
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 3396, in execute
eval(self.co, env)
File "<string>", line 17, in <module>
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 1249, in url
return self.urlparts.geturl()
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 165, in __get__
key, storage = self.key, getattr(obj, self.attr)
File "C:\Users\fernando.filho\AppData\Local\Programs\Python\Python36\lib\site-packages\bottle.py", line 1663, in fget
raise RuntimeError("Request context not initialized.")
RuntimeError: Request context not initialized.
Answering my own question, quoting #GrahamDumpleton:
The Paste server is not tolerant of being sent non ASCII characters.
this is the bottle's problem!
In order to use paste server u can change this:
"""bottle.py"""
environ['PATH_INFO'] = path.encode('latin1').decode('utf8', 'ignore')
to:
environ['PATH_INFO'] = path.encode('utf8').decode('utf8', 'ignore') #utf-8 or else
it's work well.

Twisted XML-RPC error

I get an exception on both client and server side when I run the first example at http://buildbot.twistedmatrix.com/builds/sphinx-html/291-15849/projects/web/howto/xmlrpc.html. The server code I used is below:
from twisted.web import xmlrpc, server
class Example(xmlrpc.XMLRPC):
"""An example object to be published."""
def xmlrpc_echo(self, x):
"""
Return all passed args.
"""
return x
def xmlrpc_add(self, a, b):
"""
Return sum of arguments.
"""
return a + b
def xmlrpc_fault(self):
"""
Raise a Fault indicating that the procedure should not be used.
"""
raise xmlrpc.Fault(123, "The fault procedure is faulty.")
if __name__ == '__main__':
from twisted.internet import reactor
r = Example()
reactor.listenTCP(7080, server.Site(r))
reactor.run()
Client side is below:
import xmlrpclib
s = xmlrpclib.Server('http://localhost:7080/')
print s.echo('Hello world')
The server side exception is:
Traceback (most recent call last):
File "/usr/lib/python2.6/dist-packages/twisted/web/xmlrpc.py", line 150, in render_POST
d.addCallback(self._cbRender, request, responseFailed)
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 260, in addCallback
callbackKeywords=kw)
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 249, in addCallbacks
self._runCallbacks()
File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 441, in _runCallbacks
self.result = callback(self.result, *args, **kw)
--- <exception caught here> ---
File "/usr/lib/python2.6/dist-packages/twisted/web/xmlrpc.py", line 170, in _cbRender
allow_none=self.allowNone)
exceptions.TypeError: dumps() got an unexpected keyword argument 'allow_none'
Client side exception is:
Traceback (most recent call last):
File "./client.py", line 6, in <module>
print s.echo('Hello world')
File "/usr/local/lib/python2.6/dist-packages/xmlrpclib-1.0.1-py2.6.egg/xmlrpclib.py", line 986, in __call__
return self.__send(self.__name, args)
File "/usr/local/lib/python2.6/dist-packages/xmlrpclib-1.0.1-py2.6.egg/xmlrpclib.py", line 1239, in __request
verbose=self.__verbose
File "/usr/local/lib/python2.6/dist-packages/xmlrpclib-1.0.1-py2.6.egg/xmlrpclib.py", line 1037, in request
return self._parse_response(h.getfile(), sock)
File "/usr/local/lib/python2.6/dist-packages/xmlrpclib-1.0.1-py2.6.egg/xmlrpclib.py", line 1136, in _parse_response
p.close()
File "/usr/local/lib/python2.6/dist-packages/xmlrpclib-1.0.1-py2.6.egg/xmlrpclib.py", line 508, in close
self._parser.Parse("", 1) # end of data
xml.parsers.expat.ExpatError: no element found: line 1, column 0
Looks like you have an old version of xmlrpclib?
What version of python are you using?
Where is the xmlrpclib coming from that your xmlrpc server is using, and what version is it?
$ python -v
>>> import xmlrpclib
# /usr/lib/python2.6/xmlrpclib.pyc matches /usr/lib/python2.6/xmlrpclib.py
>>> xmlrpclib.__version__
'1.0.1'
>>> xmlrpclib.dumps((None,), allow_none=True)
'<params>\n<param>\n<value><nil/></value></param>\n</params>\n
i.e. this works for me. Perhaps you are somehow using an old version of xmlrpclib?

Categories