【问题标题】:PyDrive client_secrets from other directoryPyDrive client_secrets 来自其他目录
【发布时间】:2016-02-25 17:55:33
【问题描述】:

我正在使用 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 放置在临时文件夹中,所以我不知道它在哪里会的。

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

【问题讨论】:

    标签: python pyinstaller pydrive


    【解决方案1】:

    更简单的解决方案:

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

    【讨论】:

    • settings.yaml 文件有类似的技巧吗?我想把它放在一个子文件夹中......
    • 我想对我的秘密文件进行哈希处理,因此如果有人找到它,他们将无法使用它。那么,有没有办法将此文件的内容传递给 googleauth,而不是文件路径?如果没有,我会尝试编辑源代码。
    【解决方案2】:

    真的不是最好的解决方案,但我只是自己修改了 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)
    

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        要更改默认设置文件,您需要在实例化 GAuth 实例时进行设置。下面,我在工作目录中创建了一个名为 config_files 的子文件夹,并将 pydrive 设置 yaml 重命名如下:

        from pydrive2.auth import GoogleAuth
        
        gauth = GoogleAuth(settings_file='config_files/pydrive_settings.yaml')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-08
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-15
          • 1970-01-01
          相关资源
          最近更新 更多