Оболочка Flask и различное поведение маршрутаPython

Программы на Python
Anonymous
Оболочка Flask и различное поведение маршрута

Сообщение Anonymous »

В моем приложении Flask оболочка использует другой код, чем маршруты. Как это возможно? У меня были проблемы с разрешением DNS при использовании flask-mail и docker, поэтому я запустил один и тот же код как в оболочке, так и в маршруте. Оболочка работала без проблем, но маршрут вернул ошибку, которая, по-видимому, связана с этой проблемой GitHub. Когда обезьянье исправление связано с ошибками оболочки, оно работает нормально, когда нет. Ошибки маршрута, несмотря ни на что.
У меня возникают другие проблемы с различным поведением оболочки и маршрутов в отношении ссылок на имена контейнеров, но странно видеть различное поведение между оболочкой и маршрутами в другом аспект приложения.
оболочка Flask
>>> import dns.resolver
>>> answers = dns.resolver.resolve('google.com', 'A')
>>> answers.canonical_name

маршрут
@production.route('/test_dns', methods=['GET'])
@login_required
def test_dns():
import dns.resolver
answers = dns.resolver.resolve('google.com', 'A')
print(f'{answers.canonical_name}')

return ''

ошибка маршрута
web_1 | [2024-08-01 16:28:16 +0000] [10] [ERROR] Error handling request /production/test_dns
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base_async.py", line 55, in handle
web_1 | self.handle_request(listener_name, req, client, addr)
web_1 | File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base_async.py", line 108, in handle_request
web_1 | respiter = self.wsgi(environ, resp.start_response)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 1478, in __call__
web_1 | return self.wsgi_app(environ, start_response)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 1458, in wsgi_app
web_1 | response = self.handle_exception(e)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 1455, in wsgi_app
web_1 | response = self.full_dispatch_request()
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 869, in full_dispatch_request
web_1 | rv = self.handle_user_exception(e)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 867, in full_dispatch_request
web_1 | rv = self.dispatch_request()
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 852, in dispatch_request
web_1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask_login/utils.py", line 290, in decorated_view
web_1 | return current_app.ensure_sync(func)(*args, **kwargs)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/app/web/production/views.py", line 67, in test_dns
web_1 | answers = dns.resolver.resolve('google.com', 'A')
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1565, in resolve
web_1 | return get_default_resolver().resolve(
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1321, in resolve
web_1 | timeout = self._compute_timeout(start, lifetime, resolution.errors)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1075, in _compute_timeout
web_1 | raise LifetimeTimeout(timeout=duration, errors=errors)
web_1 | dns.resolver.LifetimeTimeout: The resolution lifetime expired after 5.106 seconds: Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'


Минимально воспроизводимый пример
.
├── docker/
│ └── Dockerfile
├── app.py
├── docker-compose.yml
└── requirements.txt

docker-compose.yml
services:
web:
build:
context: .
dockerfile: ./docker/Dockerfile
command: gunicorn --worker-class eventlet --timeout 120 -w 6 -b 0.0.0.0:5000 app:app
# command: flask run --host=0.0.0.0 --port=5000
volumes:
- .:/app
ports:
- '5000:5000'
environment:
- FLASK_APP=app

requirements.txt
eventlet==0.34.2
Flask==3.0.0
gunicorn==21.2.0

docker/Dockerfile/
FROM python:3.12.4-bookworm

# making python prints go to stdout
ENV PYTHONUNBUFFERED 1

# don't write .pyc files
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
&& apt-get install -y build-essential \
&& apt-get install -y gunicorn python3-gunicorn \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*

COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

WORKDIR /app

app.py
from flask import Flask

app = Flask(__name__, static_folder='app', static_url_path="/app")

@app.route("/test_dns")
def test_dns():
import dns.resolver
answers = dns.resolver.resolve('google.com', 'A')
print(f'{answers.canonical_name}')

return ''

В этом минимальном примере маршрут выдает ошибку только тогда, когда вместо команды: Gunicorn --worker-class eventlet --timeout 120 -w 6 -b 0.0.0.0:5000 app:app используется команда: flask run --host=0.0.0.0 --port=5000.
Ошибка:
web_1 | [2024-08-02 18:00:34 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
web_1 | [2024-08-02 18:00:34 +0000] [1] [INFO] Using worker: eventlet
web_1 | [2024-08-02 18:00:34 +0000] [7] [INFO] Booting worker with pid: 7
web_1 | [2024-08-02 18:00:34 +0000] [8] [INFO] Booting worker with pid: 8
web_1 | [2024-08-02 18:00:34 +0000] [9] [INFO] Booting worker with pid: 9
web_1 | [2024-08-02 18:00:34 +0000] [10] [INFO] Booting worker with pid: 10
web_1 | [2024-08-02 18:00:34 +0000] [11] [INFO] Booting worker with pid: 11
web_1 | [2024-08-02 18:00:34 +0000] [12] [INFO] Booting worker with pid: 12
web_1 | [2024-08-02 18:01:11,183] ERROR in app: Exception on /test_dns [GET]
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 1455, in wsgi_app
web_1 | response = self.full_dispatch_request()
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 869, in full_dispatch_request
web_1 | rv = self.handle_user_exception(e)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 867, in full_dispatch_request
web_1 | rv = self.dispatch_request()
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 852, in dispatch_request
web_1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/app/app.py", line 9, in test_dns
web_1 | answers = dns.resolver.resolve('google.com', 'A')
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1565, in resolve
web_1 | return get_default_resolver().resolve(
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1321, in resolve
web_1 | timeout = self._compute_timeout(start, lifetime, resolution.errors)
web_1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web_1 | File "/usr/local/lib/python3.12/site-packages/dns/resolver.py", line 1075, in _compute_timeout
web_1 | raise LifetimeTimeout(timeout=duration, errors=errors)
web_1 | dns.resolver.LifetimeTimeout: The resolution lifetime expired after 5.106 seconds: Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'; Server Do53:127.0.0.11@53 answered udp() got an unexpected keyword argument 'ignore_errors'

заморозка семян внутри контейнера
blinker==1.8.2
click==8.1.7
dnspython==2.6.1
eventlet==0.34.2
Flask==3.0.0
greenlet==3.0.3
gunicorn==21.2.0
itsdangerous==2.2.0
Jinja2==3.1.4
MarkupSafe==2.1.5
packaging==24.1
setuptools==71.1.0
six==1.16.0
Werkzeug==3.0.3
wheel==0.43.0


Подробнее здесь: https://stackoverflow.com/questions/788 ... g-behavior

Вернуться в «Python»