Estructura del proyecto para Google App Engine

119

Comencé una aplicación en Google App Engine justo cuando salió, para jugar con la tecnología y trabajar en un proyecto favorito en el que había estado pensando durante mucho tiempo pero que nunca llegué a comenzar. El resultado es BowlSK . Sin embargo, a medida que ha crecido y se han agregado funciones, se ha vuelto realmente difícil mantener las cosas organizadas, principalmente debido al hecho de que este es mi primer proyecto de Python, y no sabía nada al respecto hasta que comencé a trabajar.

Lo que tengo:

  • El nivel principal contiene:
    • todos los archivos .py (no sabía cómo hacer que los paquetes funcionaran)
    • todas las plantillas .html para páginas de nivel principal
  • Subdirectorios:
    • carpetas separadas para css, imágenes, js, etc.
    • carpetas que contienen plantillas .html para URL de tipo subdirección

Ejemplo:
http://www.bowlsk.com/ se asigna a HomePage (paquete predeterminado), plantilla en "index.html"
http://www.bowlsk.com/games/view-series.html?series=7130 se asigna a ViewSeriesPage (nuevamente, paquete predeterminado), plantilla en "games / view-series.html"

Es desagradable. ¿Cómo reestructuro? Tenía 2 ideas:

  • Carpeta principal que contiene: appdef, indexes, main.py?

    • Subcarpeta para código. ¿Tiene que ser este mi primer paquete?
    • Subcarpeta para plantillas. La jerarquía de carpetas coincidiría con la jerarquía de paquetes
    • Subcarpetas individuales para css, imágenes, js, etc.
  • Carpeta principal que contiene appdef, indexes, main.py?

    • Subcarpeta para código + plantillas. De esta manera tengo la clase de controlador justo al lado de la plantilla, porque en esta etapa, estoy agregando muchas características, por lo que las modificaciones a una significan modificaciones a la otra. Nuevamente, ¿tengo que hacer que este nombre de carpeta sea el primer nombre de paquete para mis clases? Me gustaría que la carpeta fuera "src", pero no quiero que mis clases sean "src.WhateverPage"

¿Existe una buena práctica? Con Django 1.0 en el horizonte, ¿hay algo que pueda hacer ahora para mejorar mi capacidad para integrarme con él cuando se convierta en el motor de plantillas oficial de GAE? Simplemente comenzaría a probar estas cosas y vería cuál parece mejor, pero el soporte de refactorización de pyDev no parece manejar muy bien los movimientos de paquetes, por lo que probablemente será una tarea no trivial hacer que todo esto funcione nuevamente.

Chris Marasti-Georg
fuente

Respuestas:

104

Primero, te sugiero que eches un vistazo a " Desarrollo rápido con Python, Django y Google App Engine ".

GvR describe un diseño de proyecto general / estándar en la página 10 de su presentación de diapositivas .

Aquí publicaré una versión ligeramente modificada del diseño / estructura de esa página. Yo mismo sigo prácticamente este patrón. También mencionaste que tenías problemas con los paquetes. Solo asegúrese de que cada una de sus subcarpetas tenga un archivo __init__.py. Está bien si está vacío.

Archivos repetitivos

  • Estos apenas varían entre proyectos
  • app.yaml: dirige todas las solicitudes no estáticas a main.py
  • main.py: inicializa la aplicación y envía todas las solicitudes

Diseño del proyecto

  • static / *: archivos estáticos; servido directamente por App Engine
  • myapp / *. py: código Python específico de la aplicación
    • views.py, models.py, tests.py, __init__.py y más
  • templates / *. html: templates (o myapp / templates / *. html)

Aquí hay algunos ejemplos de código que también pueden ayudar:

main.py

import wsgiref.handlers

from google.appengine.ext import webapp
from myapp.views import *

application = webapp.WSGIApplication([
  ('/', IndexHandler),
  ('/foo', FooHandler)
], debug=True)

def main():
  wsgiref.handlers.CGIHandler().run(application)

myapp / views.py

import os
import datetime
import logging
import time

from google.appengine.api import urlfetch
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import webapp
from models import *

class IndexHandler(webapp.RequestHandler):
  def get(self):
    date = "foo"
    # Do some processing        
    template_values = {'data': data }
    path = os.path.join(os.path.dirname(__file__) + '/../templates/', 'main.html')
    self.response.out.write(template.render(path, template_values))

class FooHandler(webapp.RequestHandler):
  def get(self):
    #logging.debug("start of handler")

myapp / models.py

from google.appengine.ext import db

class SampleModel(db.Model):

Creo que este diseño funciona muy bien para proyectos nuevos y relativamente pequeños o medianos. Para proyectos más grandes, sugeriría dividir las vistas y los modelos para tener sus propias subcarpetas con algo como:

Diseño del proyecto

  • static /: archivos estáticos; servido directamente por App Engine
    • js / *. js
    • imágenes / *. gif | png | jpg
    • css / *. css
  • myapp /: estructura de la aplicación
    • modelos / *. py
    • vistas / *. py
    • pruebas / *. py
    • templates / *. html: plantillas
fuentesjr
fuente
2
Una vez que obtiene 20 o 30 vistas, y un par de "vistas" que solo manejan publicaciones y luego las redireccionan, ¿las divide en archivos separados? ¿Quizás en myapp / views / view1.py, myapp / views / view2.py? ¿O solo se muestra mi fondo Java / C #?
Chris Marasti-Georg
1
Edité mi publicación para abordar proyectos más grandes. Espero que eso ayude. Tenga en cuenta que en algunos casos será una decisión de criterio.
fuentesjr
1
Tengo un diseño similar, pero uso "app" en lugar de "myapp".
Alexander Kojevnikov
¿Alguien podría proporcionar un ejemplo práctico para un diseño de proyecto de este tipo? No he encontrado nada adecuado.
Herrherr
16

Mi diseño habitual se parece a esto:

  • app.yaml
  • index.yaml
  • request.py: contiene la aplicación WSGI básica
  • lib
    • __init__.py - funcionalidad común, incluida una clase base de controlador de solicitudes
  • controladores: contiene todos los controladores. request.yaml los importa.
  • plantillas
    • todas las plantillas de django, utilizadas por los controladores
  • modelo
    • todas las clases de modelos del almacén de datos
  • estático
    • archivos estáticos (css, imágenes, etc.). Asignado a / static por app.yaml

Puedo proporcionar ejemplos de cómo se ven mi app.yaml, request.py, lib / init .py y controladores de muestra, si esto no está claro.

Nick Johnson
fuente
5
Hola Nick, ¡hazlo! También necesito comparar entre diferentes soluciones :) ¡Gracias!
Hoang Pham
2
Hola, también me gustaría ver algunos ejemplos si es posible. Gracias.
11

Implementé un modelo de motor de aplicaciones de Google hoy y lo verifiqué en github. Esto sigue las líneas descritas anteriormente por Nick Johnson (que solía trabajar para Google).

Siga este enlace gae-boilerplate

Sunil
fuente
1
¿Puedes ampliar un poco esta respuesta? El enlace de github está muy bien para respaldar su respuesta, pero al menos debería intentar presentarlo un poco.
Shog9
1
El archivo README.md en la raíz de gae-boilerplate lo explica todo. github.com/droot/gae-boilerplate/blob/master/README.md
Ed Randall
7

Creo que la primera opción se considera la mejor práctica. Y convierta la carpeta de código en su primer paquete. El proyecto Rietveld desarrollado por Guido van Rossum es un muy buen modelo del que aprender. Échale un vistazo: http://code.google.com/p/rietveld

Con respecto a Django 1.0, le sugiero que comience a usar el código troncal de Django en lugar del GAE integrado en el puerto de django. Nuevamente, eche un vistazo a cómo se hace en Rietveld.

Jiayao Yu
fuente
¿Cuál es la mejor razón para usar Django? He estado usando WebApp y me ha funcionado muy bien. Además, espero que Google ofrezca una mejor integración de los dos pronto. ¿Cuál es la desventaja de usar el puerto de Django integrado?
jamtoday
3

Me gusta webpy, así que lo he adoptado como marco de plantillas en Google App Engine.
Las carpetas de mis paquetes suelen estar organizadas así:

app.yaml
application.py
index.yaml
/app
   /config
   /controllers
   /db
   /lib
   /models
   /static
        /docs
        /images
        /javascripts
        /stylesheets
   test/
   utility/
   views/

He aquí un ejemplo.

sistema de salida
fuente
1

No estoy completamente actualizado sobre las últimas mejores prácticas, etcétera, en lo que respecta al diseño de código, pero cuando hice mi primera aplicación GAE, usé algo junto con su segunda opción, donde el código y las plantillas están uno al lado del otro.

Hubo dos razones para esto: una, mantuvo el código y la plantilla cerca, y en segundo lugar, hice que el diseño de la estructura del directorio imitara la del sitio web, lo que lo hizo (para mí) un poco más fácil recordar dónde estaba todo.

Dominic Eidson
fuente