Python - Vite

  • Integration of a Python server and a Typescript client using Vite and a development proxy.

    Introduction

    Ee will create a web application in which:

    • The server is written with FastAPI
    • The client is written in React

    The client and server communicate using JSON.

    Server PythonClient TypescriptInternet

    Working environment

    Clone the project:

    Terminal window
    $ git clone https://gitlab.com/xtec/python/vite

    Server

    The backend server is developed completely independently of the frontend.

    Start the Python server through the Deno task:

    Terminal window
    $ deno task server

    The server exposes an HTTP endpoint at:

    Nota

    All API endpoints must start with /api/

    Client

    Now start the Typescript - Vite development server:

    Terminal window
    $ deno task client

    Have a look at the file vite.config.ts:

    // ...
    export default defineConfig({
    // ...
    server: {
    port: 3000,
    cors: true,
    proxy: {
    '/api': {
    target: 'http://localhost:8000',
    }
    },
    })

    The Vite dev server runs on http://127.0.0.1:3000 and is configured to proxy API requests to the backend server on http://127.0.0.1:8000.

    This is done using the server.proxy option. All HTTP requests whose path starts with /api are forwarded transparently to http://localhost:8000.

    If you open:

    you will see the same response as the backend endpoint:

    From the React application’s point of view, this proxy is completely transparent. In App.tsx you can see a data fetch like this:

    const { data, error } = useSWR("/api/time", fetcher)

    Notice that:

    • You do not specify localhost.
    • You do not specify any port.
    • You only use the path (/api/time).

    Production

    In production, the backend server must serve both:

    • All API endpoints.
    • All static client assets (the built React application).

    First, build the client application with Vite(Vite - Build):

    Terminal window
    $ deno task build

    This creates a directory with all the static assets for the client, typically placed under server/static (depending on the project configuration).

    The server is configured to serve static files from this directory if it exists, for example:

    You can see that a server/static directory has been created with all the static content of the client.

    The server is configured to serve the static files from this directory if it exists:

    if os.path.exists("static"):
    app.mount("/", StaticFiles(directory="static", html=True), name="static")
    Nota

    This code must be added at the end of the route configuration so that the / rule is applied last, after the API routes.

    Restart the server and go to:

    You should now see the client application being served directly by the backend server. The same origin (http://127.0.0.1:8000) is used for both the API (/api/...) and the frontend (static files).

    Docker

    Finally, package the application into a container image and push it to Docker Hub.

    You can follow these two help documents: