简体   繁体   中英

Why kivy app on android generates Swiftclient exception (require python-keystoneclient) but works on desktop (Windows)?

I have been googling but I can't seem to find anything that can help me solve this problem on my own.

I am creating an app which is meant for android, I want to be able to push data to Openstack ObjectStore using SwiftClient API. The current implementation works for the desktop version, but for android it crashes when it tries to use the "put_object()" function. In my buildozer.spec file I have tried to include the package but it makes no difference. I have of course also made sure to completely rebuild with buildozer by removing the generated folder '.buildozer' to make sure my changes are included. I tried to search on the internet if maybe the problem is using python-keystoneclient on Android, maybe it isn't supported. I did find a thread mentioning that keystoneclient might run in to random issues as an effect of other packages interfering, these are the current packages used in the application.

In buildozer.spec:

requirements = python3,kivy==2.0.0,paho-mqtt,subprocess32,python-swiftclient,requests,urllib3,chardet,idna,python-keystoneclient

Code where I get the error:

import logging
import constant
from swiftclient import client
from swiftclient.service import SwiftError


class SwiftClientManager:
    def __init__(self):
        self.client = client.Connection(
            authurl=constant.OS_AUTH_URL,
            user=constant.OS_USER,
            key=constant.OS_PASSWORD,
            auth_version=constant.OS_AUTH_VERSION,
            os_options={
                "project_id": constant.OS_PROJECT_ID,
                "user_id": constant.OS_USER_ID
                }
        )
        logging.basicConfig(level=logging.ERROR)
        logging.getLogger("requests").setLevel(logging.CRITICAL)
        logging.getLogger("swiftclient").setLevel(logging.CRITICAL)
        self.logger = logging.getLogger(__name__)
        self._opts = {'object_uu_threads': 20}

    def push_api(self, file_name, file_hierarchy, file_path):
        print(file_hierarchy)
        with open(file_path, "rb") as file:
            try:
                self.client.put_object(         # <--- here is where I get my error when it
                                                # tries to authenticate me for the server access
                    constant.OS_CONTAINER_NAME,
                    file_hierarchy + file_name + constant.LOG_FILE_TYPE,
                    contents=file.read(),
                    content_type=constant.LOG_FILE_TYPE + '/type'
                )
                pass
            except SwiftError:
                print('Could not upload file %s', file_name)
        file.close()

This is part of the stack trace I get from adb logcat | grep pythonadb logcat | grep python

03-30 10:57:17.237 17222 17282 I python  : Error: None Res: b''
03-30 10:57:17.274 17222 17282 I python  : Client initialized..
03-30 10:57:17.274 17222 17282 I python  : Client created..
03-30 10:57:17.279 17222 17282 I python  : [WARNING] [Base        ] Unknown <android> provider
03-30 10:57:17.279 17222 17282 I python  : [INFO   ] [Base        ] Start application main loop
03-30 10:57:20.823 17222 17282 I python  : [INFO   ] [Base        ] Leaving application in progress...
03-30 10:57:20.824 17222 17282 I python  :  Traceback (most recent call last):
03-30 10:57:20.824 17222 17282 I python  :    File "/path/to/app/main.py", line 125, in <module>
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/app.py", line 950, in run
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/base.py", line 582, in runTouchApp
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/base.py", line 347, in mainloop
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/base.py", line 391, in idle
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/base.py", line 342, in dispatch_input
03-30 10:57:20.826 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/base.py", line 308, in post_dispatch_input
03-30 10:57:20.827 17222 17282 I python  :    File "kivy/_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
03-30 10:57:20.827 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/uix/behaviors/button.py", line 179, in on_touch_up
03-30 10:57:20.827 17222 17282 I python  :    File "kivy/_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
03-30 10:57:20.827 17222 17282 I python  :    File "kivy/_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
03-30 10:57:20.827 17222 17282 I python  :    File "kivy/_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
03-30 10:57:20.827 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/kivy/lang/builder.py", line 57, in custom_callback
03-30 10:57:20.828 17222 17282 I python  :    File "/data/user/0/org.logger.logger/files/app/radiofingerprintlogger.kv", line 85, in <module>
03-30 10:57:20.833 17222 17282 I python  :      on_release: root.save_to_database()
03-30 10:57:20.833 17222 17282 I python  :    File "/path/to/app/.buildozer/android/app/main.py", line 80, in save_to_database
03-30 10:57:20.833 17222 17282 I python  :    File "/path/to/app/.buildozer/android/app/controller.py", line 114, in push_data
03-30 10:57:20.833 17222 17282 I python  :    File "/path/to/app/.buildozer/android/app/swift_client_manager.py", line 29, in push_api
03-30 10:57:20.833 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/swiftclient/client.py", line 2015, in put_object
03-30 10:57:20.834 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/swiftclient/client.py", line 1845, in _retry
03-30 10:57:20.834 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/swiftclient/client.py", line 1789, in get_auth
03-30 10:57:20.834 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/swiftclient/client.py", line 772, in get_auth
03-30 10:57:20.834 17222 17282 I python  :    File "/path/to/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/logger/swiftclient/client.py", line 615, in get_auth_keystone
03-30 10:57:20.834 17222 17282 I python  :  swiftclient.exceptions.ClientException: 
03-30 10:57:20.834 17222 17282 I python  :  Auth versions 2.0 and 3 require python-keystoneclient, install it or use Auth
03-30 10:57:20.834 17222 17282 I python  :  version 1.0 which requires ST_AUTH, ST_USER, and ST_KEY environment
03-30 10:57:20.834 17222 17282 I python  :  variables to be set or overridden with -A, -U, or -K.
03-30 10:57:20.834 17222 17282 I python  : Python for android ended.

So I thought I'd go back and update this question with how I worked around this issue. I simply decided to use keystoneauth1 instead, this made the application work on both systems. I hope this will help someone else in the future. Cheers!

import logging
import constant
from swiftclient import client, ClientException
from swiftclient.service import SwiftError
from keystoneauth1.identity import v3
import keystoneauth1.session

logging.getLogger('requests').setLevel(logging.DEBUG)
logging.getLogger('keystoneclient').setLevel(logging.DEBUG)
logging.getLogger('swiftclient').setLevel(logging.DEBUG)


class SwiftClientManager:
    def __init__(self):
        auth = dict()
        auth['username'] = constant.OS_USERNAME
        auth['password'] = constant.OS_PASSWORD
        auth['auth_url'] = constant.OS_AUTH_URL
        auth['project_name'] = constant.OS_PROJECT_NAME
        auth['user_domain_name'] = constant.OS_USER_DOMAIN_NAME
        auth['project_domain_name'] = constant.OS_USER_DOMAIN_NAME

        # Create a password auth plugin
        auth = v3.Password(**auth)
        # Create session
        session = keystoneauth1.session.Session(auth=auth)
        self.conn = client.Connection(session=session)

    def push_to_api(self, file_name, file_hierarchy, file_path):
        with open(file_path, 'rb') as file:
            try:
                self.conn.put_object(
                    constant.OS_CONTAINER_NAME,
                    file_hierarchy + file_name + constant.LOG_FILE_TYPE,
                    contents=file.read(),
                    content_type=constant.LOG_FILE_TYPE + '/type'
                )
            except (SwiftError, ClientException, Exception) as e:
                print(constant.FILE_UPLOAD_ERROR_STRING, file_name)
                raise e
            finally:
                file.close()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM