• Home
  • Учебник по ExtJS
  • О сайте
  •  


    Запуск нескольких приложений под одним идентификатором App Engine

    Июль 31st, 2008

    Оригинал статьи http://blog.appenginefan.com/2008/04/multiplexing-and-namespaces-running.html

    До тех пор, пока не завершился предварительный период тестирования платформы, разработчик может создать только 10 своих приложений. Последний раз, когда я заходил в панель управления своего приложения, я обнаружил что мой URL Shortlinker практически не использует для своей работы системных ресурсов. Это происходит на мой взгляд по трем причинам и соответствует ситуации у других разработчиков:

    • сайт практически никем не посещается (пока слишком мало на него внешних ссылок)
    • приложение оптимизировано для повышения производительности (так как я знал, что для этого можно сделать)
    • на самом деле это простое приложение и не требует для работы много ресурсов

    На сегодняшний день разработчики некоторых приложений уже должны беспокоиться о превышении квот, однако, готов поспорить, для многих других (таких как я) это пока не является проблемой. Таким образом, если мы имеем целый набор приложений, код которых не требует много места, то почему бы не опубликовать их вместе?

    Так появится возможность использовать общие ресурсы одного идентификатора для запуска нескольких маленьких приложений. К примеру, вы имеете базу данных ссылок, гостевую книгу, счетчик посещаемости сайта и генератор случайных чисел. Объедините их вместе, назовите приложение «Инструменты для сайта» и запустите его как один экземпляр на App Engine. К сожалению, процесс объединения может оказаться довольно сложным (что если эти приложения используют классы моделей с одинаковыми именами или названия их файлов совпадают?), поэтому придется немного поработать. Я убежден, что возможно использовать часть волшебства языка Python и поместить код каждого приложения в свой каталог и создать единый корневой обработчик-диспетчер для всех обращений к сайту.

    Второй вариант – задействовать возможность работы с мажорными версиями. Я могу опубликовать два разных приложения с одним и тем же идентификатором, одно из них будет иметь основной номер версии «1″, а другое – версию «2″. Они оба будут работать независимо друг от друга, до тех пор, пока их объекты в хранилище не будут пересекаться.

    Пример:

    Следующий код является простым каталогом закладок:

    import wsgiref.handlers
    
    from google.appengine.ext import webapp
    
    class MainPage(webapp.RequestHandler):
      def get(self):
        if self.request.get('url'):
          self.redirect(self.request.get('url'))
          return
        self.response.out.write('Link scrubber')
    
    def main():
      application = webapp.WSGIApplication([('/.*', MainPage)], debug=True)
      wsgiref.handlers.CGIHandler().run(application)
    
    if __name__ == "__main__":
      main()

    Его можно открыть, перейдя по ссылке http://2.2.aef.appspot.com/, которая находится в том же самом месте, что и приложение URL shortlinker. Таким образом shortlinker является версией 1 этой программы, а представленный выше каталог ссылок (совершенно другое приложение) определен как версия 2.

    Хотя этот подход будет работать, я не рекомендую его для использования. Это кратковременное удобство для развертывания может затем выльиться в головную боль после того, как любое из этих приложений станет популярным у пользователей. Любое минимальное изменение и обновление кода на сервере приведет к тому, что каталог ссылок будет изменять номер своей минорной версии. Также вы не сможете привязать к нему домен, обслуживаемый Службами Google. Другими словами, этот способ имеет больше ограничений, чем преимуществ.

    Третьим вариантом является тот способ, который зачастую может быть использован при наименьшем изменении кода и позволяет привлечь к приложению дополнительных пользователей: возможность работы одного и того же приложения с разными данными с помощью использования имени домена в качестве области имен в хранилище.

    Одно единственное приложение App Engine может быть привязано к большому числу разных доменов. Простое определение значения os.environ['SERVER_NAME'] в приложении, укажет на то, в какой области имен оно сейчас работает. Если мы заранее позаботимся о алгоритме разделения данных, то сможем предоставить возможность пользователям сделать свои данные уникальными для каждого из них.

    Давайте рассмотрим конкретный пример: загрузите код wiki-приложения с сайта code.google.com. Оно представляет из себя довольно неплохой движок, но не имеет возможности разделять данные по доменам. Представим, что мы имеем три различных продукта (база закладок, редиректор, хостинг страниц) и хотим добавить wiki для каждого из них.

    Если вы посмотрите на основной файл, wiki.py, то увидите, что реально только в двух местах кода выполняется задание имена объекта для чтения или записи данных в хранилище:

    def save(self):
    ...
     entity['name'] = self.name
    ...
     datastore.Put(entity)
    
    def load(name):
    ...
     query = datastore.Query('Page')
     query['name ='] = name
     entities = query.Get(1)

    Не будем заострять внимание на том, что разработчик использует кривой метод доступа к данным без моделей или запросов GQL. Мы видим, что код использует параметр «name», являющийся именем wiki-страницы, в качестве уникального ключа для загрузки и записи данных в хранилище. Достаточно добавить значение нашего домена к коду, и мы получим разделение области имен для создания сколь угодного числа одинаковых страниц с различным содержимым:

    import os
    def GetDomain():
    return os.environ['SERVER_NAME']
    
    ...
    
    def save(self):
    ...
     entity['name'] = GetDomain() + "|" +self.name # ИЗМЕНЕНО
    ...
     datastore.Put(entity)
    
    def load(name):
    ...
     query = datastore.Query('Page')
     query['name ='] = GetDomain() + "|" + name # ИЗМЕНЕНО
     entities = query.Get(1)

    С помощью выполнения несложных изменений мы обеспечили возможность использования этого приложения множеством пользователей независимо без необходимости создания для каждого из них собственного экземпляра приложения. Все это также будет работать с другим более сложным кодом, как можно увидеть на этом примере. Однако, чем выше будет уровень сложности приложения, тем гораздо труднее будет вносить подобные изменения.

    В завершении

    Даже без выполнения изменения кода, есть возможность использовать один идентификатор для работы множества приложений параллельно. С использованием домена в качестве области поиска объектов, становится возможным разбивать данные каждого пользователя в хранилище для одного приложения. Оба метода увеличивают полезное использование одного приложения, но пока еще достаточно сыры. Я верю что есть и другой лучший метод выполнения совместной работы, но пока не знаю его. Ниже описаны мысли по этому поводу:

    * приложение wiki в этом примере использует для работы с хранилищем простой интерфейс и могло бы задействовать оба метода доступа к данным: язык запросов GQL и классы модели. В зависимости от того, какая высокоуровневая реализация интерфейса работает с доступом к данным хранилища, можно разработать патч для их автоматического разделения по имени домена или подкаталогу. Если это удатся, то все проблемы с конфликтами имен объектов для выполнения нескольких приложения под одним идентификатором, будут сняты.

    * SDK написан на языке Python. В нем содержится класс, который в зависимости от содержимого конфигурационного файла app.yaml, принимает решение, какому из скриптов приложения необходимо передать управление. Возможно, используя этот код, создать свой обработчик верхнего уровня, который будет знать к какому из подкаталогов с приложением следует направить запрос на основании информации из файла app.yaml.




    Эффективная работа с глобальными счетчиками

    Июль 30th, 2008

    Оригинал статьи – http://blog.appenginefan.com/2008/06/efficient-global-counters.html

    Одним из примеров, как не нужно работать с глобальными счетчиками – тот наивный подход, который я использовал в прошлом (сохранять счетчик в объекте и обновлять его в транзакции) является бутылочным горлышком, который реально уменьшает производительность приложения. Вместо этого рекомендуется использовать механизм по разделению  счетчика на несколько составляющих, относящихся к разным группам объектов. Примерный код может выглядеть так:

    from google.appengine.ext import db
    import random
    
    SHARDS_PER_COUNTER = 20
    
    class CounterShard(db.Model):
      name = db.StringProperty(required=True)
      count = db.IntegerProperty(default=0)
    
    def GetCount(nameOfCounter):
      result = 0
      for shard in CounterShard.gql('WHERE name=:1', nameOfCounter):
        result += shard.count
      return result
    
    def ChangeCount(nameOfCounter, delta):
      shard_id = '/%s/%s' % (
         nameOfCounter, random.randint(1, SHARDS_PER_COUNTER))
      def update():
       shard = CounterShard.get_by_key_name(shard_id)
       if shard:
         shard.count += delta
       else:
         shard = CounterShard(
             key_name=shard_id, name=nameOfCounter, count=delta)
       shard.put()
      db.run_in_transaction(update)
    

    Очень интересное решение, но можно сделать еще лучше с помощью использования интерфейса Memcache API, путем сохранения значения счетчика в памяти и обновления его при необходимости. Следующий пример показывает, как можно установить период устаревания значения счетчика на одну минуту:

    def GetCount(nameOfCounter):
      memcache_id = '/CounterShard/%s' %  nameOfCounter
      result = memcache.get(memcache_id)
      if not (result == None):
        return result
      result = 0
     for shard in CounterShard.gql('WHERE name=:1', nameOfCounter):
       result += shard.count
      memcache.set(memcache_id, result, 60)
      return result
    



    Потоковый загрузчик данных для App Engine

    Июль 29th, 2008

    Недавно я провел много времени ожидая, когда AppEngine Bulk Loader наконец-то закончит свою работу. Пока в вашем приложении нет никаких данных, вы спокойно можете добавлять, изменять и удалять новые объекты в хранилище через Административную консоль, однако когда их становится очень много, работать с таким интерфейсом начинается тяжело.

    Официальным инструментом для массовой загрузки данных на сервер является Bulk Loader. Несмотря на то, что он плохо документирован, он является мощным (и медленным) инструментом.

    Как описано в статье, на которую я еще сошлюсь, суть его в том, что вы можете создать CSV файл с данными и передать его скрипту bulkload_client.py. Для корректной работы на сервере необходимо установить обработчик, который будет принимать строки в формате CSV и помещать данные в хранилище.

    Чтобы сделать это, ваш код должен вызывать метод bulkload.main(), передавая ему по одному объекту каждого типа (потомок db.Model). К примеру, если у вас есть объекты моделей Album и Track, необходимо выполнить следующее:

    if __name__=="__main__":
        bulkload.main(AlbumLoader(), TrackLoader())

    В коде указаны потомки классов bulkload.Loader — хотя вы можете не описывать свои новые классы, достаточно будет создать экземпляры класса bulkload.Loader и передать ему все параметры в конструктор. Кстати о параметрах, сначала указывается имя объекта, который загружается в приложение, затем список кортежей, каждый из которых содержит имя свойства модели и тип значения (либо стандартный тип языка Python, либо стандартный тип для хранилища, но не тип самого свойства — например, допускается str, но не db.StringProperty()).

    Это все, в обычном случае все предельно просто.

    Монстроидальный Cookie

    Первой недокументированной проблемой, с которой вы столкнетесь, будет безопасность. К примеру, если вы захотите, как это и покажется логичным, ограничить доступ к обработчику только для администраторов приложения, то обнаружите, что не существует способа передать пароль администратора скрипту bulkload_client.py. Вместо этого вам нужно будет указать очень, очень длинный cookie. Как сделать это?

    Авторизируйтесь в вашем приложении через свой браузер и перейдите по адресу, к которому привязан обработчик загрузки данных. Затем, выполните запрос GET, вместо используемого POST и увидите cookie, который необходимо будет использовать.

    Адский набор символов

    Если вы попытаетесь загрузить данные в кодировке UTF-8, то это может привести утилиту из среды разработки SDK в шок. Это происходит потому, что обработчик пытается привести полученные данные из UTF-8 в родной тип unicode еще до того, как передает его загрузчику, но класс BulkLoad.Load считает эти данные все еще закодированными (точнее модуль языка Python, отвечающий за работу с CSV ожидает тип str, а переданный ему тип unicode будет повторно декодировать их при помощи кодека ascii, что и приводит к порче данных).

    Надеюсь эту проблему скоро исправят, а пока временно приходится использовать обходное решение: создавать собственный класс, наследник класса bulkload.BulkLoad, который перекодирует данные:

    class BulkLoad(bulkload.BulkLoad):
        def Load(self, kind, data):
            return bulkload.BulkLoad.Load(self, kind, data.encode('utf-8'))


    Для определения собственной версии загрузчика, вам необходимо целиком скопировать код функции bulkload.main в свой модуль и отредактировать его — пока я не обнаружил другого удобного способа. Я надеюсь, что эту ошибку исправят довольно скоро.

    Винсент Исамбарт указал мне на то, что при инициализации экземпляра класса необходимо упомянуть, что вы используете utf-8. Я определил функцию, которая выполняет это преобразование:

    def utf8string(s):
        return unicode(s, 'utf-8') 

    …и затем использовать ее вместо типов str и unicode в конструкторе:

    class UserLoader(bulkload.Loader):
        def __init__(self):
            bulkload.Loader.__init__(self, 'User', [ ('name', utf8string), ])

    Загадочный метод HandleEntity

    В статье был приведен пример реализации метода HandleEntity, но никаких объяснений, как его можно использовать не было. Это очень полезное дополнение для обработки данных. По существу, он получает данные объекта и может изменить их так, как необходимо разработчику, после чего обратно вернуть его. Есть несколько интересных моментов:

    • Передаваемый объект является экземпляром класса datastore.Entity, а не db.Model. По своей сути он является обычным словарем языка Python с дополнительными опциями, может быть использован как обычный словарь dictionary['item'], если имеется необходимость изменения данных перед записью их в хранилище.
    • Если в процессе обработки появится необходимость создать дополнительный объект, то вы можете сделать это, передав название модели в качестве строки и опционально указать параметры name (ключ объекта) и его родителя parent (должен быть типа Key.)
    • Основной причиной, по которой вы можете создать еще один объект, будет возможность вернуть любое количество новых объектов из функции HandleEntity, таким образом каждая отдельная строка CSV файла может порождать большие массивы данных.
    • Пожалуй, наиболее интересной является возможность вообще не создавать объекты. Таким образом Поточный загрузчик превращается в Поточный универсальный обработчик. Если метод не возвращает объектов, то ничего нового в хранилище не создается, и модель данных, переданная функции становится нерелевантной. Вы можете использовать такой загрузчик для выполнения практически любой повторяющейся функции, которая принимает в качестве параметров значения из CSV файла.

    К примеру, ниже приведен код Bulk Deleter, который получает список ключей объектов для удаления их из CSV файла:

    class BulkDeleter(bulkload.Loader):
        def __init__(self):
            bulkload.Loader.__init__(self, 'BulkDelete', [ ('key', str), ])
    
        def HandleEntity(self, entity):
            key = entity['key'] entity = db.get(db.Key(key))
            if entity:
                entity.delete()
                return []

    Другие проблемы

    Все это хорошо, но, к сожалению, медленно и ненадежно. Может быть мне не повезло, но я часто видел ошибки 502 Bad Gateway и 500 Server Error, которые прерывали работу загрузчика. Один из параметров, которые можно передать программе bulkload_client.py, позволяет указать количество строк CSV файла, которые единовременно передаются за один раз. Его уменьшение может помочь решить проблему, но это не кажется правильным методом. Каждый раз вы запускаете процесс загрузки данных с самого начала.

    Я отправил патч для скрипта, запускаемого на стороне клиента, который выполняет пропуск заданного количества строк от начала файла, таким образом можно просто возобновить прерванную загрузку данных. Он также сообщает, сколько строк с данными было загружено на сервер, до того как произошла ошибка, и таким образом вы всегда будете знать, с какого места нужно возобновить загрузку. Возможно вы захотите, чтобы обработка данных происходила индемпотентно, так как не можете быть всегда уверены, где произойдет ошибка. Поэтому возможно захотите выполнять проверку существования объектов до их добавления к хранилищу, в противном случае придется указывать точное значение их ключей и тогда они будут перезаписывать объекты со старыми данными с помощью метода put().

    Надеюсь, этот материал окажется полезным! Хотя… нет, подождите. Я надеюсь что он окажется бесполезным, так как это будет означать что Bulk Loader стал работать как надо. :) В любом случае, надеюсь, что ваши данные будут загружены без проблем!




    Pagination: постраничный вывод в App Engine

    Июль 28th, 2008

    Разбиение вывода информации на страницы легко осуществимо в приложениях Google App Engine, для чего достаточно использовать обычный метод query.fetch(), подробнее описанный в документации:

    Небольшой пример части кода, как можно организовать загрузку объектов со статьями из хранилища по-странично, выглядит следующим образом:

    
    def generate_stories(self, query, template_values={}):
      """ Создание страницы с помощью переданной строки запроса объектов Stories.
    
      Мы работаем с различными типами вывода информации (форматы Atom, HTML и другие),
      таким образом страницы, которые выдают целиком списки доступных статей не должны
      воспроизводить эту логику.
    
      Параметры функции:
      query: созданный объект запроса данных, который извлекает список статей
                template_values: дополнительные значения для передачи в шаблон
      """
      # Определяем рамки получаемых значений с помощью параметров start и num,
      #  переданных в адресной строке
      start = self.get_arg_range('start', minvalue=0, maxvalue=1000, default=0)
      num = self.get_arg_range('num', minvalue=1, maxvalue=100, default=10)
    
      # включаем в выборку еще один дополнительный объект для определения существования
      #  следующей страницы - этот метод быстрее, чем выполнение второго запроса
      # для проверки существования следующей страницы
      stories = query.fetch(num+1, start)
      # был ли извлечен дополнительный объект? Если да, то это не последняя страница
      more_stories = len(stories) > num
      # убираем этот дополнительный объект из результатов
      stories = stories[:num-1]
      # если переменная не равна нулю, то также имеется предыдущая страница
      prev_stories = start > 0
      # и передаем реальное количество объектов, которые будут отображены
      disp_end = max(len(stories), 0) + start + 1
      disp_start = start + 1
    



    Установка Linux для новичков

    Июль 27th, 2008

    Данная статья рассказывает о процессе установки операционной системы Linux (в данном случае дистрибутив Ubuntu версии 8.04) на обычный офисный компьютер. Она адресована в первую очередь опытным пользователям операционной системы Windows и не работавшим ранее с Unix системами ИТ-специалистам.

    Все аспекты рассмотрены по-шагово и приведены со скриншотами всех этапов установки.

    Первое

    Для установки мы используем дистрибутив Ubuntu версии 8.04, который можно скачать с официального сайта или его зеркал в виде образа ISO и записать на компакт-диск. Почему именно Ubuntu? Большинство экспертов считает, что это наиболее дружественный к рядовому пользователю дистрибутив, который позволяет неподготовленным пользователям с наименьшими проблемами мигрировать с других операционных систем. Обратите внимание, что компания Canonical, производитель дистрибутива Ubuntu, выпускает его новые версии каждые полгода. Мы рассматриваем продукт, который увидел свет в августе 2008 года, и если вы читаете эти строки спустя продолжительное время, то было бы неплохо проверить его новые версии на сайте http://www.ubuntu.com/getubuntu

    Итак приступаем

    Скачиваем ISO образ установочной системы, например, с этого зеркала – http://mirror.anl.gov/pub/ubuntu-iso/CDs/hardy/ubuntu-8.04.1-desktop-i386.iso и прожигаем его на пустую CD болванку с помощью любимой программы для записи дисков.

    Берем свободный офисный компьютер и выполняем загрузку с этого диска. Обратите внимание, что информация, которая имеется на дисках компьютера в процессе установки может быть перезаписана, поэтому не рекомендуем экспериментировать на рабочей системе. Некоторые системные администраторы, которые не стеснены в количестве компьютеров, обычно для таких случаев используют две машины – одну с Windows, другую с Linux.

    У нас появляется экран с выбором языка установки:

    Конечно выбираем великий и могучий русский язык. На следующем экране из появившегося меню выбираем пункт Установить Ubuntu

    Read the rest of this entry »




    Небольшие изменения

    Июль 25th, 2008

    Мы рады сообщить, что в платформе Google App Engine произошли некоторые изменения. Наиболее значительные из них:

    • Доступно больше приложений: Хотите создать больше, чем 3 приложения в одном аккаунте App Engine? Теперь их можно сделать до 10!
    • Шкала времени в графиках панели управления: Появилась возможность задавать период в панели для получения требуемой детализации графика. Можно выбирать период в 24, 12 и 6 часов.
    • Экспорт журналов событий: Теперь можно использовать программу appcfg.py для того, чтобы загрузить на локальный компьютер журналы в текстовом формате. Для дополнительной информации запустите appcfg.py с параметром —-help.
    • Отправка писем с почтовым адресом авторизованного пользователя: Если вы используете Users API, то теперь появилась возможность отправлять сообщение с обратным адресом текущего авторизованного пользователя.

    Обновите SDK и прочитайте полный список произошедших изменений. Какие изменения вы хотите еще видеть в App Engine? Напишите это в группе Google проекта!




    App Engine Launcher для Mac OS X

    Июль 24th, 2008

    Пока я занимался написанием тестов для платформы Google App Engine, у меня появилась следующая идея: какие из приложений: BBEdit, Dreamweaver, CSSEdit или TextMate могут помочь в разработке приложений для App Engine? Как это глупо не звучит, я задумался о своей рабочей среде. Я использовал:

    • несколько приложений на Python, CSS, HTML и JavaScript.
    • командную строку для их запуска и просмотра журнала ошибок.
    • браузер для проведения локального тестирования и доступа к локальной консоли разработчика.
    • командную строку для публикации приложения.
    • браузер для просмотра панели управления развернутого приложения.

    Я задумался о том, какой недружественной пользователю может оказаться командная строка, и как много повторяющихся действий приходится выполнять для того, чтобы опубликовать приложение. С этими мыслями я занялся совместной работой с Джоном Грабовски из команды Google Mac и Бреттом Слаткином, инженером-разработчиком App Engine, над проектом Google App Engine Launcher для Mac OS X.

    App Engine Launcher не является заменителем вашего редактора кода или интегрированной среды разработки IDE. Она предоставляет удобный способ разработчику управлять списком его приложений. За несколько кликов можно запустить, просмотреть, опубликовать приложение или перейти к его журналу ошибок. Также в ней содержатся вкусные возможности вроде drag and drop, интеграции с редактором и быстрый переход к локальной консоли разработчика и панели управления опубликованного приложения.

    Загрузите его прямо сейчас. Если у вас появится предложение по добавлению в него новых возможностей (например, скриптинг, версии для Windows и Linux, искусственный интеллект ;) , напишите об этом в группе обсуждения.




    Подсказки по созданию масштабируемых приложений

    Июль 23rd, 2008

    Google App Engine позволяет создавать масштабируемые приложения намного проще, чем это делается на традиционных платформах, и правильно спроектированные приложения будут одинаково хорошо обслуживать от одного пользователя до миллиона. Что означает фраза, что приложения Google App Engine должны быть «правильно спроектированы»? Мы приводим несколько простых подсказок, при использовании которых, вы будете уверены, что ваше приложение надежно справится с высокой нагрузкой.

    • Избегайте конфликтов при работе с объектами хранилища. Если каждый запрос вашего приложения выполняет чтение и запись определенного объекта, то латентность приложения будет возрастать по мере того, как увеличивается его трафик, так как чтение и запись одного объекта происходит последовательно. Одним из таких примеров является использование глобального счетчика, то есть объекта, который содержит число обращений к странице и обновляется при каждом запросе. Есть несколько интересных способов реализации других алгоритмов по работе с такими объектами, одним из них является кэширование, которое будет рассмотрено ниже.
    • Избегайте использования больших групп объектов. Любые два объекта, которые имеют одного объекта-предка будут принадлежать к одной группе. Все операции записи в группы объектов являются последовательными, таким образом использование больших групп приведет к тому, что производительность приложения при работе с популярными объектами одной группы быстро деградирует. Вместо этого возьмите за правило использовать небольшие локализованные группы объектов.
    • Сохраняйте умеренно. Операция записи отнимает в системе больше ресурсов, чем операция чтения; примите это к сведению при работе с моделями данных. Если в какой-то части приложения вы можете избежать сохранения данных, так и стоит поступить.
    • Определите функцию main() для повторного использования кода. Экземпляры вашего приложения остаются запущенными какое-то время после получения запроса пользователя, поэтому есть шанс, что другой запрос будет отправлен в рабочий экземпляр приложения. В коде приложения можно определить функцию main, как показано в следующем примере:
      def main():
          application = webapp.WSGIApplication(_URLS, debug=True)
          wsgiref.handlers.CGIHandler().run(application)
      
      if __name__ == '__main__':
          main()

      Приложение может повторно использовать глобальные переменные, таким образом несмотря на то, что не будет гарантии, что следующий запрос попадет на запущенный экземпляр приложения, вы получите преимущества по кэшированию объектов и вычисляемых выражений. Этот пример работает просто: App Engine обнаружит определение функции main() и вызовет ее вместо проведения повторного импортирования модуля.

    • Профилируйте свой код. Вы можете использовать профайлер языка Python для того, чтобы изучить производительность своего кода.

    Есть еще какие-то предложения по оптимизации web-приложения под App Engine? Добавьте их к этому посту!




    Google App Engine + Google Data API: Интересная связка для Web

    Июль 22nd, 2008

    Не думали ли вы о том, что было бы неплохо создать в блоге запись о намечающейся вечеринке, добавить ее в календарь, пригласить друзей и все это сделать одним движением мыши? И все бы фотографии и видео с вечеринки, выложенные в открытый доступ, были привязаны к этому же событию? Интерфейс Google Data API все это делает возможным так, что ваши приложения на Google App Engine смогут взаимодействовать с другими сервисами Google, отображать и обновлять информацию определенного пользователя в этих сервисах.

    Команда разработчиков Google Data API выпустила обновление для клиентской библиотеки Google Data на языке Python, которое поддерживает работу под Google App Engine. С помощью нее ваше приложение сможет использовать интерфейс AuthSub и получить доступ к пользовательским данным.

    Джеф Скаддер, разработчик Google Data API и основной контрибьютор библиотеки Google Data Python client library, написал статью, в которой рассматриваются все шаги, которые необходимо выполнить для использования данных Google Data в приложении Google App Engine. Он также добавил пример такого приложения в проект Google App Engine sample code.

    Попробуйте использование этих возможностей!




    Google App Engine Helper для Django

    Июль 21st, 2008

    После того, как платформа Google App Engine была открыта для разработчиков, большинство предложений, которые поступили в компанию, касались более тесной интеграции с популярным фреймворком Django.

    Компания Google разработала и опубликовала специальный каркас, который обеспечивает более легкий процесс разработки проекта на Django и последующего его запуска на Google App Engine.

    Возможности этого каркаса:

    • Сохранение возможности использования большинства команд скрипта manage.py
    • Класс BaseModel имеет все те же возможности, что и стандартный для Django класс Model.
    • Возможность сериализации и десериализации экземпляров модели в код JSON, YAML и XML.
    • Доступ к тестовой среде Django с возможностью поддержки загрузки тестовых данных.

    Каркас опубликован под лицензией Apache 2.0. Команда Google продолжает работу с сообществом разработчиков Django для внесения в проект дополнительной функциональности.

    Каркас может быть загружен со страницы http://code.google.com/p/google-app-engine-django. Русскоязычная статья по его использованию находится по адресу http://googleappengine.ru/articles/appengine_helper_for_django.html. Об ошибках и предложениях по дополнительной функциональности можно сообщить на странице проекта.