{"id":16327387,"url":"https://github.com/willsams/example-js-react-with-python","last_synced_at":"2026-01-16T00:57:01.224Z","repository":{"id":219633526,"uuid":"742149063","full_name":"WillSams/example-js-react-with-python","owner":"WillSams","description":"JavaScript + Python full stack example application using React + Redux Sagas for the frontend and a GraphQL API backend using FastAPI + AsyncPG. ","archived":false,"fork":false,"pushed_at":"2025-02-24T14:58:46.000Z","size":3192,"stargazers_count":0,"open_issues_count":20,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T04:32:18.218Z","etag":null,"topics":["ariadne","asyncpg","bootstrap4","direnv","docker","fastapi","graphql","jwt-authorization","knexjs","nodejs","nvm","postgresql","pytest","pytest-mock","python","reactjs","redux-sagas"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WillSams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"samswebs"}},"created_at":"2024-01-11T21:26:39.000Z","updated_at":"2024-11-27T12:22:17.000Z","dependencies_parsed_at":"2024-04-22T13:32:39.419Z","dependency_job_id":"b9ed1e31-a5b9-4665-8e0a-60eb1a3903ce","html_url":"https://github.com/WillSams/example-js-react-with-python","commit_stats":null,"previous_names":["willsams/acme-hotel-react-fastapi-tortoiseorm","willsams/example-js-react-with-python"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-js-react-with-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-js-react-with-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-js-react-with-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-js-react-with-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WillSams","download_url":"https://codeload.github.com/WillSams/example-js-react-with-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246892847,"owners_count":20850850,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ariadne","asyncpg","bootstrap4","direnv","docker","fastapi","graphql","jwt-authorization","knexjs","nodejs","nvm","postgresql","pytest","pytest-mock","python","reactjs","redux-sagas"],"created_at":"2024-10-10T23:11:18.624Z","updated_at":"2026-01-16T00:57:01.213Z","avatar_url":"https://github.com/WillSams.png","language":"JavaScript","readme":"# Hotel Reservation React + Redux Sagas Example - JavaScript/Python\n\n**JavaScript, Vite, Reactjs, Redux Toolkit, Redux Sagas, Python, FastAPI, GraphQL, AsyncPG, Postgres**\n\n[![Application Unit Tests](https://github.com/WillSams/example-js-react-with-python/actions/workflows/pr-validate.yml/badge.svg)](https://github.com/WillSams/eexample-js-react-with-python/actions/workflows/pr-validate.yml)\n\nThis example contains a frontend and backend:\n\n- The frontend is a [React](https://react.dev) application using [Bootstrap4](https://getbootstrap.com/docs/4.6/getting-started/introduction/) for view designs.\n- The backend is a [GraphQL API](https://graphql.org) providing the ability to create, delete, and list reservatios plus available rooms for a given date range.\n\nReact [Typescript](https://github.com/WillSams/example-ts-react-with-python) and [Express MVC](https://github.com/WillSams/example-mvc-expressjs-with-python) versions of this same idea are available.\n\nAn [abandoned](https://github.com/WillSams/example-mvc-expressjs-with-python/tree/abandoned) branch for the previous version of this repository includes the usage of TortoiseORM.\n\n**Context**:\n\n- When a room is reserved, it cannot be reserved by another guest on overlapping dates.\n- Whenever there are multiple available rooms for a request, the room with the lower final price is assigned.\n- Whenever a request is made for a single room, a double bed room may be assigned (if no single is available?).\n- Smokers are not placed in non-smoking rooms.\n- Non-smokers are not placed in allowed smoking rooms.\n- Final price for reservations are determined by daily price * num of days requested, plus the cleaning fee.\n\n**Web UI Usage**:\n\n![text](images/home-example.png)\n\n**API Usage**:\n\nExample usage via [curl](https://curl.se/download.html):\n\n```bash\n# First, grab an access token provided by the API\nACCESS_TOKEN=$(curl -s -X POST \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  -d 'grant_type=password\u0026username=example-user\u0026password=example-user' \\\n  \"http://localhost:$RESERVATION_PORT/development/token\" | jq -r '.access_token')\n\n# List all existing booked reservations\ncurl http://localhost:$RESERVATION_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{\"query\": \"query { getAllReservations { reservations { room_id checkin_date checkout_date  } } }\"}'\n\n# Create a new reservation\n# Note: if there is an overlap, you'll see a \n#   'Reservation dates overlap with an existing reservation' error message\n# To see the aforementioned error, run this mutation a multiple times\ncurl http://localhost:$RESERVATION_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{ \"query\": \"mutation { createReservation( input: { room_id: \\\"91754a14-4885-4200-a052-e4042431ffb8\\\", checkin_date: \\\"2023-12-31\\\", checkout_date: \\\"2024-01-02\\\"  }) { success errors reservation { id room_id checkin_date checkout_date total_charge } } }\" }'\n\n# List Available Rooms for a given date range\ncurl http://localhost:$RESERVATION_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{\"query\": \"query { getAvailableRooms( input: { checkin_date: \\\"2023-12-31\\\", checkout_date: \\\"2024-01-02\\\" }) { success errors rooms { id num_beds allow_smoking daily_rate cleaning_fee } } }\" }'\n```\n\n**Open API UI Usage**:\n\nNavigate to [http://localhost:$RESERVATION_PORT/docs](http://localhost:$RESERVATION_PORT/docs).\n\n![backend/docs](./frontend/public/img/openapi_example.png)\n\n## Pre-requisites\n\nTo run the service, you will need to install the following tools.\n\n- [NodeJS](https://nodejs.org/en/)\n- [Docker](https://www.docker.com/)\n\nThe below are optional but highly recommended:\n\n- [nvm](https://github.com/nvm-sh/nvm) - Used to manage NodeJS versions.\n- [Direnv](https://direnv.net/) - Used to manage environment variables.\n- Install [direnv](https://direnv.net) for persisting environment variables needed for development.\n\n## Getting Started\n\nFirst, we'll need to set up our environment variables.  You can do this by either any of the methods mentioned in [/tools/ENV.md](./tools/ENV.md) but I recommend using [Direnv](https://direnv.net/).\n\n### Install Python Packages\n\nExecute the following in your terminal:\n\n```bash\npython -m venv venv\nsource venv/bin/activate  # for Windows, source venv/Scripts/activate\npython -m pip install --upgrade pip \npip install -r requirements.txt\n```\n\n### Install Node.js Packages\n\nExecute the following within your terminal:\n\n```bash\nnvm use                  # To eliminate any issues, install/use the version listed in .nvmrc. \nnpm i                    # install the packages needed for project\ncd ../frontend \u0026\u0026 npm i  # install the packages needed for the frontend\ncd ../db \u0026\u0026 npm i        # install the packages needed for database migrations\ncd ..                    # navigate back to the root of the repostiory\n```\n\n### Create the database\n\nFinally, let's create and seed the databases and our Reservations and Rooms tables:\n\n```bash\n# Create the databases and seed them\nNODE_ENV=development | npm run refresh \u0026\u0026 npm run seed\n```\n\nDuring development, you can just execute `npm run dev:db-baseline` to refresh the database back to the original seed data.\n\n## Development\n\nTo run both the frontend and backend concurrently:\n\n```bash\ndocker-compose up -d  # runs the database in the background\nnpm run dev\n```\n\nAlso, you just execute the backend via `npm run dev:backend`.  to verify the backend is working:\n\n```bash\ncurl http://localhost:$RESERVATION_PORT/$ENV/about\n```\n\nYou can also acces the Ariadne GraphiQL (interactive test playground) instance at [http://localhost:$RESERVATION_PORT/$ENV/graphql](http://localhost:$PLAYGROUND_PORT/$ENV/graphql).  \n\n## Testing\n\nThe backend uses [Pytest](https://docs.pytest.org) and the frontend uses [Jest](https://jestjs.io/).  To run these tests, simply execute `npm run test:backend` or `npm run test:frontend', respectively.\n\n## Containerization\n\n### Building the Backend Container\n\n```bash\ndocker build backend/. -t acme-hotel-example-backend:latest \\\n    --build-arg RESERVATION_PORT=\"80\" \\\n    --build-arg ENV=\"${ENV}\" \\\n    --build-arg IS_DEBUG=\"${IS_DEBUG}\" \\\n    --build-arg SECRET_KEY=\"$SECRET_KEY\" \\\n    --build-arg REFRESH_SECRET_KEY=\"$REFRESH_SECRET_KEY\" \\\n    --build-arg PG_URL=\"$PG_URL\"\n\n# finally, to run a named container\ndocker run --name backend-dev -p 8000:80 acme-hotel-example-backend\n```\n\nTo verify the environment variables set, you can execute the following on the named container by:\n\n```bash\nCONTAINER_ID=$(docker ps -qf \"name=backend-dev\" -n 1)\n\n# this will display the container's environment variables in console\ndocker exec $CONTAINER_ID printenv   \n```\n\nIf you need to re-create the container with the same name, do **docker rm \u003ccontainer-name\u003e** (i.e., backend-dev) first.\n\n### Building the Frontend Container\n\n```bash\ndocker build frontend/. -t acme-hotel-example-frontend:latest \\\n    --build-arg FRONTEND_PORT=\"80\" \\\n    --build-arg NODE_ENV=${NODE_ENV}\n\n# finally, to run a named container\ndocker run --name frontend-dev -p 3000:80 acme-hotel-example-frontend\n```\n\nTo verify, follow similar steps also explained in the above [Building the Backend Container](#building-the-backend-container) section.\n","funding_links":["https://ko-fi.com/samswebs"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillsams%2Fexample-js-react-with-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillsams%2Fexample-js-react-with-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillsams%2Fexample-js-react-with-python/lists"}