Structure du projet pour Google App Engine

119

J'ai lancé une application dans Google App Engine dès sa sortie, pour jouer avec la technologie et travailler sur un projet pour animaux de compagnie auquel je pensais depuis longtemps mais que je n'avais jamais réussi à démarrer. Le résultat est BowlSK . Cependant, au fur et à mesure qu'il grandit et que des fonctionnalités ont été ajoutées, il est devenu vraiment difficile de garder les choses organisées - principalement en raison du fait qu'il s'agit de mon premier projet python, et je n'en savais rien jusqu'à ce que je commence à travailler.

Ce que j'ai:

  • Le niveau principal contient:
    • tous les fichiers .py (je ne savais pas comment faire fonctionner les packages)
    • tous les modèles .html pour les pages de niveau principal
  • Sous-répertoires:
    • dossiers séparés pour css, images, js, etc.
    • dossiers contenant des modèles .html pour les URL de sous-répertoire

Exemple:
http://www.bowlsk.com/ correspond à HomePage (package par défaut), modèle à "index.html"
http://www.bowlsk.com/games/view-series.html?series=7130 correspond à ViewSeriesPage (encore une fois, package par défaut), modèle à "games / view-series.html"

C'est dégueulasse. Comment restructurer? J'avais 2 idées:

  • Dossier principal contenant: appdef, index, main.py?

    • Sous-dossier pour le code. Cela doit-il être mon premier colis?
    • Sous-dossier pour les modèles. La hiérarchie des dossiers correspondrait à la hiérarchie des packages
    • Sous-dossiers individuels pour css, images, js, etc.
  • Dossier principal contenant appdef, index, main.py?

    • Sous-dossier pour code + modèles. De cette façon, j'ai la classe de gestionnaire juste à côté du modèle, car à ce stade, j'ajoute beaucoup de fonctionnalités, donc les modifications apportées à l'une signifient des modifications à l'autre. Encore une fois, dois-je avoir ce nom de dossier comme premier nom de package pour mes classes? Je voudrais que le dossier soit "src", mais je ne veux pas que mes classes soient "src.WwhatPage"

Existe-t-il une meilleure pratique? Avec Django 1.0 à l'horizon, y a-t-il quelque chose que je peux faire maintenant pour améliorer ma capacité à m'intégrer avec celui-ci lorsqu'il deviendra le moteur officiel de création de modèles GAE? Je commencerais simplement à essayer ces choses et à voir ce qui me semble le mieux, mais le support de refactoring de pyDev ne semble pas gérer très bien les mouvements de paquets, donc ce sera probablement une tâche non triviale de remettre tout cela en marche.

Chris Marasti-Georg
la source

Réponses:

104

Tout d'abord, je vous suggère de jeter un œil à " Développement rapide avec Python, Django et Google App Engine "

GvR décrit une mise en page générale / standard du projet à la page 10 de sa présentation de diapositives .

Ici, je publierai une version légèrement modifiée de la mise en page / structure de cette page. Je suis à peu près ce modèle moi-même. Vous avez également mentionné que vous aviez des problèmes avec les colis. Assurez-vous simplement que chacun de vos sous-dossiers contient un fichier __init__.py. Ce n'est pas grave si c'est vide.

Fichiers de la chaudière

  • Celles-ci ne varient guère entre les projets
  • app.yaml: dirigez toutes les requêtes non statiques vers main.py
  • main.py: initialisez l'application et envoyez-lui toutes les requêtes

Présentation du projet

  • static / *: fichiers statiques; diffusé directement par App Engine
  • myapp / *. py: code python spécifique à l'application
    • views.py, models.py, tests.py, __init__.py et plus
  • templates / *. html: templates (ou myapp / templates / *. html)

Voici quelques exemples de code qui peuvent également vous aider:

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):

Je pense que cette mise en page fonctionne très bien pour les projets nouveaux et relativement petits à moyens. Pour les projets plus importants, je suggérerais de diviser les vues et les modèles pour avoir leurs propres sous-dossiers avec quelque chose comme:

Présentation du projet

  • static /: fichiers statiques; diffusé directement par App Engine
    • js / *. js
    • images / *. gif | png | jpg
    • css / *. css
  • myapp /: structure de l'application
    • modèles / *. py
    • vues / *. py
    • tests / *. py
    • templates / *. html: modèles
fuentesjr
la source
2
Une fois que vous avez atteint 20 ou 30 vues, et quelques "vues" qui ne gèrent que les messages puis les redirigent, les divisez-vous dans des fichiers séparés? Peut-être dans myapp / views / view1.py, myapp / views / view2.py? Ou que juste mon arrière-plan Java / C # transparaît?
Chris Marasti-Georg
1
J'ai édité mon article pour aborder des projets plus importants. J'espère que cela aide. Gardez à l'esprit que dans certains cas, ce sera un jugement.
fuentesjr
1
J'ai une disposition similaire, mais j'utilise "app" au lieu de "myapp".
Alexander Kojevnikov
Quelqu'un pourrait-il fournir un exemple de travail pour une telle disposition de projet? Je n'ai rien trouvé de convenable.
herrherr le
16

Ma mise en page habituelle ressemble à ceci:

  • app.yaml
  • index.yaml
  • request.py - contient l'application WSGI de base
  • lib
    • __init__.py - fonctionnalité commune, y compris une classe de base de gestionnaire de requêtes
  • contrôleurs - contient tous les gestionnaires. request.yaml les importe.
  • modèles
    • tous les templates django, utilisés par les contrôleurs
  • modèle
    • toutes les classes de modèles de banque de données
  • statique
    • fichiers statiques (css, images, etc.). Mappé vers / static par app.yaml

Je peux fournir des exemples de ce à quoi mes contrôleurs app.yaml, request.py, lib / init .py et exemples ressemblent, si ce n'est pas clair.

Nick Johnson
la source
5
Salut Nick, fais-le! J'ai également besoin de comparer différentes solutions :) Merci!
Hoang Pham
2
Salut, j'aimerais aussi voir des exemples si c'est possible. Merci.
11

J'ai implémenté un modèle standard de moteur d'application Google aujourd'hui et l'ai vérifié sur github. C'est dans le sens décrit par Nick Johnson ci-dessus (qui travaillait pour Google).

Suivez ce lien gae-passe-partout

sunil
la source
1
Pouvez-vous développer un peu cette réponse? Le lien github est très bien pour soutenir votre réponse, mais vous devriez au moins essayer de l'introduire un peu.
Shog9 du
1
Le fichier README.md dans la racine gae-passe-partout explique tout. github.com/droot/gae-boilerplate/blob/master/README.md
Ed Randall
7

Je pense que la première option est considérée comme la meilleure pratique. Et faites du dossier de code votre premier package. Le projet Rietveld développé par Guido van Rossum est un très bon modèle pour apprendre. Jetez-y un œil: http://code.google.com/p/rietveld

En ce qui concerne Django 1.0, je vous suggère de commencer à utiliser le code du tronc Django au lieu du GAE intégré au port django. Encore une fois, regardez comment cela se fait à Rietveld.

Jiayao Yu
la source
Quelle est la meilleure raison d'utiliser Django? J'utilise WebApp et cela me sert très bien. En outre, j'espère que Google offrira bientôt une meilleure intégration des deux. Quel est l'inconvénient d'utiliser le port Django intégré?
jamtoday
3

J'aime webpy , je l'ai donc adopté comme cadre de création de modèles sur Google App Engine.
Mes dossiers de paquets sont généralement organisés comme ceci:

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

Voici un exemple.

systempuntoout
la source
1

Je ne suis pas tout à fait au courant des dernières meilleures pratiques, et cetera, en ce qui concerne la mise en page du code, mais lorsque j'ai créé ma première application GAE, j'ai utilisé quelque chose le long de votre deuxième option, où le code et les modèles sont côte à côte.

Il y avait deux raisons à cela - l'une, cela gardait le code et le modèle à proximité, et deuxièmement, la disposition de la structure du répertoire imitait celle du site Web - ce qui (pour moi) me permettait de me souvenir un peu plus où tout était.

Dominic Eidson
la source