无法启动 flask +连接器+ Swagger

sauutmhj  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(47)

问题

我启动了一个Flask应用程序(+ Connexion和Swagger UI),并试图打开http://127.0.0.1:5000/api/ui。浏览器显示starlette.exceptions.HTTPException: 404: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

设置

% pip install "connexion[flask, swagger-ui]"
% export FLASK_APP="app"
    (Prepare files)
% flask run --debug
    (Access http://127.0.0.1:5000/api/ui)

字符串
结果

  • Python 3.12.0
  • 连接器3.0.2
  • Flask 3.0.0
  • swagger_ui_bundle 1.1.0
  • Werkzeug 3.0.1

文件

目录结构

app/
    __init__.py
    openapi.yaml
    hello.py


__init__.py

from connexion import FlaskApp
from flask.app import Flask
from pathlib import Path

BASE_DIR = Path(__file__).parent.resolve()

def create_app() -> Flask:
    flask_app: FlaskApp = FlaskApp(__name__)
    app: Flask = flask_app.app

    flask_app.add_api("openapi.yaml")
    return app


openapi.yaml

openapi: 3.0.3
info:
  title: "test"
  description: "test"
  version: "1.0.0"

servers:
  - url: "/api"

paths:
  /hello:
    get:
      summary: "hello"
      description: "hello"
      operationId: "hello.say_hello"
      responses:
        200:
          description: "OK"
          content:
            text/plain:
              schema:
                type: string
                example: "hello"


hello.py

def say_hello() -> str:
    return 'Hello, world!'

错误信息

基于这些设置,我相信我可以在http://127.0.0.1:5000/api/ui上看到Swagger UI。然而,我遇到了下面的错误消息。

Traceback (most recent call last):
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 867, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 841, in dispatch_request
    self.raise_routing_exception(req)
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 450, in raise_routing_exception
    raise request.routing_exception  # type: ignore
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/ctx.py", line 353, in match_request
    result = self.url_adapter.match(return_rule=True)  # type: ignore
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/werkzeug/routing/map.py", line 624, in match
    raise NotFound() from None
werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 1478, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 1458, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 1455, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 869, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/flask/app.py", line 759, in handle_user_exception
    return self.ensure_sync(handler)(e)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/myusername/tmp/.venv/lib/python3.12/site-packages/connexion/apps/flask.py", line 245, in _http_exception
    raise starlette.exceptions.HTTPException(exc.code, detail=exc.description)
starlette.exceptions.HTTPException: 404: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

jv4diomz

jv4diomz1#

TL:DR:您需要一个ASGI服务器来运行应用程序。
在connectorx 1 e0f1x上也有类似的问题。
这只会引导你到运行你的应用程序的文档,可以在这里找到。
考虑到上述情况,我设法创建了自己的解决方案:
__init__.py

from connexion import FlaskApp

def create_app():
    app = FlaskApp(__name__)
    app.add_api("openapi.yaml", validate_responses=True)
    return app

app = create_app()

字符串
openapi.yaml

openapi: 3.0.3
info:
  title: test
  description: test
  version: 1.0.0

paths:
  /hello:
    get:
      summary: hello
      description: hello
      operationId: app.hello.say_hello
      responses:
        200:
          description: OK
          content:
            text/plain:
              schema:
                type: string
                example: hello


有关其他帮助,请参阅下面我使用的Docker设置:
docker-compose.yaml

version: '3.8'

services:
  test-api:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - '8000:8000'
    volumes:
      - ./app:/usr/src/app/app


Dockerfile

FROM public.ecr.aws/lambda/python:3.10

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app/

RUN pip3 install --no-cache-dir -r requirements.txt

ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_RUN_PORT=8000

EXPOSE 8000

COPY entrypoint.sh /usr/src/app/entrypoint.sh
RUN chmod +x /usr/src/app/entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]


entrypoint.sh

#!/bin/sh

gunicorn -w 1 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app --reload

# Keep the script running to keep the container alive
tail -f /dev/null


requirements.txt

connexion[flask, swagger-ui, uvicorn]==3.0.2
gunicorn==21.2.0
Werkzeug==3.0.1
Flask==3.0.0
setuptools >= 21.0.0
swagger-ui-bundle==1.1.0


项目结构:

project-root/
|-- app/
|   |-- __init__.py
|   |-- hello.py
|   |-- openapi.yaml
|-- Dockerfile
|-- docker-compose.yml
|-- entrypoint.sh
|-- requirements.txt
|-- .env


希望这对你有帮助!我建议从这个工作点开始使用特定的设置,例如CORS,数据库设置,迁移,修改Docker设置等。

相关问题