Coder Social home page Coder Social logo

buuntu / fastapi-react Goto Github PK

View Code? Open in Web Editor NEW
2.1K 42.0 331.0 4.29 MB

🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker

License: MIT License

Dockerfile 0.79% Python 49.15% HTML 3.23% Shell 3.69% CSS 0.69% TypeScript 39.05% JavaScript 2.48% Mako 0.93%
fastapi postgres cookiecutter react react-admin nginx boilerplate full-stack typescript sqlalchemy

fastapi-react's Introduction

FastAPI + React · build license Dependabot Status

fastapi-logo react-logo     react-admin     react-logo     react-logo sql-alchemy

A cookiecutter template for bootstrapping a FastAPI and React project using a modern stack.


Features

Table of Contents

Background

It is often laborsome to start a new project. 90% of the time you have to decide how to handle authentication, reverse proxies, docker containers, testing, server-side validation, linting, etc. before you can even get started.

FastAPI-React serves to streamline and give you that functionality out of the box.

It is meant as a lightweight/React alternative to FastAPI's official fullstack project. If you want a more comprehensive project in Vue, I would suggest you start there. A lot of the backend code is taken from that project or the FastAPI official docs.

Quick Start

First, install cookiecutter if you don't already have it:

pip3 install cookiecutter

Second, install docker-compose if you don't already have it:

docker-compose installation official docs.

Then, in the directory you want your project to live:

cookiecutter gh:Buuntu/fastapi-react

You will need to put in a few variables and it will create a project directory (called whatever you set for project_slug).

Input Variables
  • project_name [default fastapi-react-project]
  • project_slug [default fastapi-react-project] - this is your project directory
  • port [default 8000]
  • postgres_user [default postgres]
  • postgres_password [default password]
  • postgres_database [default app]
  • superuser_email [default [email protected]]
  • superuser_password [default password]
  • secret_key [default super_secret]

Develop

Change into your project directory and run:

chmod +x scripts/build.sh
./scripts/build.sh

This will build and run the docker containers, run the alembic migrations, and load the initial data (a test user).

It may take a while to build the first time it's run since it needs to fetch all the docker images.

Once you've built the images once, you can simply use regular docker-compose commands to manage your development environment, for example to start your containers:

docker-compose up -d

Once this finishes you can navigate to the port set during setup (default is localhost:8000), you should see the slightly modified create-react-app page:

default create-react-app

Note: If you see an Nginx error at first with a 502: Bad Gateway page, you may have to wait for webpack to build the development server (the nginx container builds much more quickly).

Login screen: regular login

The backend docs will be at http://localhost:8000/api/docs. API Docs

Admin Dashboard

This project uses react-admin for a highly configurable admin dashboard.

After starting the project, navigate to http://localhost:8000/admin. You should see a login screen. Use the username/password you set for the superuser on project setup.

NOTE: regular users will not be able to access the admin dashboard

React Adming Login

You should now see a list of users which you can edit, add, and delete. The table is configured with the REST endpoints to the FastAPI /users routes in the backend.

React Admin Dashboard

The admin dashboard is kept in the frontend/src/admin directory to keep it separate from the regular frontend.

Security

To generate a secure key used for encrypting/decrypting the JSON Web Tokens, you can run this command:

openssl rand -hex 32

The default is fine for development but you will want something more secure for production.

You can either set this on project setup as secret_key or manually edit the Python SECRET_KEY variable in backend/app/core/security.py.

Testing

This project comes with Pytest and a few Pytest fixtures for easier mocking. The fixtures are all located in backend/conftest.py within your project directory.

All tests are configured to run on a test database using SQLAlchemy transactions to reset the testing state on each function. This is to avoid a database call affecting the state of a different test.

Fixtures

These fixtures are included in backend/conftest.py and are automatically imported into any test files that being with test_.

test_db

The test_db fixture is an empty test database and an instance of a SQLAlchemy Session class.

def test_user(test_db):
    assert test_db.query(models.User).all()

test_user

def test_user_exists(test_user):
    assert test_user.email == "[email protected]"

test_superuser

def test_superuser(client, test_superuser):
    assert test_superuser.is_superuser

client

To use an unauthenticated test client, use client:

def test_get_users(client):
    client.get("/api/v1/users")
    assert response.status_code == 200

user_token_headers

If you need an authenticated client using OAuth2 and JWTs:

def test_user_me(client, user_token_headers):
    response = client.get(
      "/api/v1/users/me",
      headers=user_token_headers,
    )
    assert response.status_code == 200

Since OAuth2 expects the access token in the headers, you will need to pass in user_token_headers as the headers argument in any client request that requires authentication.

superuser_token_headers

def test_user_me(client, superuser_token_headers):
    response = client.get(
      "/api/v1/users",
      headers=superuser_token_headers,
    )
    assert response.status_code == 200

Background Tasks

This template comes with Celery and Redis Docker containers pre-configured for you. For any long running processes, it's recommended that you handle these using a task queue like Celery to avoid making the client wait for a request to finish. Some examples of this might be sending emails, uploading large files, or any long running, resource intensive tasks.

There is an example task in backend/app/tasks.py and an example Celery test in backend/app/tests/test_tasks.py. This test runs synchronously, which is what Celery docs recommend.

If you are not happy with Celery or Redis, it should be easy to swap these containers out with your favorite tools. Some suggested alternatives might be Huey as the task queue and RabbitMQ for the message broker.

Flower

You can monitor tasks using Flower by going to http://localhost:5555

Frontend Utilities

There are a few helper methods to handle authentication in frontend/src/utils. These store and access the JWT returned by FastAPI in local storage. Even though this doesn't add any security, we prevent loading routes that might be protected on the frontend, which results in a better UX experience.

Utility Functions

login

// in src/utils/auth.ts

/**
 *  Handles authentication with backend and stores in JWT in local storage
 **/
const login = (email: string, password: string) => boolean;

logout

// in src/utils/auth.ts

// clears token from local storage
const logout = (email: string, password: string) => void;

isAuthenticated

// Checks authenticated state from JWT tokens
const isAuthenticated = () => boolean;

Routes

Some basic routes are included (and handled in frontend/Routes.tsx).

  • /login - Login screen
  • /logout - Logout
  • / - Home
  • /protected - Example of protected route

Higher Order Components

PrivateRoute

This handles routes that require authentication. It will automatically check whether the correct token with the "user" permissions is present or redirect to the home page.

// in src/Routes.tsx
import { Switch } from 'react-router-dom';

// Replace this with your component
import { ProtectedComponent } from 'components';

const Routes = () => (
  <Switch>
    <PrivateRoute path="/protected_route" component={ProtectedComponent} />
  </Switch>
);

Deployment

This stack can be adjusted and used with several deployment options that are compatible with Docker Compose, but it may be easiest to use Docker in Swarm Mode with an Nginx main load balancer proxy handling automatic HTTPS certificates, using the ideas from DockerSwarm.rocks.

Please refer to DockerSwarm.rocks to see how to deploy such a cluster easily. You will have to change the Traefik examples to Nginx or update your docker-compose file.

Contributing

Contributing is more than welcome. Please read the Contributing doc to find out more.

fastapi-react's People

Contributors

adamnieto avatar arihantsurana avatar buuntu avatar cdeil avatar dependabot-preview[bot] avatar dependabot[bot] avatar f1r3hydr4nt avatar ilyakam avatar jakemanger avatar jasonhoku avatar josxa avatar numbnp avatar robberth 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  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

fastapi-react's Issues

Depreciation message in chrome

Probably due to react version problem(current version=^16.13.1, problem solved in 17.0.2), the following depreciation warning appears on chrome. Will changing the package.json file resolve the issue or is this problem more complicated?

more information: facebook/react#20829

[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M91, around May 2021. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details.
(anonymous) @ scheduler.development.js:305
../node_modules/scheduler/cjs/scheduler.development.js @ scheduler.development.js:857
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
../node_modules/scheduler/index.js @ index.js:6
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
(anonymous) @ react-dom.development.js:20
../node_modules/react-dom/cjs/react-dom.development.js @ react-dom.development.js:25011
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
../node_modules/react-dom/index.js @ index.js:37
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
./src/index.tsx @ index.css?08b9:45
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ index.ts:4
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1

Also, thanks for your work! I would have wasted a lot of time if it weren't for this project.

Map /app directory as volume for Celery worker?

Hey,

I've been working on a smallish API using this project and ran into an interesting thing with the celery worker. As of right now, the docker-compose file does not seem to map the source code directory(/app) into the container. What this means is that the container either needs to be rebuilt or re-copy the code in if you update any of the celery tasks.

I'm wondering if it would be better to simply map the code as a volume in the same way as is done with the backend so that updates are automatically copied? This is the same thing that is done in the official fastapi version as well, see here.

On that note, it might also be good to add an auto-reload for the worker on file change, using something such as watchdog. Although, if that was done a production flag should probably be used to disable this behavior during production scenarios.

If either of these seem like something that would be a good fit I'm happy to throw together a PR.

Add smpt server for password emails

There should be routes that trigger an email for "forgot" and "reset" password options. These can be celery tasks but probably need a separate container for a simple SMTP server in order to send the emails.

The fullstack Vue project has an example of a containerized SMTP server.

npm i on frontend depreciated modules

$ npm i

npm WARN deprecated [email protected]: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated [email protected]: request has been deprecated, see request/request#3142
npm WARN deprecated [email protected]: request-promise-native has been deprecated because it extends the now deprecated request package, see request/request#3142
npm WARN deprecated [email protected]: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated @hapi/[email protected]: joi is leaving the @Hapi organization and moving back to 'joi' (hapijs/joi#2411)
npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated @hapi/[email protected]: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/[email protected]: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/[email protected]: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/[email protected]: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated [email protected]: use String.prototype.padStart()
npm WARN deprecated [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.

[email protected] postinstall C:\Users\Hoku\Documents\PublicGitSite\FastAPI-React-GitSignUp-Branch\fastapi-react{{cookiecutter.project_slug}}\frontend\node_modules\babel-runtime\node_modules\core-js
node -e "try{require('./postinstall')}catch(e){}"

I can fix this one tomorrow if you'd like.

PrivateRoute auth vulnerable to user spoofing localStorage?

I'm very new to auth so sorry if this is all wrong. The code for isAuthenticated which is used to avoid rendering PrivateRoutes to unauthenticated users just checks local storage for a plain string permissions. Wouldn't this make it possible for a user to set 'permissions' to 'user' or 'admin' manually on local storage and then be able to possibly access static information that they shouldn't be able to? I'm guessing this wouldn't let them access any data via the API, but shouldn't isAuthenticated call the server and validate the token? Thank you.

export const isAuthenticated = () => {
  const permissions = localStorage.getItem('permissions');
  if (!permissions) {
    return false;
  }
  return permissions === 'user' || permissions === 'admin' ? true : false;
};

Add React ProtectedRoute

This route component should automatically redirect to login page if unauthorized, with a flash message.

User table does not exists...

Not sure what i am doing wrong here. I am getting when trying to login with a user or create one.
Does not look like the DB is created...

postgres_1 | 2020-10-28 13:24:12.381 UTC [32] ERROR: relation "user" does not exist at character 263
postgres_1 | 2020-10-28 13:24:12.381 UTC [32] STATEMENT: SELECT "user".id AS user_id, "user".email AS user_email, "user".first_name AS user_first_name, "user".last_name AS user_last_name, "user".hashed_password AS user_hashed_password, "user".is_active AS user_is_active, "user".is_superuser AS user_is_superuser
postgres_1 | FROM "user"
postgres_1 | WHERE "user".email = '[email protected]'
postgres_1 | LIMIT 1
......
backend_1 | sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "user" does not exist
backend_1 | LINE 2: FROM "user"

Send back permissions in JWT response

You shouldn't be able to login to the dashboard if you're not a superuser. Currently you can but are immediately redirected when trying to get /users because you get a 403. This should happen at login though, by adding scopes to the access token we should be able to do that.

`E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file.`

Hello! Thank you for sharing such a helpful starter project! I'm sure it's an issue on my end but when trying to build the Docker containers for the first time. I kept all the defaults for now but I run into E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file. error when trying to build. Many possible solutions I've found involve changing the sources.list but that may be going in the wrong direction. Any help/ideas would be greatly appreciated and thanks again for your contribution!

Here's the error output when running the script:

❯ ~/Code/fastapi-react-project ./scripts/build.sh
Building worker
Step 1/7 : FROM python:3.8
 ---> 7f5b6ccd03e9
Step 2/7 : RUN mkdir /app
 ---> Using cache
 ---> f0116c1f6621
Step 3/7 : WORKDIR /app
 ---> Using cache
 ---> b7cf3d34ff55
Step 4/7 : RUN apt update &&     apt install -y postgresql-client
 ---> Running in cfe01c7ac65a

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Ign:1 http://deb.debian.org/debian buster InRelease
Ign:2 http://deb.debian.org/debian buster-updates InRelease
Ign:3 http://security.debian.org/debian-security buster/updates InRelease
Err:4 http://deb.debian.org/debian buster Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Err:5 http://security.debian.org/debian-security buster/updates Release
  Cannot initiate the connection to security.debian.org:80 (0.0.15.75). - connect (22: Invalid argument)
Err:6 http://deb.debian.org/debian buster-updates Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Reading package lists...
E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file.
E: The repository 'http://security.debian.org/debian-security buster/updates Release' does not have a Release file.
E: The repository 'http://deb.debian.org/debian buster-updates Release' does not have a Release file.
ERROR: Service 'worker' failed to build: The command '/bin/sh -c apt update &&     apt install -y postgresql-client' returned a non-zero code: 100
Starting fastapi-react-project_postgres_1 ... done
Building backend
Step 1/7 : FROM python:3.8
 ---> 7f5b6ccd03e9
Step 2/7 : RUN mkdir /app
 ---> Using cache
 ---> f0116c1f6621
Step 3/7 : WORKDIR /app
 ---> Using cache
 ---> b7cf3d34ff55
Step 4/7 : RUN apt update &&     apt install -y postgresql-client
 ---> Running in a4fe17886f2c

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Ign:1 http://security.debian.org/debian-security buster/updates InRelease
Err:2 http://security.debian.org/debian-security buster/updates Release
  Cannot initiate the connection to security.debian.org:80 (0.0.15.75). - connect (22: Invalid argument)
Ign:3 http://deb.debian.org/debian buster InRelease
Ign:4 http://deb.debian.org/debian buster-updates InRelease
Err:5 http://deb.debian.org/debian buster Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Err:6 http://deb.debian.org/debian buster-updates Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Reading package lists...
E: The repository 'http://security.debian.org/debian-security buster/updates Release' does not have a Release file.
E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file.
E: The repository 'http://deb.debian.org/debian buster-updates Release' does not have a Release file.
ERROR: Service 'backend' failed to build: The command '/bin/sh -c apt update &&     apt install -y postgresql-client' returned a non-zero code: 100
Starting fastapi-react-project_postgres_1 ... done
Building backend
Step 1/7 : FROM python:3.8
 ---> 7f5b6ccd03e9
Step 2/7 : RUN mkdir /app
 ---> Using cache
 ---> f0116c1f6621
Step 3/7 : WORKDIR /app
 ---> Using cache
 ---> b7cf3d34ff55
Step 4/7 : RUN apt update &&     apt install -y postgresql-client
 ---> Running in 5178718013f2

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Ign:1 http://security.debian.org/debian-security buster/updates InRelease
Ign:2 http://deb.debian.org/debian buster InRelease
Ign:3 http://deb.debian.org/debian buster-updates InRelease
Err:4 http://security.debian.org/debian-security buster/updates Release
  Cannot initiate the connection to security.debian.org:80 (0.0.15.75). - connect (22: Invalid argument)
Err:5 http://deb.debian.org/debian buster Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Err:6 http://deb.debian.org/debian buster-updates Release
  Cannot initiate the connection to deb.debian.org:80 (0.0.15.74). - connect (22: Invalid argument)
Reading package lists...
E: The repository 'http://security.debian.org/debian-security buster/updates Release' does not have a Release file.
E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file.
E: The repository 'http://deb.debian.org/debian buster-updates Release' does not have a Release file.
ERROR: Service 'backend' failed to build: The command '/bin/sh -c apt update &&     apt install -y postgresql-client' returned a non-zero code: 100

Maximum call stack size exceeded

I am trying to execute the command chmod +x scripts/build.sh ./scripts/build.sh, using the default configuration, however, I am always getting this error:

npm notice 
npm notice New patch version of npm available! 7.0.3 -> 7.0.5
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v7.0.5>
npm notice Run `npm install -g [email protected]` to update!
npm notice 
npm ERR! Maximum call stack size exceeded

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-10-24T13_56_07_518Z-debug.log
ERROR: Service 'frontend' failed to build : The command '/bin/sh -c npm rebuild' returned a non-zero code: 1
Starting fastapi-react-project_postgres_1 ... 
Starting fastapi-react-project_postgres_1 ... error

ERROR: for fastapi-react-project_postgres_1  Cannot start service postgres: driver failed programming external connectivity on endpoint fastapi-react-project_postgres_1 (64ddcd8b9c18461c2873dfbb73f31a713928de7744232e764ec2fe7ed78b2dd1): Bind for 0.0.0.0:5432 failed: port is already allocated

ERROR: for postgres  Cannot start service postgres: driver failed programming external connectivity on endpoint fastapi-react-project_postgres_1 (64ddcd8b9c18461c2873dfbb73f31a713928de7744232e764ec2fe7ed78b2dd1): Bind for 0.0.0.0:5432 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
Starting fastapi-react-project_postgres_1 ... 
Starting fastapi-react-project_postgres_1 ... error

ERROR: for fastapi-react-project_postgres_1  Cannot start service postgres: driver failed programming external connectivity on endpoint fastapi-react-project_postgres_1 (31ccd7b0ce884e6658231ae13ef1be29c5c34888676df38322930a3cdbcb67ed): Bind for 0.0.0.0:5432 failed: port is already allocated

ERROR: for postgres  Cannot start service postgres: driver failed programming external connectivity on endpoint fastapi-react-project_postgres_1 (31ccd7b0ce884e6658231ae13ef1be29c5c34888676df38322930a3cdbcb67ed): Bind for 0.0.0.0:5432 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.

Configuration:

  • Docker version 19.03.13, build 4484c46d9d
  • Mac Os Catalina
  • NPM 7.0.3
  • Node v15.0.1

I have found this question, however, I have tried every possible solution without success.

What can be the reason I am getting this?

Form validation errors on Sign Up and Login pages

I found a bug where the frontend errors out when you press the submit button on empty fields for the login and sign up pages.

Here is a gif of the error for the sign up page. The same error occurred with login page as well.

error_with_signup_and_signin

Flower not reachable

Just setup the project and started it. I can manage the users, but I am unable to reach the Flower UI for Celery.

Question on middleware implementation

Hi @Buuntu

I really like your boilerplate here - there's a lot of good practices to study I think. I stumbled upon one thing that puzzles me a bit though. You add middleware to create a database session for each request and close it again. But you also create a dependency to do the same if I'm not mistaken?

I imagine that you first implemented the middleware approach but realized you could solve it with dependency injection instead? I'm curious if I'm wrong in my perception?

incorrect type on get_user_by_email()

The current signature is def get_user_by_email(db: Session, email: str) -> schemas.UserBase: but I believe this to be incorrect. It should be def get_user_by_email(db: Session, email: str) -> schemas.User:. The reason is that this function returns the DB row which includes the id as part of the model.

Request to backend fails link on main webpage on no- localhost machine.

Error: Objects are not valid as a React child (found: TypeError: Failed to fetch). If you meant to render a collection of children, use an array instead.
in code (at Home.tsx:41)
in p (at Home.tsx:40)
in Home (created by Context.Consumer)
in Route (at Routes.tsx:49)
in header (at Routes.tsx:37)
in div (at Routes.tsx:36)
in Switch (at Routes.tsx:31)
in Routes (at App.tsx:4)
in App (at src/index.tsx:9)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.tsx:8)
▼ 28 stack frames were expanded.
code
Home.tsx:41
p
Home.tsx:40
Route
Routes.tsx:49
header
Routes.tsx:37
div
Routes.tsx:36
Switch
Routes.tsx:31
Routes
App.tsx:4
App
src/index.tsx:9
BrowserRouter
src/index.tsx:8
throwOnInvalidObjectType
/node_modules/react-dom/cjs/react-dom.development.js:13413
reconcileChildFibers
/node_modules/react-dom/cjs/react-dom.development.js:14313
reconcileChildren
/node_modules/react-dom/cjs/react-dom.development.js:16762
updateHostComponent
/node_modules/react-dom/cjs/react-dom.development.js:17302
beginWork
/node_modules/react-dom/cjs/react-dom.development.js:18627
HTMLUnknownElement.callCallback
/node_modules/react-dom/cjs/react-dom.development.js:188
invokeGuardedCallbackDev
/node_modules/react-dom/cjs/react-dom.development.js:237
invokeGuardedCallback
/node_modules/react-dom/cjs/react-dom.development.js:292
beginWork$1
/node_modules/react-dom/cjs/react-dom.development.js:23203
performUnitOfWork
/node_modules/react-dom/cjs/react-dom.development.js:22157
workLoopSync
/node_modules/react-dom/cjs/react-dom.development.js:22130
performSyncWorkOnRoot
/node_modules/react-dom/cjs/react-dom.development.js:21756
(anonymous function)
/node_modules/react-dom/cjs/react-dom.development.js:11089
unstable_runWithPriority
/node_modules/scheduler/cjs/scheduler.development.js:653
runWithPriority$1
/node_modules/react-dom/cjs/react-dom.development.js:11039
flushSyncCallbackQueueImpl
/node_modules/react-dom/cjs/react-dom.development.js:11084
flushSyncCallbackQueue
/node_modules/react-dom/cjs/react-dom.development.js:11072
scheduleUpdateOnFiber
/node_modules/react-dom/cjs/react-dom.development.js:21199
dispatchAction
/node_modules/react-dom/cjs/react-dom.development.js:15660
▲ 28 stack frames were expanded.
queryBackend
src/views/Home.tsx:23
20 | const message = await getMessage();
21 | setMessage(message);
22 | } catch (err) {

23 | setError(err);
| ^ 24 | }
25 | };
26 |
View compiled
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error. Click the 'X' or hit ESC to dismiss this message.

I assume this to be indicative of the methodology for file pathing, needing %PUBLIC_URL% or another director to account for react link generation.

I will take a look at this in the next couple days, might be a quick fix.

Replace snapshot tests with something else

Snapshot tests take ~10 seconds to run - need to either speed these up or replace them with something else.

Probably should just replace with react-testing-library or cypress honestly.

Scripts fail with version issues on backend

while trying to build the backend:

`INFO: pip is looking at multiple versions of celery to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of bcrypt to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of authlib to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of alembic to determine which version is compatible with other requirements. This could take a while.
ERROR: Cannot install -r requirements.txt (line 3) and starlette==0.13.8 because these package versions have conflicting dependencies.

The conflict is caused by:
The user requested starlette==0.13.8
fastapi 0.61.1 depends on starlette==0.13.6

To fix this you could try to:

  1. loosen the range of package versions you've specified
  2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies
ERROR: Service 'backend' failed to build : The command '/bin/sh -c pip install --no-cache-dir -r requirements.txt' returned a non-zero code: 1

'unknown' is not assignable to parameter of type 'SetStateAction<string>'.

When launching docker compose up and then going to localhost:8000, I got the following error:

/app/src/views/Login.tsx
TypeScript error in /app/src/views/Login.tsx(54,18):
Argument of type 'unknown' is not assignable to parameter of type 'SetStateAction'.
Type 'unknown' is not assignable to type '(prevState: string) => string'. TS2345

52 |       } else {
53 |         // handle errors thrown from backend

54 | setError(err);
| ^
55 | }
56 | }
57 | };

Nginx and frontend containers don't start

Nginx -

2021/08/23 16:40:52 [emerg] 1#1: host not found in upstream "frontend" in /etc/nginx/conf.d/default.conf:10

nginx: [emerg] host not found in upstream "frontend" in /etc/nginx/conf.d/default.conf:10

2021/08/23 16:41:49 [emerg] 1#1: host not found in upstream "frontend" in /etc/nginx/conf.d/default.conf:10

nginx: [emerg] host not found in upstream "frontend" in /etc/nginx/conf.d/default.conf:10

{project_name}_frontend_1 -

/app/run.sh: line 2: $'\r': command not found

/app/run.sh: line 3: syntax error near unexpected token `$'in\r''

'app/run.sh: line 3: `case $1 in

Docker Version - Version: 3.6.0 (67351)
OS: Windows 10 Pro
Edition: Professional
Build: 19042

GitHub "Black" code formatter check always fails.

GitHub build check report:

Run lgeiger/black-action@master
/usr/bin/docker run --name b3ac6ed6ddacb693d4fffba82c2c3d567b1ef_f8ec2f --label 3b3ac6 --workdir /github/workspace --rm -e pythonLocation -e INPUT_ARGS -e HOME -e GITHUB_JOB -e GITHUB_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_ACTOR -e GITHUB_WORKFLOW -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GITHUB_EVENT_NAME -e GITHUB_SERVER_URL -e GITHUB_API_URL -e GITHUB_GRAPHQL_URL -e GITHUB_WORKSPACE -e GITHUB_ACTION -e GITHUB_EVENT_PATH -e RUNNER_OS -e RUNNER_TOOL_CACHE -e RUNNER_TEMP -e RUNNER_WORKSPACE -e ACTIONS_RUNTIME_URL -e ACTIONS_RUNTIME_TOKEN -e ACTIONS_CACHE_URL -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/fastapi-react/fastapi-react":"/github/workspace" 3b3ac6:ed6ddacb693d4fffba82c2c3d567b1ef {{cookiecutter.project_slug}}/backend --check
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/app/alembic/env.py
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/app/api/api_v1/routers/users.py
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/app/api/api_v1/routers/tests/test_users.py
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/app/core/auth.py
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/app/db/session.py
would reformat /github/workspace/{{cookiecutter.project_slug}}/backend/conftest.py
Oh no! 💥 💔 💥
6 files would be reformatted, 24 files would be left unchanged.
Run tests

Add user tests

Add mocked tests for user endpoints (post/edit/get single one). Need to add fixtures for this too.

script build.sh continues to execute even if the docker is not available

It happens that I start the build.sh at the moment when docker is not running yet.

The script shows the trace of the error from the "docker-compose up" but does not quit, but continues executing commands

This is not critical at the moment, but in the future it may have destructive actions.

upgrade alembic error

When running:
alembic upgrade head
in my ubuntu console.

I got this error:
Traceback (most recent call last):
File "/usr/bin/alembic", line 11, in
load_entry_point('alembic==1.1.0.dev0', 'console_scripts', 'alembic')()
File "/usr/lib/python3/dist-packages/alembic/config.py", line 540, in main
CommandLine(prog=prog).main(argv=argv)
File "/usr/lib/python3/dist-packages/alembic/config.py", line 534, in main
self.run_cmd(cfg, options)
File "/usr/lib/python3/dist-packages/alembic/config.py", line 511, in run_cmd
fn(
File "/usr/lib/python3/dist-packages/alembic/command.py", line 279, in upgrade
script.run_env()
File "/usr/lib/python3/dist-packages/alembic/script/base.py", line 475, in run_env
util.load_python_file(self.dir, "env.py")
File "/usr/lib/python3/dist-packages/alembic/util/pyfiles.py", line 98, in load_python_file
module = load_module_py(module_id, path)
File "/usr/lib/python3/dist-packages/alembic/util/compat.py", line 174, in load_module_py
spec.loader.exec_module(module)
File "", line 783, in exec_module
File "", line 219, in _call_with_frames_removed
File "app/alembic/env.py", line 8, in
from app.db.models import Base
ModuleNotFoundError: No module named 'app'

I don't change my Dockerfile.

My docker file is:

FROM python:3.8

RUN mkdir app
WORKDIR app/

RUN apt update &&
apt install -y postgresql-client

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

Nginx container sometimes errors on load

This has to do with not waiting for frontend and backend containers to be started before the Nginx container loads. Using something like depends_on in Docker won't work because the frontend container has technically started even before Webpack is built. Backend can be an issue too but Webpack is the one that takes a significant amount of time in my experience.

Example error:

nginx_1     | 2020/07/08 06:13:44 [emerg] 1#1: host not found in upstream "backend" in /etc/nginx/conf.d/default.conf:24
nginx_1     | nginx: [emerg] host not found in upstream "backend" in /etc/nginx/conf.d/default.conf:24

What we need is something like Docker's healthcheck or the wait-for-it script to check that these containers are responding to requests. It would also be good if Nginx can report an error message that makes sense (like that it's starting up) during this time, to avoid confusion.

ReadMe Improvements.

Can the readme.md reflect the coockiecutters pip reccomended setup?

Is it for a python3 venv or a redirected path for python3? I went with pip3 install

Secondly, can we have more info on "docker-compose up -d" seems to not work intuitively, requiring un-listed documentation:

Suggested by CLI all run errors:
docker-machine start default
docker-machine create

until finally (maybe add documentation to this step)':
docker-machine create none

Oh, no that didn't do anything either. :(

It was sudo docker-compose up -d

Maybe more clarity for the docker-compose installation or maybe my cookiecutter setup was wrong?

Either way, excited to see this powerful tech here educating <3 Thank you!

How to update docker compose file for dockerswarm deployment with traefik

Hi thanks for this great project generator. It works great but I'm trying to figure out how to deploy it.
I read the tutorial on dockerswarm rocks but I don't know how to update the docker compose file as suggested in the docs.

I tried it like this

version: '3.7'
services:
  traefik:
    # Use the latest Traefik image
    image: traefik:v2.2
    ports:
        # Listen on port 80, default for HTTP, necessary to redirect to HTTPS
        - target: 80
        published: 80
        mode: host
        # Listen on port 443, default for HTTPS
        - target: 443
        published: 443
        mode: host
    deploy:
        placement:
        constraints:
            # Make the traefik service run only on the node with this label
            # as the node with it has the volume for the certificates
            - node.labels.traefik-public.traefik-public-certificates == true
        labels:
        # Enable Traefik for this service, to make it available in the public network
        - traefik.enable=true
        # Use the traefik-public network (declared below)
        - traefik.docker.network=traefik-public
        # Use the custom label "traefik.constraint-label=traefik-public"
        # This public Traefik will only use services with this label
        # That way you can add other internal Traefik instances per stack if needed
        - traefik.constraint-label=traefik-public
        # admin-auth middleware with HTTP Basic auth
        # Using the environment variables USERNAME and HASHED_PASSWORD
        - traefik.http.middlewares.admin-auth.basicauth.users=${USERNAME?Variable not set}:${HASHED_PASSWORD?Variable not set}
        # https-redirect middleware to redirect HTTP to HTTPS
        # It can be re-used by other stacks in other Docker Compose files
        - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
        - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
        # traefik-http set up only to use the middleware to redirect to https
        # Uses the environment variable DOMAIN
        - traefik.http.routers.traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`)
        - traefik.http.routers.traefik-public-http.entrypoints=http
        - traefik.http.routers.traefik-public-http.middlewares=https-redirect
        # traefik-https the actual router using HTTPS
        # Uses the environment variable DOMAIN
        - traefik.http.routers.traefik-public-https.rule=Host(`${DOMAIN?Variable not set}`)
        - traefik.http.routers.traefik-public-https.entrypoints=https
        - traefik.http.routers.traefik-public-https.tls=true
        # Use the special Traefik service api@internal with the web UI/Dashboard
        - traefik.http.routers.traefik-public-https.service=api@internal
        # Use the "le" (Let's Encrypt) resolver created below
        - traefik.http.routers.traefik-public-https.tls.certresolver=le
        # Enable HTTP Basic auth, using the middleware created above
        - traefik.http.routers.traefik-public-https.middlewares=admin-auth
        # Define the port inside of the Docker service to use
        - traefik.http.services.traefik-public.loadbalancer.server.port=8080
    volumes:
        # Add Docker as a mounted volume, so that Traefik can read the labels of other services
        - /var/run/docker.sock:/var/run/docker.sock:ro
        # Mount the volume to store the certificates
        - traefik-public-certificates:/certificates
    command:
        # Enable Docker in Traefik, so that it reads labels from Docker services
        - --providers.docker
        # Add a constraint to only use services with the label "traefik.constraint-label=traefik-public"
        - --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`)
        # Do not expose all Docker services, only the ones explicitly exposed
        - --providers.docker.exposedbydefault=false
        # Enable Docker Swarm mode
        - --providers.docker.swarmmode
        # Create an entrypoint "http" listening on address 80
        - --entrypoints.http.address=:80
        # Create an entrypoint "https" listening on address 80
        - --entrypoints.https.address=:443
        # Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
        - --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
        # Store the Let's Encrypt certificates in the mounted volume
        - --certificatesresolvers.le.acme.storage=/certificates/acme.json
        # Use the TLS Challenge for Let's Encrypt
        - --certificatesresolvers.le.acme.tlschallenge=true
        # Enable the access log, with HTTP requests
        - --accesslog
        # Enable the Traefik log, for configurations and errors
        - --log
        # Enable the Dashboard and API
        - --api
    networks:
        # Use the public network created to be shared between Traefik and
        # any other service that needs to be publicly available with HTTPS
        - traefik-public
#   nginx:
#     image: nginx:1.17
#     volumes:
#       - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
#     ports:
#       - 8000:80
#     depends_on:
#       - backend

  redis:
    image: redis
    ports:
      - 6379:6379

  postgres:
    image: postgres:12
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - '5432:5432'
    volumes:
      - db-data:/var/lib/postgresql/data:cached

  worker:
    build:
      context: backend
      dockerfile: Dockerfile
    command: celery worker -A app.tasks --loglevel=DEBUG -Q main-queue -c 1

  flower:  
    image: mher/flower
    command: flower --broker=redis://redis:6379/0 --port=5555
    ports:  
        - 5555:5555
    depends_on:
      - "redis"

  backend:
    build:
      context: backend
      dockerfile: Dockerfile
    command: python app/main.py
    tty: true
    volumes:
      - ./backend:/app/:cached
      - ./.docker/.ipython:/root/.ipython:cached
    environment:
      PYTHONPATH: .
      DATABASE_URL: 'postgresql://postgres:password@postgres:5432/postgres'
    depends_on:
      - "postgres"


volumes:
  db-data:

But it's not working... What am I doing wrong? Or is there a template file for deployment?
Thanks

cannot load localhost:8000

whenever I run docker-compose up -d everything works, but when I go to localhost:8000 nginx returns 499 then 504, and it does this every time.

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.