PyDrive client_secrets来自其他目录

时间:2016-02-25 17:55:33

标签: python pyinstaller pydrive

我正在使用PyDrive从我使用Pyinstaller打包的桌面Python应用程序将文件上传到GoogleDrive。我想尽可能地隐藏client_secrets.json,所以我使用这个解决方案将它嵌入到Pyinstaller .exe文件中:Bundling Data files with PyInstaller 2.1 and MEIPASS error --onefile

然而,PyDrive没有从Pyinstaller放置数据文件的临时目录中找到client_secrets文件。

如何让PyDrive从另一个目录中读取json文件,尤其是AppData?我想在将文件从临时目录移动到工作目录之前进行身份验证和删除,如果之后,但有些用户没有管理员权限,无法修改程序文件(应用程序的安装位置)

我看到我可以使用我可以引用另一个目录的settings.yaml文件,但是pyinstaller似乎使用sys._MEIPASS变量将嵌入式client_secrets.json放在temp文件夹中,所以我不知道它在哪里将是。

我必须直接将这个有价值的内容传递给GoogleAuth(),有没有办法做到这一点?

3 个答案:

答案 0 :(得分:5)

更简单的解决方案:

from pydrive.auth import GoogleAuth
GoogleAuth.DEFAULT_SETTINGS['client_config_file'] = path_to_secrets_file

答案 1 :(得分:1)

真的不是最好的解决方案,但我自己修改了Pydrive auth.py文件来做...

我通过添加此方法使用了我在代码中添加关于MEIPASS的技巧:

 def resource_path(self,relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        try:
            # PyInstaller creates a temp folder and stores path in _MEIPASS
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")
        return os.path.join(base_path, relative_path)

修改这些方法:

加载凭据文件的方法:(我不关心它是否出现,但你当然不能将其设置为我的)

def LoadCredentialsFile(self, credentials_file=None):
    """Loads credentials or create empty credentials if it doesn't exist.

    Loads credentials file from path in settings if not specified.

    :param credentials_file: path of credentials file to read.
    :type credentials_file: str.
    :raises: InvalidConfigError, InvalidCredentialsError
    """
    if credentials_file is None:
      credentials_file = self.settings.get('save_credentials_file')
      if credentials_file is None:
        raise InvalidConfigError('Please specify credentials file to read')
    try:
      storage = Storage(self.resource_path(credentials_file))
      self.credentials = storage.get()
    except CredentialsFileSymbolicLinkError:
      raise InvalidCredentialsError('Credentials file cannot be symbolic link')

加载client.secrets的方法:

  def LoadClientConfigFile(self, client_config_file=None):
    """Loads client configuration file downloaded from APIs console.

    Loads client config file from path in settings if not specified.

    :param client_config_file: path of client config file to read.
    :type client_config_file: str.
    :raises: InvalidConfigError
    """
    if client_config_file is None:
      client_config_file = self.settings['client_config_file']
    try:
      client_type, client_info = clientsecrets.loadfile(self.resource_path(client_config_file))
...method continue here...

和init方法:

def __init__(self, settings_file='settings.yaml',http_timeout=None):
    """Create an instance of GoogleAuth.

    This constructor just sets the path of settings file.
    It does not actually read the file.

    :param settings_file: path of settings file. 'settings.yaml' by default.
    :type settings_file: str.
    """
    self.http_timeout=http_timeout
    ApiAttributeMixin.__init__(self)
    self.client_config = {}
    try:
      self.settings = LoadSettingsFile(self.resource_path(settings_file))
    except SettingsError:
      self.settings = self.DEFAULT_SETTINGS
    else:
      if self.settings is None:
        self.settings = self.DEFAULT_SETTINGS
      else:
        ValidateSettings(self.settings)

我知道这可能不是一个好方法:)但如果有人知道更好的方法,但它有效......

所以,如果有人有更好的解决方案,请告诉我:)

答案 2 :(得分:1)

设置路径时,请确保路径中没有前导/:

例如: path_to_secrets_file = '/docs/secrets.json' -> 这将从根目录搜索,但未找到抱怨文件。如果省略 / 它会正确地与当前工作文件夹合并。

from pydrive.auth import GoogleAuth
GoogleAuth.DEFAULT_SETTINGS['client_config_file'] = path_to_secrets_file