将存储在谷歌云存储中的python模块导入本地脚本

时间:2015-03-11 05:36:42

标签: python google-cloud-storage

我有一个存储在谷歌云存储中的python脚本。有没有办法将python模块导入我的本地脚本?

3 个答案:

答案 0 :(得分:1)

如果您在linux下工作,您可以将您的Google云存储安装为远程文件系统(例如通过sshfs,但我不知道它如何适用于gcs ......)然后将新安装的fs的文件夹添加到您的本地$PYTHONPATH。也许这可以是一种在本地添加脚本的方法。

希望它有所帮助。

编辑也许看一下这篇文章:GCE Use Cloud Storage Bucket as Mounted Drive

答案 1 :(得分:1)

可以这样做,但是像WWhisperer建议的那样以局部方式安装它是一个更好的主意。

但是,如果您愿意,可以在堆栈溢出和elsewhere上将远程资源导入Python O'Reilly进行一些有趣的讨论。

答案 2 :(得分:0)

可以覆盖Python的导入过程,以便您可以从本地磁盘以外的其他位置加载源。根据{{​​3}}的答案,您可以构建MetaPathFinder和Loader。

import sys
import types
from .gcsutils import get_blob
from importlib.abc import Loader, MetaPathFinder
from importlib.machinery import ModuleSpec, SourceFileLoader
import os


class GCSMetaFinder(MetaPathFinder):
    def find_spec(self, fullname, path, target=None):
        # we prefix our code that is not on disk with a "virtual_prefix" that we map into a cloud storage path.
        if fullname.startswith('virtual_prefix'):
            if len(fullname.split(".")) <= 2:
                # We need to create a "package" for our virtual prefix so we can load modules under it.
                return ModuleSpec(fullname, PlaceHolderLoader())
            try:
                _, relative_path = fullname.split('.')
                filename = "code/{}.py".format(relative_path)
                # get_blob is a helper function that uses google.cloud.storage with a preset bucket to get a blob (https://googleapis.dev/python/storage/latest/buckets.html#google.cloud.storage.bucket.Bucket.blob)
                blob = get_blob(filename)
                if blob.exists():
                    return ModuleSpec(fullname, GCSLoader(blob))
            except AssertionError as e:
                return None
        return None

class PlaceHolderLoader(Loader):
    # creates a "package" so that python thinks modules can exist under here.
    def create_module(self, spec):
        dummy_module = types.ModuleType(spec.name)
        dummy_module.__path__ = []
        return dummy_module

    def exec_module(self, module):
        pass


class GCSLoader(Loader):
    def __init__(self, blob):
        self.blob = blob

    def create_module(self, spec):
        return None # use default module creation semantics

    def exec_module(self, module):
        data = self.blob.download_as_string()
        exec(data, vars(module))


def install():
    """Inserts the finder into the import machinery"""
    sys.meta_path.insert(0, GCSMetaFinder())

我已经根据我们现在为项目测试的内容更新了此代码。