Então isso é embaraçoso. Eu tenho um aplicativo que juntei Flask
e, por enquanto, ele está apenas exibindo uma única página HTML estática com alguns links para CSS e JS. E não consigo encontrar onde na documentação Flask
descreve o retorno de arquivos estáticos. Sim, eu poderia usar, render_template
mas sei que os dados não estão padronizados. Eu teria pensado send_file
ou url_for
era a coisa certa, mas não consegui fazê-los funcionar. Enquanto isso, estou abrindo os arquivos, lendo o conteúdo e criando um Response
tipo de mimet apropriado:
import os.path
from flask import Flask, Response
app = Flask(__name__)
app.config.from_object(__name__)
def root_dir(): # pragma: no cover
return os.path.abspath(os.path.dirname(__file__))
def get_file(filename): # pragma: no cover
try:
src = os.path.join(root_dir(), filename)
# Figure out how flask returns static files
# Tried:
# - render_template
# - send_file
# This should not be so non-obvious
return open(src).read()
except IOError as exc:
return str(exc)
@app.route('/', methods=['GET'])
def metrics(): # pragma: no cover
content = get_file('jenkins_analytics.html')
return Response(content, mimetype="text/html")
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_resource(path): # pragma: no cover
mimetypes = {
".css": "text/css",
".html": "text/html",
".js": "application/javascript",
}
complete_path = os.path.join(root_dir(), path)
ext = os.path.splitext(path)[1]
mimetype = mimetypes.get(ext, "text/html")
content = get_file(complete_path)
return Response(content, mimetype=mimetype)
if __name__ == '__main__': # pragma: no cover
app.run(port=80)
Alguém quer dar uma amostra de código ou URL para isso? Eu sei que isso vai ser muito simples.
python
flask
static-files
hughdbrown
fonte
fonte
Respostas:
O método preferido é usar o nginx ou outro servidor da web para servir arquivos estáticos; eles poderão fazer isso com mais eficiência do que o Flask.
No entanto, você pode usar
send_from_directory
para enviar arquivos de um diretório, o que pode ser bastante conveniente em algumas situações:Você não usar
send_file
ousend_static_file
com um caminho fornecido pelo usuário.send_static_file
exemplo:fonte
send_from_directory
foi projetado para resolver esse problema de segurança. Existe um erro de saída se o caminho levar para fora do diretório específico.<path>
é equivalente a<string:path>
, e porque você deseja que o Flask garanta um parâmetro semelhante ao caminho solicitado<path:path>
.Se você deseja apenas mover a localização dos seus arquivos estáticos, o método mais simples é declarar os caminhos no construtor. No exemplo abaixo, movi meus modelos e arquivos estáticos para uma subpasta chamada
web
.static_url_path=''
remove qualquer caminho anterior da URL (ou seja, o padrão/static
).static_folder='web/static'
para servir todos os arquivos encontrados na pastaweb/static
como arquivos estáticos.template_folder='web/templates'
Da mesma forma, isso altera a pasta de modelos.Usando esse método, a seguinte URL retornará um arquivo CSS:
E finalmente, aqui está uma amostra da estrutura da pasta, onde
flask_server.py
está a instância do Flask:fonte
get_static_file('index.html')
?Você também pode, e este é o meu favorito, definir uma pasta como caminho estático para que os arquivos contidos no site sejam acessíveis a todos.
Com esse conjunto, você pode usar o HTML padrão:
fonte
project/static/style.css
disponível.Tenho certeza de que você encontrará o que precisa lá: http://flask.pocoo.org/docs/quickstart/#static-files
Basicamente, você só precisa de uma pasta "estática" na raiz do seu pacote e, em seguida, pode usar
url_for('static', filename='foo.bar')
ou vincular diretamente seus arquivos em http://example.com/static/foo.bar .EDIT : conforme sugerido nos comentários, você pode usar diretamente o
'/static/foo.bar'
caminho do URL, mas aurl_for()
sobrecarga (desempenho) é bastante baixa e, usando isso, você poderá personalizar facilmente o comportamento posteriormente (alterar a pasta, alterar o caminho do URL, mova seus arquivos estáticos para S3, etc).fonte
'/static/foo.bar'
diretamente?Você pode usar esta função:
fonte
send_static_file
com a entrada do usuário. Não use esta solução em nada importante.O que eu uso (e está funcionando muito bem) é um diretório "templates" e um diretório "estático". Coloco todos os meus arquivos .html / modelos de balão dentro do diretório de modelos e estático contém CSS / JS. render_template funciona bem para arquivos html genéricos, que eu saiba, independentemente da extensão em que você usou a sintaxe de modelagem do Flask. Abaixo está um exemplo de chamada no meu arquivo views.py.
Apenas certifique-se de usar url_for () quando desejar fazer referência a algum arquivo estático no diretório estático separado. Você provavelmente acabará fazendo isso de qualquer maneira nos links de arquivos CSS / JS em html. Por exemplo...
Aqui está um link para o tutorial informal "canônico" do Flask - muitas ótimas dicas aqui para ajudá-lo a começar a correr.
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
fonte
Um exemplo de trabalho mais simples, com base nas outras respostas, é o seguinte:
Com o HTML chamado index.html :
IMPORTANTE: E index.html está em uma pasta chamada estática , o que significa que
<projectpath>
tem o.py
arquivo e<projectpath>\static
ohtml
arquivo.Se você deseja que o servidor fique visível na rede, use
app.run(debug=True, host='0.0.0.0')
EDIT: Para mostrar todos os arquivos na pasta, se solicitado, use este
Qual é essencialmente
BlackMamba
a resposta, então dê a eles um voto positivo.fonte
Para fluxo angular + padrão, que cria a próxima árvore de pastas:
Eu uso a seguinte solução:
Isso ajuda a redefinir a pasta 'estática' para personalizada.
fonte
Então, eu comecei a trabalhar (com base na resposta do @ user1671599) e queria compartilhá-lo com vocês.
(Espero estar fazendo certo, já que é meu primeiro aplicativo em Python)
Eu fiz isso -
Estrutura do projeto:
server.py:
AppStarter.py:
fonte
Uma das maneiras simples de fazer. Felicidades!
demo.py
Agora crie o nome da pasta chamada modelos . Adicione seu arquivo index.html dentro da pasta de modelos
index.html
Estrutura do Projeto
fonte
render_template
solução, mas não queria fazê-lo porque o arquivo era estático, sem substituições: "Sim, eu poderia usar render_template, mas sei que os dados não estão padronizados".Pensou em compartilhar .... este exemplo.
Isso funciona melhor e simples.
fonte
Use
redirect
eurl_for
Isso armazena todos os arquivos (css e js ...) mencionados no seu html.
fonte
A maneira mais simples é criar uma pasta estática dentro da pasta principal do projeto. Pasta estática contendo arquivos .css.
pasta principal
Imagem da pasta principal contendo pastas estáticas e de modelos e script de balão
frasco
html (layout)
html
fonte
Se você tiver modelos em seu diretório raiz, colocar o app = Flask ( nome ) funcionará se o arquivo que o contém também estiver no mesmo local, se esse arquivo estiver em outro local, será necessário especificar o local do modelo para ativar Balão para apontar para o local
fonte
Todas as respostas são boas, mas o que funcionou bem para mim é apenas usar a função simples
send_file
do Flask. Isso funciona bem quando você só precisa enviar um arquivo html como resposta quando o host: port / ApiName mostrará a saída do arquivo no navegadorfonte
Por padrão, o balão usa uma pasta "modelos" para conter todos os seus arquivos de modelo (qualquer arquivo de texto sem formatação, mas geralmente
.html
ou algum tipo de linguagem de modelo como jinja2) e uma pasta "estática" para conter todos os seus arquivos estáticos (por exemplo,.js
.css
e suas imagens).No seu
routes
, você pode usarrender_template()
para renderizar um arquivo de modelo (como eu disse acima, por padrão, ele é colocado natemplates
pasta) como resposta para sua solicitação. E no arquivo de modelo (geralmente é um arquivo .html), você pode usar alguns.js
arquivos e / ou `.css ', então acho que sua pergunta é como vincular esses arquivos estáticos ao arquivo de modelo atual.fonte
Se você está apenas tentando abrir um arquivo, você pode usar
app.open_resource()
. Portanto, ler um arquivo seria algo comofonte