Pergunta

Existe alguma solução inteligente para armazenar arquivos estáticos no diretório raiz do aplicativo do Flask. Espera -se que robots.txt e sitemap.xml sejam encontrados em /, então minha idéia era criar rotas para eles:

@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
  response = make_response(open('sitemap.xml').read())
  response.headers["Content-type"] = "text/plain"
  return response

Deve haver algo mais conveniente :)

Foi útil?

Solução

A melhor maneira é definir static_url_path para root URL

from flask import Flask

app = Flask(__name__, static_folder='static', static_url_path='')

Outras dicas

@vonpetrushev está certo, na produção, você deseja servir arquivos estáticos via nginx ou apache, mas para o desenvolvimento é bom ter seu ambiente de desenvolvimento simples ter seu aplicativo python servindo o conteúdo estático também, para que você não precise se preocupar sobre a mudança de configurações e vários projetos. Para fazer isso, você vai querer usar o SharedDatamiddleware.

from flask import Flask
app = Flask(__name__)
'''
Your app setup and code
'''
if app.config['DEBUG']:
    from werkzeug import SharedDataMiddleware
    import os
    app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
      '/': os.path.join(os.path.dirname(__file__), 'static')
    })

Este exemplo pressupõe que seus arquivos estáticos estejam na pasta "estática", ajuste -se ao que se encaixa no seu ambiente.

A resposta mais limpa para esta pergunta é o responda Para isso (idêntico) pergunta:

from flask import Flask, request, send_from_directory
app = Flask(__name__, static_folder='static')    

@app.route('/robots.txt')
@app.route('/sitemap.xml')
def static_from_root():
    return send_from_directory(app.static_folder, request.path[1:])

Para resumir:

  • Como David apontou, com a configuração certa, é ok para servir alguns arquivos estáticos através do Prod
  • Procurar /robots.txt não deve resultar em um redirecionamento para /static/robots.txt. (Em Seans, responde, não está imediatamente claro como isso é alcançado.)
  • Não está limpo para adicionar arquivos estáticos na pasta de raiz do aplicativo
  • Finalmente, a solução proposta parece muito mais limpa do que a abordagem de middleware adicionada:

Embora seja uma pergunta antiga respondida, estou respondendo a isso porque esta postagem é bastante alta nos resultados do Google. Embora não esteja coberto na documentação, se você ler os documentos da API Para o construtor de objeto de aplicação do Flask, ele está coberto. Passando o parâmetro nomeado static_folder igual a:

from flask import Flask
app = Flask(__name__,
            static_folder="/path/to/static",
            template_folder="/path/to/templates")

... Você pode definir de onde são servidos arquivos estáticos. Da mesma forma, você pode definir um template_folder, o nome de você static_url_path.

Servir arquivos estáticos não tem nada a ver com o aplicativo destinado a fornecer conteúdo dinâmico. A maneira correta de servir arquivos estáticos depende do servidor que você está usando. Afinal, quando você colocar seu aplicativo em funcionamento, precisará vinculá -lo a um servidor da Web. Eu posso falar apenas para o Apache HTTPD, portanto, a maneira de servir arquivos estáticos é definida no host virtual que você está vinculando ao seu aplicativo através do MOD-WSGI. Aqui está o guia que mostrará como servir sitemaps, robots.txt ou qualquer conteúdo estático:http://code.google.com/p/modwsgi/wiki/quickconfigurationguide#mcing_at_root_of_site

Outra maneira de enviar arquivos estáticos é usar uma regra de captura como esta:

@app.route('/<path:path>')
def catch_all(path):
    if not app.debug:
        flask.abort(404)
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    return f.read()

Eu uso isso para tentar minimizar a configuração ao desenvolver. Eu tive a ideia de http://flask.pocoo.org/snippets/57/

Além disso, estou desenvolvendo usando o frasco na minha máquina independente, mas implantando com o Apache no servidor de produção. Eu uso:

file_suffix_to_mimetype = {
    '.css': 'text/css',
    '.jpg': 'image/jpeg',
    '.html': 'text/html',
    '.ico': 'image/x-icon',
    '.png': 'image/png',
    '.js': 'application/javascript'
}
def static_file(path):
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    root, ext = os.path.splitext(path)
    if ext in file_suffix_to_mimetype:
        return flask.Response(f.read(), mimetype=file_suffix_to_mimetype[ext])
    return f.read()

[...]

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-d', '--debug', dest='debug', default=False,
                      help='turn on Flask debugging', action='store_true')

    options, args = parser.parse_args()

    if options.debug:
        app.debug = True
        # set up flask to serve static content
        app.add_url_rule('/<path:path>', 'static_file', static_file)
    app.run()

Isso poderia ter sido adicionado desde que essa pergunta foi feita, mas eu estava olhando através do "helphers.py" de Flask e encontrei Flask.send_from_directory:

send_from_directory(directory, filename, **options)
'''
  send_from_directory(directory, filename, **options)
  Send a file from a given directory with send_file.  This
  is a secure way to quickly expose static files from an upload folder
  or something similar.
'''

... que referências Flask.send_file:

send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False)

... o que parece melhor para mais controle, embora send_from_directory passe ** opções diretamente para send_file.

Da documentação aqui: http://flask.pocoo.org/docs/quickstart/#static-files

Os aplicativos dinâmicos da Web também precisam de arquivos estáticos. Geralmente, é de onde vêm os arquivos CSS e JavaScript. Idealmente, seu servidor da Web está configurado para atendê -los para você, mas durante o frasco de desenvolvimento também pode fazer isso. Basta criar uma pasta chamada estática no seu pacote ou ao lado do seu módulo e ela estará disponível no /estático no aplicativo.

Para gerar URLs para essa parte do URL, use o nome de URL "estático" especial:

url_for ('static', nome do arquivo = 'style.css')

O arquivo deve ser armazenado no sistema de arquivos como estático/style.css.

Estou tendo o mesmo dilema também. Fiz algumas pesquisas e encontrei minha resposta (MHO):

Pode muito bem citar a documentação

Os aplicativos dinâmicos da Web também precisam de arquivos estáticos. Geralmente, é de onde vêm os arquivos CSS e JavaScript. Idealmente, seu servidor da web está configurado para servi -los para você, mas durante o frasco de desenvolvimento também pode fazer isso. Basta criar uma pasta chamada estática no seu pacote ou ao lado do seu módulo e ela estará disponível no /estático no aplicativo.

IMHO: Quando seu aplicativo está pronto para Produção, a porção de arquivo estático deve ser (ou idealmente) configurada no servidor da web (nginx, Apache); mas durante desenvolvimento, Flask disponibilizou -o para servir arquivos estáticos. Isso é para ajudá -lo a se desenvolver rapidamente - não há necessidade de configurar servidores da web e tal.

Espero que ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top