A resposta depende de como você está atendendo a este aplicativo.
Submontado dentro de outro contêiner WSGI
Supondo que você irá executar este aplicativo dentro de um contêiner WSGI (mod_wsgi, uwsgi, gunicorn, etc); você precisa realmente montar, nesse prefixo, o aplicativo como uma subparte desse contêiner WSGI (qualquer coisa que fale WSGI servirá) e definir seu APPLICATION_ROOT
valor de configuração para o seu prefixo:
app.config["APPLICATION_ROOT"] = "/abc/123"
@app.route("/")
def index():
return "The URL for this page is {}".format(url_for("index"))
# Will return "The URL for this page is /abc/123/"
Definir o APPLICATION_ROOT
valor de configuração simplesmente limita o cookie de sessão do Flask a esse prefixo de URL. Todo o resto será tratado automaticamente para você pelos excelentes recursos de manipulação de WSGI do Flask e Werkzeug.
Um exemplo de submontagem adequada do seu aplicativo
Se você não tiver certeza do que o primeiro parágrafo significa, dê uma olhada neste aplicativo de exemplo com o Flask montado dentro dele:
from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/abc/123'
@app.route('/')
def index():
return 'The URL for this page is {}'.format(url_for('index'))
def simple(env, resp):
resp(b'200 OK', [(b'Content-Type', b'text/plain')])
return [b'Hello WSGI World']
app.wsgi_app = DispatcherMiddleware(simple, {'/abc/123': app.wsgi_app})
if __name__ == '__main__':
app.run('localhost', 5000)
Solicitações de proxy para o aplicativo
Se, por outro lado, você for executar seu aplicativo Flask na raiz de seu contêiner WSGI e fazer proxy de solicitações para ele (por exemplo, se estiver sendo FastCGI, ou se nginx estiver proxy_pass
enviando solicitações para um subendpoint para seu servidor uwsgi
/ autônomo, gevent
então você pode:
- Use um Blueprint, como Miguel aponta em sua resposta .
- ou usar a
DispatcherMiddleware
partir de werkzeug
(ou a PrefixMiddleware
partir de resposta das Su27 ) para sub-montagem de sua aplicação no servidor WSGI stand-alone você está usando. (Veja um exemplo de submontagem adequada de seu aplicativo acima para o código a ser usado).
flask.Flask#create_url_adapter
ewerkzeug.routing.Map#bind_to_environ
parece que deve funcionar - como você estava executando o código? (O aplicativo realmente precisa ser montado no subcaminho em um ambiente WSGI paraurl_for
retornar o valor esperado.)DispatcherMiddleware
abordagem, ao executar o frasco sozinho. Não consigo fazer isso funcionar ao correr atrás de Gunicorn.uwsgi -s /tmp/yourapplication.sock --manage-script-name --mount /yourapplication=myapp:app
. detalhes consulte (documento uwsgi) [ flask.pocoo.org/docs/1.0/deploying/uwsgi/]Você pode colocar suas rotas em um plano:
Em seguida, você registra o blueprint com o aplicativo usando um prefixo:
fonte
app.register_blueprint
e entre registrá-lo ao instanciar o objeto Blueprint acima, passandourl_prefix='/abc/123
? Obrigado!register_blueprint
chamada dá ao aplicativo a liberdade de "montar" o blueprint em qualquer lugar que desejar, ou até mesmo montar o mesmo blueprint várias vezes em URLs diferentes. Se você colocar o prefixo no próprio blueprint, ficará mais fácil para o aplicativo, mas terá menos flexibilidade.Você deve observar que
APPLICATION_ROOT
NÃO é para essa finalidade.Tudo que você precisa fazer é escrever um middleware para fazer as seguintes alterações:
PATH_INFO
para lidar com o url prefixado.SCRIPT_NAME
para gerar o url prefixado.Como isso:
Envolva seu aplicativo com o middleware, assim:
Visita
http://localhost:9010/foo/bar
,Você obterá o resultado certo:
The URL for this page is /foo/bar
E não se esqueça de definir o domínio do cookie, se necessário.
Esta solução é dada pela essência do Larivact . O
APPLICATION_ROOT
não é para este trabalho, embora pareça ser. É muito confuso.fonte
APPLICATION_ROOT
é para este trabalho" - é aí que eu estava errado.Blueprint
Ourl_prefix
parâmetro de desejo eAPPLICATION_ROOT
foram combinados por padrão, para que eu pudesse terAPPLICATION_ROOT
urls de escopo para o aplicativo inteiro eurl_prefix
urls de escopoAPPLICATION_ROOT
apenas para o blueprint individual. SighAPPLICATION_ROOT
.__call__
método:response = Response('That url is not correct for this application', status=404) return response(environ, start_response)
usingfrom werkzeug.wrappers import BaseResponse as Response
Esta é mais uma resposta python do que uma resposta Flask / werkzeug; mas é simples e funciona.
Se, como eu, você deseja que as configurações do seu aplicativo (carregadas de um
.ini
arquivo) também contenham o prefixo do seu aplicativo Flask (portanto, não ter o valor definido durante a implantação, mas durante o tempo de execução), você pode optar pelo seguinte:Indiscutivelmente, isso é um tanto hackeado e se baseia no fato de que a função de rota do Flask requer a
route
como primeiro argumento posicional.Você pode usá-lo assim:
NB: Não vale a pena que seja possível usar uma variável no prefixo (por exemplo, definindo-o como
/<prefix>
), e depois processar esse prefixo nas funções que você decorar com o seu@app.route(...)
. Se você fizer isso, obviamente terá que declarar oprefix
parâmetro em sua (s) função (ões) decorada (s). Além disso, você pode querer verificar o prefixo enviado em relação a algumas regras e retornar um 404 se a verificação falhar. A fim de evitar uma reimplementação 404 customizada, por favorfrom werkzeug.exceptions import NotFound
,raise NotFound()
se a verificação falhar.fonte
Blueprint
. Obrigado por compartilhar!Portanto, acredito que uma resposta válida para isso é: o prefixo deve ser configurado no aplicativo de servidor real que você usa quando o desenvolvimento é concluído. Apache, nginx, etc.
No entanto, se você quiser que isso funcione durante o desenvolvimento enquanto executa o aplicativo Flask na depuração, dê uma olhada nesta essência .
O frasco está
DispatcherMiddleware
para o resgate!Vou copiar o código aqui para a posteridade:
Agora, ao executar o código acima como um aplicativo Flask autônomo,
http://localhost:5000/spam/
será exibidoHello, world!
.Em um comentário sobre outra resposta, expressei que gostaria de fazer algo assim:
Aplicando
DispatcherMiddleware
ao meu exemplo inventado:fonte
Outra maneira completamente diferente é com pontos de montagem em
uwsgi
.Do documento sobre hospedagem de vários aplicativos no mesmo processo ( link permanente ).
No seu
uwsgi.ini
você adicionaSe você não chamar seu arquivo
main.py
, será necessário alterar omount
e omodule
Você
main.py
poderia ter esta aparência:E uma configuração nginx (novamente para integridade):
Agora, a chamada
example.com/foo/bar
será exibida/foo/bar
conforme retornada por flask'surl_for('bar')
, pois se adapta automaticamente. Dessa forma, seus links funcionarão sem problemas de prefixo.fonte
fonte
Eu precisava de algo semelhante, chamado de "raiz de contexto". Fiz isso no arquivo conf em /etc/httpd/conf.d/ usando WSGIScriptAlias:
myapp.conf:
Agora posso acessar meu aplicativo como: http: // localhost: 5000 / myapp
Consulte o guia - http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
fonte
Minha solução em que aplicativos flask e PHP coexistem nginx e PHP5.6
MANTER Flask na raiz e PHP nos subdiretórios
Adicionar 1 linha
USE LOCALIZAÇÕES ANINHADAS para PHP e deixe FLASK permanecer na raiz
LEIA com atenção https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
Precisamos entender a correspondência de localização (nenhuma): Se nenhum modificador estiver presente, a localização é interpretada como uma correspondência de prefixo. Isso significa que o local fornecido será comparado ao início do URI de solicitação para determinar uma correspondência. =: Se um sinal de igual for usado, este bloco será considerado uma correspondência se o URI de solicitação corresponder exatamente ao local fornecido. ~: Se um modificador de til estiver presente, este local será interpretado como uma correspondência de expressão regular que diferencia maiúsculas de minúsculas. ~ *: Se um modificador de til e asterisco for usado, o bloco de localização será interpretado como uma correspondência de expressão regular que não diferencia maiúsculas de minúsculas. ^ ~: Se um modificador de caractere e til estiver presente, e se este bloco for selecionado como a melhor correspondência de expressão não regular, a correspondência de expressão regular não ocorrerá.
A ordem é importante, a partir da descrição de "localização" do nginx:
Para encontrar o local que corresponde a uma determinada solicitação, o nginx primeiro verifica os locais definidos usando as sequências de prefixo (locais de prefixo). Entre eles, o local com o prefixo correspondente mais longo é selecionado e lembrado. Em seguida, as expressões regulares são verificadas, na ordem em que aparecem no arquivo de configuração. A pesquisa de expressões regulares termina na primeira correspondência e a configuração correspondente é usada. Se nenhuma correspondência com uma expressão regular for encontrada, a configuração da localização do prefixo lembrada anteriormente é usada.
Isso significa:
fonte
Para as pessoas que ainda lutam com isso, o primeiro exemplo funciona, mas o exemplo completo está aqui se você tiver um aplicativo Flask que não está sob seu controle:
fonte