在Python App Engine中如何唯一地识别在Dev SDK上运行的应用程序实例?

时间:2011-08-25 19:15:00

标签: python google-app-engine

我的应用程序依赖于使用urlfetch与之通信的外部服务。我有多个开发人员,他们在开发计算机上运行他们自己的应用程序实例,同时添加功能。每个开发人员实例都需要能够唯一地向外部服务标识自己,以便外部服务可以将他们的数据分开。

我需要一种从应用程序中为每个开发人员自动生成唯一标识符的方法。

是的,我可以让每个开发人员在代码中的变量中放入一个唯一的id,但我更希望它是自动的。

另外,我可能会阅读有关计算机硬件的一些信息(如MAC地址)并使用它,但我希望这段代码只使用在生产服务器上运行的东西,这样我最终也可以在那里使用它

2 个答案:

答案 0 :(得分:1)

我见过识别实例的唯一技巧是使用全局变量地址。

UNIQUE_INSTANCE_ID = {} # at module level
logging.debug("Instance %s." % (str("%X" % id( UNIQUE_INSTANCE_ID )).zfill(16)))

这似乎可以很好地唯一地识别一个实例;但它只识别一个实例,而不是一台机器。因此,如果重新启动实例,则会获得新标识符。这可能是一个“功能”。

你也可以使用一些META变量;如果开发人员都在主目录之外,你可以解析'PATH_TRANSLATED'之外的用户名。

至少,您可以将UUID注入数据总体的数据存储区;在数据存储区和缓存中存储元数据类型,并将该UUID包装到请求中。

from uuid import uuid4
from google.appengine.ext import db
from google.appengine.api import memcache

cache = memcache.Client()

class InstanceStamp(db.Model):
    code = db.StringProperty()

    INSTANCE_STAMP_KEY = "instance_stamp"

    @classmethod
    def get_stamp(cls):
        cache_key = cls.INSTANCE_STAMP_KEY 
        stamp_code = cache.get(cache_key)
        if stamp_code is None:
            code = uuid4().hex
            stamp = cls.get_or_insert('instance_stamp', code=code)
            if stamp is not None:
                cache.set(cache_key, stamp.code, 300)
                stamp_code = stamp.code
        return stamp_code

答案 1 :(得分:0)

每个db.Key实例的字符串版本具有相同的前缀,并且该前缀对于每个开发人员实例看起来是唯一的。尽管它们都具有相同的应用程序ID,但每台计算机的密钥编码版本也不同。

例如,一台机器上Foo:1的字符串键是:

  

ahNkZXZ-bWVkaWFjb29sZXItYXBwcgkLEgNGb28YAQw

在另一台机器上:

  

ahFzfm1lZGlhY29vbGVyLWFwcHIJCxIDRm9vGAEM

我不确定键的多少个字符(位?)代表应用程序名称而不是对象的类型和ID,所以我不认为只使用包含前N个字符的子字符串是正确的方法。

首次尝试:

def get_unique_id():
    return str(db.Key.from_path('UNIQUE_INSTANCE_ID', 1))

它的作用是为不存在的模型类型创建一个虚假的db.Key。在不同的机器上,这给出了不同的值,并且在同一台机器上,它始终给出相同的值。

<强>更新

正如@Nick Johnson指出的那样,实际上并没有像我预期的那样工作,也没有解决问题。我假设它是app.yaml中使用的appid中的appid,但是用于key的appid是来自app.yaml的appid,其前缀取决于应用程序是在SDK中还是在HR数据存储区中运行,因此这些键的字符串表示形式不同,因为它们中的appid是不同的。