Giter Site home page Giter Site logo

automationpanda / bulldoggy-reminders-app Goto Github PK

View Code? Open in Web Editor NEW
218.0 6.0 33.0 2.3 MB

A demo web app for reminders built in Python using FastAPI and HTMX

License: MIT License

Python 75.08% HTML 15.82% CSS 8.19% Dockerfile 0.91%
python css fastapi html htmx jinja pydantic playwright pytest requests

bulldoggy-reminders-app's Introduction

Bulldoggy Logo

Bulldoggy: The Reminders App

Bulldoggy is a small demo web app for tracking reminders. It uses:

Learning how it works

Development and testing are two sides of the same coin:

  1. To learn how to develop the Bulldoggy app, watch my PyTexas 2023 keynote, Full-Stack Python.
  2. To learn how to test the Bulldoggy app, watch my DjangoCon US 2023 keynote, Testing Modern Web Apps Like A Champion.

These two keynotes are bookends for each other.

Installing dependencies

You will need a recent version of Python to run this app. To install project dependencies:

pip install -r requirements.txt

It is recommended to install dependencies into a virtual environment.

Running the app

To run the app:

uvicorn app.main:app --reload

Then, open your browser to http://127.0.0.1:8000 to load the app.

Running the app with Docker

Build the image with:

docker build -t bulldoggy-reminders-app:0.1 .

To run the image:

docker run -it --rm --name bulldoggy-reminders-app -p 8000:8000 bulldoggy-reminders-app:0.1

Logging into the app

The config.json file declares the users for the app. You may use any configured user credentials, or change them to your liking. The "default" username is pythonista with the password I<3testing.

Setting the database path

The app uses TinyDB, which stores the database as a JSON file. The default database filepath is reminder_db.json. You may change this path in config.json. If you change the filepath, the app will automatically create a new, empty database.

Using the app

Bulldoggy is a reminders app. After you log in, you can create reminder lists.

Bulldoggy login

Each reminder list appears on the left, and the items in the list appear on the right. You may add, delete, or edit lists and items. You may also strike out completed items.

Bulldoggy reminders

Reading the docs

To read the API docs, open the following pages:

  • /docs for classic OpenAPI docs
  • /redoc for more modern ReDoc docs

Why did I build this app in Python?

Personally, I love Python, and I wanted to demonstrate how to build a full-stack modern web app entirely with Python.

JavaScript essentially has a near-monopoly on front-end web development. Browsers require JavaScript code to perform dynamic web page interactions. However, HTMX offers a novel way to sidestep this limitation: it provides special HTML attributes to denote dynamic interactions for elements. Under the hood, HTMX uses AJAX to issue HTTP requests and swap hypertext contents for elements targetted with its special attributes. JavaScript is still there – you just don't need to touch it!

This enables web frameworks in languages like Python, Go, Java, and others to offer dynamic web page content directly in HTML without requiring developers to explicitly code any JavaScript. HTMX empowers you, as a developer, to build beautiful web apps while remaining in the tech stack of your choice!

To learn more about this app's design, please watch my PyTexas 2023 keynote, Full-Stack Python.

Credits

TODO list

  • Automate API tests
  • Automate UI tests
  • Automate unit tests

bulldoggy-reminders-app's People

Contributors

automationpanda avatar vikmaksymenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

bulldoggy-reminders-app's Issues

Install error

I created a venv and tried to install the dependencies. Debian 12.

And got this error:

  Running setup.py install for greenlet ... error
  error: subprocess-exited-with-error
  
  × Running setup.py install for greenlet did not run successfully.
  │ exit code: 1
  ╰─> [266 lines of output]
      running install
      /home/siena/git/my/htmx/fastapi-todo/.venv/lib/python3.11/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-cpython-311
      creating build/lib.linux-x86_64-cpython-311/greenlet
      copying src/greenlet/__init__.py -> build/lib.linux-x86_64-cpython-311/greenlet
      creating build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_gc.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_version.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_stack_saved.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_generator.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_weakref.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_leaks.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_greenlet.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_extension_interface.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_contextvars.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_cpp.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_throw.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_tracing.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/__init__.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/test_generator_nested.py -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      running egg_info
      writing src/greenlet.egg-info/PKG-INFO
      writing dependency_links to src/greenlet.egg-info/dependency_links.txt
      writing requirements to src/greenlet.egg-info/requires.txt
      writing top-level names to src/greenlet.egg-info/top_level.txt
      reading manifest file 'src/greenlet.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      no previously-included directories found matching 'docs/_build'
      warning: no files found matching '*.py' under directory 'appveyor'
      warning: no previously-included files matching '*.pyc' found anywhere in distribution
      warning: no previously-included files matching '*.pyd' found anywhere in distribution
      warning: no previously-included files matching '*.so' found anywhere in distribution
      warning: no previously-included files matching '.coverage' found anywhere in distribution
      adding license file 'LICENSE'
      adding license file 'LICENSE.PSF'
      adding license file 'AUTHORS'
      writing manifest file 'src/greenlet.egg-info/SOURCES.txt'
      /home/siena/git/my/htmx/fastapi-todo/.venv/lib/python3.11/site-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning:     Installing 'greenlet.platform' as data is deprecated, please list it in `packages`.
          !!
      
      
          ############################
          # Package would be ignored #
          ############################
          Python recognizes 'greenlet.platform' as an importable package,
          but it is not listed in the `packages` configuration of setuptools.
      
          'greenlet.platform' has been automatically added to the distribution only
          because it may contain data files, but this behavior is likely to change
          in future versions of setuptools (and therefore is considered deprecated).
      
          Please make sure that 'greenlet.platform' is included as a package by using
          the `packages` configuration field or the proper discovery methods
          (for example by using `find_namespace_packages(...)`/`find_namespace:`
          instead of `find_packages(...)`/`find:`).
      
          You can read more about "package discovery" and "data files" on setuptools
          documentation page.
      
      
      !!
      
        check.warn(importable)
      copying src/greenlet/greenlet.c -> build/lib.linux-x86_64-cpython-311/greenlet
      copying src/greenlet/greenlet.h -> build/lib.linux-x86_64-cpython-311/greenlet
      copying src/greenlet/slp_platformselect.h -> build/lib.linux-x86_64-cpython-311/greenlet
      creating build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/setup_switch_x64_masm.cmd -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_aarch64_gcc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_alpha_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_amd64_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_arm32_gcc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_arm32_ios.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_csky_gcc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_m68k_gcc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_mips_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc64_aix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc64_linux.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc_aix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc_linux.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc_macosx.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_ppc_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_riscv_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_s390_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_sparc_sun_gcc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x32_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x64_masm.asm -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x64_masm.obj -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x64_msvc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x86_msvc.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/platform/switch_x86_unix.h -> build/lib.linux-x86_64-cpython-311/greenlet/platform
      copying src/greenlet/tests/_test_extension.c -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      copying src/greenlet/tests/_test_extension_cpp.cpp -> build/lib.linux-x86_64-cpython-311/greenlet/tests
      running build_ext
      building 'greenlet._greenlet' extension
      creating build/temp.linux-x86_64-cpython-311
      creating build/temp.linux-x86_64-cpython-311/src
      creating build/temp.linux-x86_64-cpython-311/src/greenlet
      x86_64-linux-gnu-gcc -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -I/home/siena/git/my/htmx/fastapi-todo/.venv/include -I/usr/include/python3.11 -c src/greenlet/greenlet.c -o build/temp.linux-x86_64-cpython-311/src/greenlet/greenlet.o
      In file included from src/greenlet/greenlet.c:11:
      src/greenlet/greenlet.h:42:5: error: unknown type name ‘CFrame’
         42 |     CFrame* cframe;
            |     ^~~~~~
      src/greenlet/greenlet.c: In function ‘green_clear_exc’:
      src/greenlet/greenlet.c:168:17: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
        168 |     g->exc_state.exc_type = NULL;
            |                 ^
      src/greenlet/greenlet.c:170:17: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
        170 |     g->exc_state.exc_traceback = NULL;
            |                 ^
      src/greenlet/greenlet.c: In function ‘g_switchstack’:
      src/greenlet/greenlet.c:508:44: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘recursion_depth’; did you mean ‘recursion_limit’?
        508 |         current->recursion_depth = tstate->recursion_depth;
            |                                            ^~~~~~~~~~~~~~~
            |                                            recursion_limit
      src/greenlet/greenlet.c:509:38: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘frame’; did you mean ‘cframe’?
        509 |         current->top_frame = tstate->frame;
            |                                      ^~~~~
            |                                      cframe
      src/greenlet/greenlet.c:522:25: warning: assignment to ‘int *’ from incompatible pointer type ‘_PyCFrame *’ [-Wincompatible-pointer-types]
        522 |         current->cframe = tstate->cframe;
            |                         ^
      src/greenlet/greenlet.c:544:17: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘recursion_depth’; did you mean ‘recursion_limit’?
        544 |         tstate->recursion_depth = target->recursion_depth;
            |                 ^~~~~~~~~~~~~~~
            |                 recursion_limit
      src/greenlet/greenlet.c:545:17: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘frame’; did you mean ‘cframe’?
        545 |         tstate->frame = target->top_frame;
            |                 ^~~~~
            |                 cframe
      src/greenlet/greenlet.c:568:24: warning: assignment to ‘_PyCFrame *’ from incompatible pointer type ‘int *’ [-Wincompatible-pointer-types]
        568 |         tstate->cframe = target->cframe;
            |                        ^
      src/greenlet/greenlet.c: In function ‘g_initialstub’:
      src/greenlet/greenlet.c:821:50: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘recursion_depth’; did you mean ‘recursion_limit’?
        821 |     self->recursion_depth = PyThreadState_GET()->recursion_depth;
            |                                                  ^~~~~~~~~~~~~~~
            |                                                  recursion_limit
      src/greenlet/greenlet.c: In function ‘green_new’:
      src/greenlet/greenlet.c:921:34: warning: assignment to ‘int *’ from incompatible pointer type ‘_PyCFrame *’ [-Wincompatible-pointer-types]
        921 |         ((PyGreenlet*)o)->cframe = &PyThreadState_GET()->root_cframe;
            |                                  ^
      In file included from /usr/include/python3.11/Python.h:45,
                       from src/greenlet/greenlet.h:8:
      src/greenlet/greenlet.c: In function ‘green_traverse’:
      src/greenlet/greenlet.c:1021:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1021 |     Py_VISIT(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/objimpl.h:199:13: note: in definition of macro ‘Py_VISIT’
        199 |         if (op) {                                                       \
            |             ^~
      In file included from /usr/include/python3.11/Python.h:38:
      src/greenlet/greenlet.c:1021:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1021 |     Py_VISIT(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/objimpl.h:200:30: note: in expansion of macro ‘_PyObject_CAST’
        200 |             int vret = visit(_PyObject_CAST(op), arg);                  \
            |                              ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1021:5: note: in expansion of macro ‘Py_VISIT’
       1021 |     Py_VISIT(self->exc_state.exc_type);
            |     ^~~~~~~~
      src/greenlet/greenlet.c:1023:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1023 |     Py_VISIT(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/objimpl.h:199:13: note: in definition of macro ‘Py_VISIT’
        199 |         if (op) {                                                       \
            |             ^~
      src/greenlet/greenlet.c:1023:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1023 |     Py_VISIT(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/objimpl.h:200:30: note: in expansion of macro ‘_PyObject_CAST’
        200 |             int vret = visit(_PyObject_CAST(op), arg);                  \
            |                              ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1023:5: note: in expansion of macro ‘Py_VISIT’
       1023 |     Py_VISIT(self->exc_state.exc_traceback);
            |     ^~~~~~~~
      src/greenlet/greenlet.c: In function ‘green_clear’:
      src/greenlet/greenlet.c:1059:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1059 |     Py_CLEAR(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/object.h:581:29: note: in expansion of macro ‘_PyObject_CAST’
        581 |         PyObject *_py_tmp = _PyObject_CAST(op); \
            |                             ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1059:5: note: in expansion of macro ‘Py_CLEAR’
       1059 |     Py_CLEAR(self->exc_state.exc_type);
            |     ^~~~~~~~
      In file included from /usr/include/python3.11/Python.h:44:
      src/greenlet/greenlet.c:1059:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1059 |     Py_CLEAR(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/object.h:583:14: note: in definition of macro ‘Py_CLEAR’
        583 |             (op) = NULL;                        \
            |              ^~
      src/greenlet/greenlet.c:1061:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1061 |     Py_CLEAR(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/object.h:581:29: note: in expansion of macro ‘_PyObject_CAST’
        581 |         PyObject *_py_tmp = _PyObject_CAST(op); \
            |                             ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1061:5: note: in expansion of macro ‘Py_CLEAR’
       1061 |     Py_CLEAR(self->exc_state.exc_traceback);
            |     ^~~~~~~~
      src/greenlet/greenlet.c:1061:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1061 |     Py_CLEAR(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/object.h:583:14: note: in definition of macro ‘Py_CLEAR’
        583 |             (op) = NULL;                        \
            |              ^~
      src/greenlet/greenlet.c: In function ‘green_dealloc’:
      src/greenlet/greenlet.c:1139:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1139 |     Py_CLEAR(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/object.h:581:29: note: in expansion of macro ‘_PyObject_CAST’
        581 |         PyObject *_py_tmp = _PyObject_CAST(op); \
            |                             ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1139:5: note: in expansion of macro ‘Py_CLEAR’
       1139 |     Py_CLEAR(self->exc_state.exc_type);
            |     ^~~~~~~~
      src/greenlet/greenlet.c:1139:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’
       1139 |     Py_CLEAR(self->exc_state.exc_type);
            |                             ^
      /usr/include/python3.11/object.h:583:14: note: in definition of macro ‘Py_CLEAR’
        583 |             (op) = NULL;                        \
            |              ^~
      src/greenlet/greenlet.c:1141:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1141 |     Py_CLEAR(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
         24 | #define _Py_CAST(type, expr) ((type)(expr))
            |                                      ^~~~
      /usr/include/python3.11/object.h:581:29: note: in expansion of macro ‘_PyObject_CAST’
        581 |         PyObject *_py_tmp = _PyObject_CAST(op); \
            |                             ^~~~~~~~~~~~~~
      src/greenlet/greenlet.c:1141:5: note: in expansion of macro ‘Py_CLEAR’
       1141 |     Py_CLEAR(self->exc_state.exc_traceback);
            |     ^~~~~~~~
      src/greenlet/greenlet.c:1141:29: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_traceback’
       1141 |     Py_CLEAR(self->exc_state.exc_traceback);
            |                             ^
      /usr/include/python3.11/object.h:583:14: note: in definition of macro ‘Py_CLEAR’
        583 |             (op) = NULL;                        \
            |              ^~
      src/greenlet/greenlet.c: In function ‘PyGreenlet_New’:
      src/greenlet/greenlet.c:1653:15: warning: assignment to ‘int *’ from incompatible pointer type ‘_PyCFrame *’ [-Wincompatible-pointer-types]
       1653 |     g->cframe = &PyThreadState_GET()->root_cframe;
            |               ^
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> greenlet

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

Main.py is missing the end.

I could be wrong but after reading all the code I think that the main.py file is missing some content at the end..

From the parenthesis of the custom_openapi function

To the uvicorn call to run the program and maybe other stuff.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.