2010-09-23 7 views
14

Tworzę aplikację Google AppEngine i wątpię, czy powinienem przechowywać (wrażliwe) dane konfiguracyjne, takie jak dane logowania.Co to jest dobre miejsce do przechowywania konfiguracji w Google AppEngine (python)

Czy powinienem utworzyć pojedynczą jednostkę do konfiguracji, lub czy istnieje inny zalecany sposób jej zapisania.

+0

jakiego rodzaju dane uwierzytelniające? – systempuntoout

+0

@systempuntoout Na przykład moje dane uwierzytelniające Amazon AWS dotyczące dostępu do S3 –

+0

Jeśli nie podoba ci się zwykłe poświadczenia w kodzie źródłowym, jedynym sposobem jest użycie modelu konfiguracji w magazynie danych, w przeciwnym razie możesz zapisać ustawienia w niektórych plikach .ini dostęp do niego za pomocą [ConfigParser] (http://docs.python.org/library/configparser.html). – systempuntoout

Odpowiedz

17

Jeśli masz problemy z osadzaniem ich w swoim źródle, możesz to zrobić, ale jeśli potrzebujesz, aby można było je dynamicznie konfigurować, dane to droga do zrobienia. Możesz uniknąć pobierania ustawień dla każdego żądania, buforując je w pamięci lokalnej. Oto klasa pomocnicza do tego:

class Configuration(db.Model): 
    _INSTANCE = None 

    @classmethod 
    def get_instance(cls): 
    if not cls._INSTANCE: 
     cls._INSTANCE = cls.get_or_insert('config') 
    return cls._INSTANCE 

Po prostu podklasuj to przy dowolnych wartościach konfiguracji, których potrzebujesz (lub zmodyfikuj samą klasę). Ponieważ załadowany kod jest nadal wyświetlany między żądaniami, wystarczy wykonać jedną instancję pobierania dla każdej aplikacji - jeśli jednak chcesz mieć możliwość dynamicznej aktualizacji konfiguracji, możesz skorzystać z limitu czasu.

Jeśli chcesz buforować rzeczy przez ograniczony czas, najlepszym rozwiązaniem jest po prostu przechowywanie znacznik czasu, gdy go pobrane:

class Configuration(db.Model): 
    CACHE_TIME = datetime.timedelta(minutes=5) 

    _INSTANCE = None 
    _INSTANCE_AGE = None 

    @classmethod 
    def get_instance(cls): 
    now = datetime.datetime.now() 
    if not cls._INSTANCE or cls._INSTANCE_AGE + cls.CACHE_TIME < now: 
     cls._INSTANCE = cls.get_or_insert('config') 
     cls._INSTANCE_AGE = now 
    return cls._INSTANCE 
+0

Bardzo interesujące, nigdy wcześniej nie widziałem tej techniki.Zazwyczaj używałbym memcache w celu zminimalizowania liczby pobrań z magazynu danych, ale wygląda na to, że będzie jeszcze szybciej, dopóki instancja zostanie załadowana. Dowolny limit pamięci, który uniemożliwiłby korzystanie z tego zbyt wiele? – Franck

+0

Tak, są limity pamięci - choć mogą ulec zmianie. Prawdopodobnie nie powinieneś używać pamięci instancji do uogólnionego buforowania, ale jest idealny do danych konfiguracyjnych. –

+1

Ok, dzięki, będę o tym pamiętać. Czy masz jakieś wskazówki, jak zbudować limit czasu, o którym mówisz? – Franck

10

Przechowuj je w module. Możesz iść prosto, jakby moduł config.py z, powiedzmy:

AMAZON_KEY = 'XXXX' 

Następnie użyj:

import config 
service = my_amazon_service(config.AMAZON_KEY) 

Albo mają nieco bardziej wyrafinowany obiekt konfiguracyjny, który pozwala mieć sensowne domyślne dla aplikacji, namespaced config keys itp.

4

Jeśli to dane wrażliwe, nie należy przechowywać go w kodzie źródłowym jak to zostaną sprawdzone w kontroli źródła. Źli ludzie (wewnątrz lub na zewnątrz organizacji) mogą go tam znaleźć. Ponadto środowisko programistyczne prawdopodobnie używa różnych wartości konfiguracyjnych ze środowiska produkcyjnego. Jeśli te wartości są przechowywane w kodzie, będziesz musiał uruchomić inny kod w fazie projektowania i produkcji, co jest nieporządną i złą praktyką.

W moich projektach, umieścić dane konfiguracyjne w magazynu danych przy użyciu tej klasy:

from google.appengine.ext import ndb 

class Settings(ndb.Model): 
    name = ndb.StringProperty() 
    value = ndb.StringProperty() 

    @staticmethod 
    def get(name): 
    NOT_SET_VALUE = "NOT SET" 
    retval = Settings.query(Settings.name == name).get() 
    if not retval: 
     retval = Settings() 
     retval.name = name 
     retval.value = NOT_SET_VALUE 
     retval.put() 
    if retval.value == NOT_SET_VALUE: 
     raise Exception(('Setting %s not found in the database. A placeholder ' + 
     'record has been created. Go to the Developers Console for your app ' + 
     'in App Engine, look up the Settings record with name=%s and enter ' + 
     'its value in that record\'s value field.') % (name, name)) 
    return retval.value 

Aplikacja byłoby to zrobić, aby uzyskać wartość:

AMAZON_KEY = Settings.get('AMAZON_KEY') 

Jeśli jest wart, że klucz w magazynie danych, dostaniesz go. Jeśli tak nie jest, zostanie utworzony rekord zastępczy i zostanie zgłoszony wyjątek. Wyjątek przypomni Ci o przejściu do Developers Console i zaktualizowaniu rekordu zastępczego.

Uważam, że to nie zgaduje ustawień wartości konfiguracyjnych. Jeśli nie masz pewności, jakie wartości konfiguracyjne ustawić, po prostu uruchom kod, a on ci to powie!

+1

Dobra robota, działa jak urok, dodałem również zestaw metody !! –

Powiązane problemy