standard google engine deploy app python css google-app-engine static webapp2

python - deploy - Publicación de hojas de estilo con webapp2 fuera de Google App Engine



deploy python google app engine (3)

Así que he implementado con éxito una aplicación que utiliza webapp2 / jinja2 y un servidor Pegar, pero tengo problemas para servir hojas de estilo estáticas.

He tenido suerte accediendo a archivos estáticos a través de este método , así como la implementación de un StaticFileHandler que encontré con algunos google-fu:

import os import mimetypes import webapp2 import logging class StaticFileHandler(webapp2.RequestHandler): def get(self, path): abs_path = os.path.abspath(os.path.join(self.app.config.get(''webapp2_static.static_file_path'', ''static''), path)) if os.path.isdir(abs_path) or abs_path.find(os.getcwd()) != 0: self.response.set_status(403) return try: f = open(abs_path, ''r'') self.response.headers.add_header(''Content-Type'', mimetypes.guess_type(abs_path)[0]) self.response.out.write(f.read()) f.close() except: self.response.set_status(404)

donde mi ruta de aplicación principal se ve así:

app = webapp2.WSGIApplication([(''/'', HelloWorld), (r''/display'', DisplayHandler), (r''/static/(.+)'', StaticFileHandler) ], debug=True)

Mis archivos CSS están en una carpeta debajo de la raíz de la aplicación: /static/css/main.css

Puedo acceder al archivo a través de la URL directa, e incluso vincularlo como una hoja de estilo, pero los estilos no se aplicarán. ¿Algunas ideas? ¿Hay alguna otra manera de servir hojas de estilo? ¿Alguna forma de implementar una app.yaml similar a GAE?


@Mnemon, felicitaciones por resolver mi problema. Yo te revalidaría, pero no tengo permitido hacer eso. Me convenciste de que si no es la única aplicación de webapp2 sin GAE, al menos es una forma de que funcione.

Pero también puedo contribuir que tu solución ahora se puede instalar como "pip install webapp2_static", de pipi --- por un autor que parece estar usando su nombre real ... de eso estoy seguro. Otros documentos de webapp2 que encontré útiles están disponibles aquí .

Estoy implementando tu código en un servidor de desarrollo de escritorio Linux, usando pegar, que también usaste:

def main(): from paste import httpserver httpserver.serve(app, host=''127.0.0.1'', port=''8080'')

Pero con el código como lo tienes arriba (que parece ser completamente idéntico al del archivo webapp2_static.py), no creo que poner mis archivos css en una carpeta llamada static en la raíz de la aplicación funcione como dijiste.

Por ejemplo, tengo /home/user/proj/public_html/app/app.py, donde el archivo py contiene su código más otras "vistas" para mi sitio ultra simple. (No sé cómo funciona realmente el pegamento, así que quizás por ahora el public_html esté allí para referencia, para que no me confunda cuando estoy cargando cosas en el servidor de producción).

Entonces, si pongo las hojas de estilo css en una carpeta llamada / static, entonces, si pongo / static como un subdirectorio de / app o de / public_html, encuentro que ninguna de las dos ubicaciones funciona; En su lugar, debo convertirlo en un subdirectorio de / proj.

No esperaba eso, pero la cura para mí es cambiar la ''estática'' predeterminada en tu llamada app.configure.get (..., ''static'') a ''public_html / app / static''. Luego funciona, con la carpeta / static dentro de / app.

Del mismo modo, el uso del código pipi con ''./app/static/ en lugar del'' estático ''predeterminado no funciona; Descubrí que necesito ./public_html/app/static en su lugar (o tal vez era solo / public_html / app / static o incluso public_html / app / static ... Olvidé ... uno de esos funcionó).

Probé cómo funciona tu cálculo de abs_path y lo he reelaborado en el siguiente código, en el cual he descartado tu enfoque a favor de algo más Djangoesque. A saber, en mi archivo de aplicación py puse en la parte superior lo siguiente:

STATIC_DIR = os.sep + ''tostatic'' + os.path.abspath(os.path.dirname(__file__)) + os.sep + ''static''

Luego, en la página a la que quiero agregar css, mi página de inicio en mi caso, puse un texto muy legible:

<link href="{{STATIC_DIR}}/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">

Para la "vista" que genera mi página de inicio, tengo (env es un objeto de entorno jinja2 que toma un cargador de plantillas como argumento):

class Home(webapp2.RequestHandler): def get(self): template = env.get_template(''index.html'') template_values = {''STATIC_DIR'': STATIC_DIR } self.response.write(template.render(template_values))

Y, finalmente, el enrutamiento de URL es como en:

app = webapp2.WSGIApplication( [ (r''/'', Home), (r''/tostatic/(.+)'', StaticView), ], debug=True)

La vista para la publicación de archivos estáticos ahora es:

class StaticView(webapp2.RequestHandler): def get(self, path): path = os.sep + path try: f = open(path, ''r'') self.response.headers.add_header(''Content-Type'', mimetypes.guess_type(path)[0]) self.response.out.write(f.read()) f.close() except Exception, e: print ''Problem in StaticView:'', e self.response.set_status(404)

Para cerrar finalmente, el problema que tenía con su enfoque es el que yo y otros noobs cercanos tenemos con la salida de las URL de la asociación heredada con el sistema de archivos. En su enfoque, "estático" es tanto un subdirectorio como una cadena entre barras en la parte frontal de la URL que le dice al intérprete qué vista (qué subclase webapp2.RequestHandler) ejecutar. Tomas el / static del resto de la URL y luego lo codificas de nuevo. Y cuando llega el momento de decidir qué poner para href en la etiqueta, el codificador de páginas HTML tiene que recordar esa duplicidad. Con el enfoque de {{STATIC_DIR}} variable de plantilla, queda claro qué hacer. Y es fácil redefinir la ubicación de los archivos estáticos --- solo se debe cambiar la declaración STATIC_DIR.

Descubrí que self.response.set_status (404) aparece en Firebug, pero no en Firefox. Evidentemente, con webapp2 debe proporcionar y publicar sus propias páginas de códigos de estado HTTP.



self.response.headers.add_header(''Content-Type'', mimetypes.guess_type(abs_path)[0]) self.response.headers[''Content-Type''] = mimetypes.guess_type(abs_path)[0]