ModuleNotFoundError with Flask app

I am trying to deploy a very simple Flask-React app to railway, but I keep getting this error :
Traceback (most recent call last):
File "./backend/app.py", line 5, in <module>
from flask import Flask, jsonify, request, send_from_directory
ModuleNotFoundError: No module named 'flask'
Traceback (most recent call last):
File "./backend/app.py", line 5, in <module>
from flask import Flask, jsonify, request, send_from_directory
ModuleNotFoundError: No module named 'flask'
This is my file structure : Image This is my Dockerfile :
# Backend build
FROM python:3.8 AS backend-build
WORKDIR /app/backend
COPY ./backend/requirements.txt .
RUN pip install -r requirements.txt
COPY ./backend .

# Frontend build
FROM node:14 AS frontend-build
WORKDIR /app/frontend
COPY ./frontend/package*.json ./
RUN npm install
COPY ./frontend .
RUN npm run build

# Final Stage
FROM python:3.8
WORKDIR /app
COPY --from=backend-build /app/backend ./backend
COPY --from=frontend-build /app/frontend ./frontend/build
EXPOSE 5000
CMD ["python", "./backend/app.py"]
# Backend build
FROM python:3.8 AS backend-build
WORKDIR /app/backend
COPY ./backend/requirements.txt .
RUN pip install -r requirements.txt
COPY ./backend .

# Frontend build
FROM node:14 AS frontend-build
WORKDIR /app/frontend
COPY ./frontend/package*.json ./
RUN npm install
COPY ./frontend .
RUN npm run build

# Final Stage
FROM python:3.8
WORKDIR /app
COPY --from=backend-build /app/backend ./backend
COPY --from=frontend-build /app/frontend ./frontend/build
EXPOSE 5000
CMD ["python", "./backend/app.py"]
And this is my requirements.py : Flask==2.3.2 Flask-Cors==3.0.10 Flask-SQLAlchemy==3.0.3 spacy==3.5.3 dateparser==1.1.8 I have tried using pip freeze to see the installed packages, and flask get's installed correctly, I am new to Flask apps, Dockerfiles and runway so I don't know how to solve this problem. PS : the app does build but the app crashes in the deploy phase
111 Replies
Percy
Percy2y ago
Project ID: 6ecdf6a2-891e-42b8-a238-d0567de6cde3
wapeto
wapeto2y ago
6ecdf6a2-891e-42b8-a238-d0567de6cde3
Brody
Brody2y ago
share a link to your repo please
Brody
Brody2y ago
its private
wapeto
wapeto2y ago
now public have you found anything ?
Brody
Brody2y ago
have some patients please, this is comunity support
wapeto
wapeto2y ago
Sure, I'm sorry
Brody
Brody2y ago
you used chatgpt lol @Wapeto show me a screenshot of your railway project
wapeto
wapeto2y ago
I did mildpanic , as I said I'm new to Flask and Railway. What screenshot do you want exactly ?
Brody
Brody2y ago
a screenshot of your browser window open to the railway project
wapeto
wapeto2y ago
Brody
Brody2y ago
okay so since you have 2 services in a single repo, that is referred to as a mono repo. and if you have two services in a repo, you need two services in your railway project so lets only tackle one at a time
wapeto
wapeto2y ago
Okay... What does it mean ?
Brody
Brody2y ago
remove your repo from that service it will make sense in time, you just gotta follow what i say
wapeto
wapeto2y ago
How do I delete the repo from the service without deleting the service ?
Brody
Brody2y ago
in the service settings
wapeto
wapeto2y ago
found it
Brody
Brody2y ago
now rename that service to frontend 1. do you have any service variables set? 2. do you have a build command set? 3. do you have a start command set?
wapeto
wapeto2y ago
1. No 2. No 3. No
Brody
Brody2y ago
good do you know how to merge a pull request on your repo?
wapeto
wapeto2y ago
normally
Brody
Brody2y ago
okay check your pull requests
wapeto
wapeto2y ago
should be done
Brody
Brody2y ago
you did this right?
wapeto
wapeto2y ago
yes
Brody
Brody2y ago
in the service settings, set the root directory to /frontend
wapeto
wapeto2y ago
done
Brody
Brody2y ago
add your repo back
wapeto
wapeto2y ago
its building
Brody
Brody2y ago
yes let me know how that goes
wapeto
wapeto2y ago
it failed
Brody
Brody2y ago
build logs please
wapeto
wapeto2y ago
Wait they seem cut of Im going to try redeploy
Brody
Brody2y ago
okay
wapeto
wapeto2y ago
Nah same thing hapened, this is the Build Log :
==============
Using Nixpacks
==============

context: e5e50de39194e757a8116eb81f42943d
Nixpacks build failed


Nixpacks was unable to generate a build plan for this app.
Please check the documentation for supported languages: https://nixpacks.com

The contents of the app directory are:

frontend/
backend/
README.md

==============
Using Nixpacks
==============

context: e5e50de39194e757a8116eb81f42943d
Nixpacks build failed


Nixpacks was unable to generate a build plan for this app.
Please check the documentation for supported languages: https://nixpacks.com

The contents of the app directory are:

frontend/
backend/
README.md

Brody
Brody2y ago
bruh
wapeto
wapeto2y ago
And then it crashes
Brody
Brody2y ago
^
wapeto
wapeto2y ago
I did
Brody
Brody2y ago
prove it
wapeto
wapeto2y ago
shit it didnt save or smth, my bad
Brody
Brody2y ago
lol
LaCrak27
LaCrak272y ago
pic or it didn't happen
Brody
Brody2y ago
real
LaCrak27
LaCrak272y ago
(jk i leave now)
Brody
Brody2y ago
where you going, we aint done
wapeto
wapeto2y ago
lol
LaCrak27
LaCrak272y ago
oh god
wapeto
wapeto2y ago
Okay, it built correctly This is the output from Deploy Logs :
npm WARN config production Use `--omit=dev` instead.
> serve build -s -n -L -p $PORT
INFO Accepting connections at http://localhost:7716
npm WARN config production Use `--omit=dev` instead.
> serve build -s -n -L -p $PORT
INFO Accepting connections at http://localhost:7716
How do I open the website now ? (or is there smth else to do before that)
Brody
Brody2y ago
youd need to generate a domain in the service settings also big congratulations on not having build warnings, most people who have deployed react apps have a bunch of build warnings
wapeto
wapeto2y ago
I have this tho
Brody
Brody2y ago
did you generate a domain?
wapeto
wapeto2y ago
Thxx but it's really a basic app so there's that. yes and this is the page it links me to
Brody
Brody2y ago
its still an accomplishment send me the domain please
wapeto
wapeto2y ago
React App
Web site created using create-react-app
Brody
Brody2y ago
it works
wapeto
wapeto2y ago
My bad once again, Im sorry
Brody
Brody2y ago
no worries
wapeto
wapeto2y ago
Thanks soooo much, you're a wizard
Brody
Brody2y ago
okay backend time!!
wapeto
wapeto2y ago
oh I had forgotten What do I have to do ?
Brody
Brody2y ago
create a empty service in the same project and name it backend
wapeto
wapeto2y ago
And when everything is done, could you please tell me everything you did si I can solve the problem alone next time ? okay done renamed and changed the root directory too
Brody
Brody2y ago
then set the root directory to /backend but make sure to save it this time
wapeto
wapeto2y ago
I made sure lmao
Brody
Brody2y ago
ah you getting the hang of this okay i think you are good to add the repo
wapeto
wapeto2y ago
wapeto
wapeto2y ago
should I do something else ?
Brody
Brody2y ago
you need to generate a domain
wapeto
wapeto2y ago
Okay everything is done and running, but I have this error when I try using the app and make requests :
react_devtools_backend_compact.js:2367 K {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}code: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}stack: "AxiosError: Network Error\n at u.onerror (https://abnar.up.railway.app/static/js/main.0060d090.js:2:172793)"[[Prototype]]: Error
overrideMethod @ react_devtools_backend_compact.js:2367
(anonyme) @ SaveInput.js:12
d @ regeneratorRuntime.js:44
(anonyme) @ regeneratorRuntime.js:125
(anonyme) @ regeneratorRuntime.js:69
o @ asyncToGenerator.js:3
u @ asyncToGenerator.js:25
Promise.then (asynchrone)
o @ asyncToGenerator.js:12
i @ asyncToGenerator.js:22
(anonyme) @ asyncToGenerator.js:27
(anonyme) @ asyncToGenerator.js:19
(anonyme) @ SaveInput.js:7
Ae @ react-dom.production.min.js:54
Be @ react-dom.production.min.js:54
(anonyme) @ react-dom.production.min.js:55
jr @ react-dom.production.min.js:105
Mr @ react-dom.production.min.js:106
(anonyme) @ react-dom.production.min.js:117
cs @ react-dom.production.min.js:274
Le @ react-dom.production.min.js:52
$r @ react-dom.production.min.js:109
qt @ react-dom.production.min.js:74
Wt @ react-dom.production.min.js:73
xhr.js:251 POST http://localhost:5000/save net::ERR_CONNECTION_REFUSED
react_devtools_backend_compact.js:2367 K {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}code: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}stack: "AxiosError: Network Error\n at u.onerror (https://abnar.up.railway.app/static/js/main.0060d090.js:2:172793)"[[Prototype]]: Error
overrideMethod @ react_devtools_backend_compact.js:2367
(anonyme) @ SaveInput.js:12
d @ regeneratorRuntime.js:44
(anonyme) @ regeneratorRuntime.js:125
(anonyme) @ regeneratorRuntime.js:69
o @ asyncToGenerator.js:3
u @ asyncToGenerator.js:25
Promise.then (asynchrone)
o @ asyncToGenerator.js:12
i @ asyncToGenerator.js:22
(anonyme) @ asyncToGenerator.js:27
(anonyme) @ asyncToGenerator.js:19
(anonyme) @ SaveInput.js:7
Ae @ react-dom.production.min.js:54
Be @ react-dom.production.min.js:54
(anonyme) @ react-dom.production.min.js:55
jr @ react-dom.production.min.js:105
Mr @ react-dom.production.min.js:106
(anonyme) @ react-dom.production.min.js:117
cs @ react-dom.production.min.js:274
Le @ react-dom.production.min.js:52
$r @ react-dom.production.min.js:109
qt @ react-dom.production.min.js:74
Wt @ react-dom.production.min.js:73
xhr.js:251 POST http://localhost:5000/save net::ERR_CONNECTION_REFUSED
Brody
Brody2y ago
your app now needs to make requests to the backend domain of the railway service
wapeto
wapeto2y ago
ouhhh true
Brody
Brody2y ago
you are using sqlite right
wapeto
wapeto2y ago
but my backend keeps crashing yup
Brody
Brody2y ago
show logs please
wapeto
wapeto2y ago
Okay I just checked and it's because I need the server to run : python -m spacy download en_core_web_sm somehwere
Brody
Brody2y ago
okay hold on show me the table at the top of the build logs please
wapeto
wapeto2y ago
Brody
Brody2y ago
replace your railway.json file with this
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"nixpacksPlan": {
"phases": {
"download": {
"dependsOn": ["install"],
"cmds": ["python -m spacy download en_core_web_sm"]
}
}
}
},
"deploy": {
"startCommand": "gunicorn app:app"
}
}
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"nixpacksPlan": {
"phases": {
"download": {
"dependsOn": ["install"],
"cmds": ["python -m spacy download en_core_web_sm"]
}
}
}
},
"deploy": {
"startCommand": "gunicorn app:app"
}
}
you will also want to add the contents of this link https://www.toptal.com/developers/gitignore/api/python to a .gitignore file in your backend, and delete the __pycache__ folder in the repo
wapeto
wapeto2y ago
Thxx, sorry if Im not answering I'm dealing with the routes errors not, even though I changed the routes to the backend domain, it still sends requests to localhost:5000
Brody
Brody2y ago
you have it hard coded somewhere
wapeto
wapeto2y ago
My bad I was mistaken about the error, it's just that the search feature returns this error now :
SearchInput.js:22 Uncaught TypeError: Cannot read properties of undefined (reading 'map')
at Je (SearchInput.js:22:22)
at xl (react-dom.production.min.js:167:137)
at Pi (react-dom.production.min.js:197:258)
at xu (react-dom.production.min.js:292:88)
at ws (react-dom.production.min.js:280:389)
at gs (react-dom.production.min.js:280:320)
at ys (react-dom.production.min.js:280:180)
at ls (react-dom.production.min.js:271:88)
at os (react-dom.production.min.js:268:429)
at S (scheduler.production.min.js:13:203)
SearchInput.js:22 Uncaught TypeError: Cannot read properties of undefined (reading 'map')
at Je (SearchInput.js:22:22)
at xl (react-dom.production.min.js:167:137)
at Pi (react-dom.production.min.js:197:258)
at xu (react-dom.production.min.js:292:88)
at ws (react-dom.production.min.js:280:389)
at gs (react-dom.production.min.js:280:320)
at ys (react-dom.production.min.js:280:180)
at ls (react-dom.production.min.js:271:88)
at os (react-dom.production.min.js:268:429)
at S (scheduler.production.min.js:13:203)
And the code this comes from is the SearchInput.js :
import React, { useState } from "react";
import axios from "axios";

function SearchInput() {
const [input, setInput] = useState("");
const [results, setResults] = useState([]);

const handleSubmit = async () => {
try {
const response = await axios.post('abnar-backend.up.railway.app/search', { input });
setResults(response.data.results);
console.log("Searched!")
} catch (error) {
console.error(error);
}
};

return (
<div>
<input type="text" value={input} onChange={e => setInput(e.target.value)} />
<button onClick={handleSubmit}>Search</button>
{results.map((result, index) => (
<p key={index}>{result[0]} | Score: {result[1]}</p>

))}
</div>
);
}

export default SearchInput
import React, { useState } from "react";
import axios from "axios";

function SearchInput() {
const [input, setInput] = useState("");
const [results, setResults] = useState([]);

const handleSubmit = async () => {
try {
const response = await axios.post('abnar-backend.up.railway.app/search', { input });
setResults(response.data.results);
console.log("Searched!")
} catch (error) {
console.error(error);
}
};

return (
<div>
<input type="text" value={input} onChange={e => setInput(e.target.value)} />
<button onClick={handleSubmit}>Search</button>
{results.map((result, index) => (
<p key={index}>{result[0]} | Score: {result[1]}</p>

))}
</div>
);
}

export default SearchInput
Where results is set
Brody
Brody2y ago
you need to be using https
wapeto
wapeto2y ago
My bad
abnar.up.railway.app/:1 Access to XMLHttpRequest at 'https://abnar-backend.up.railway.app/save' from origin 'https://abnar.up.railway.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
abnar.up.railway.app/:1 Access to XMLHttpRequest at 'https://abnar-backend.up.railway.app/save' from origin 'https://abnar.up.railway.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Brody
Brody2y ago
your backend needs to have a cors origin for abnar.up.railway.app https://flask-cors.readthedocs.io/en/latest/
wapeto
wapeto2y ago
I have this :
wapeto
wapeto2y ago
should i add a ressource ?
Brody
Brody2y ago
what is something i could search for with your api show me the deploy logs for the backend
wapeto
wapeto2y ago
Well it's just some kind of memory, you input some text, when you save it labels it, and when you type some keywords in the searchbar, the most relevant texts shoudl show up
Brody
Brody2y ago
^
wapeto
wapeto2y ago
I'm sorry the error for the crash was my fault, it's solved now and the backend logs are empty :
[2023-06-04 22:07:08 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2023-06-04 22:07:08 +0000] [1] [INFO] Listening at: http://0.0.0.0:7940 (1)
[2023-06-04 22:07:08 +0000] [1] [INFO] Using worker: sync
[2023-06-04 22:07:08 +0000] [10] [INFO] Booting worker with pid: 10
['/app', '/opt/venv/bin', '/root/.nix-profile/lib/python38.zip', '/root/.nix-profile/lib/python3.8', '/root/.nix-profile/lib/python3.8/lib-dynload', '/opt/venv/lib/python3.8/site-packages']
[2023-06-04 22:07:08 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2023-06-04 22:07:08 +0000] [1] [INFO] Listening at: http://0.0.0.0:7940 (1)
[2023-06-04 22:07:08 +0000] [1] [INFO] Using worker: sync
[2023-06-04 22:07:08 +0000] [10] [INFO] Booting worker with pid: 10
['/app', '/opt/venv/bin', '/root/.nix-profile/lib/python38.zip', '/root/.nix-profile/lib/python3.8', '/root/.nix-profile/lib/python3.8/lib-dynload', '/opt/venv/lib/python3.8/site-packages']
Brody
Brody2y ago
do you actually use a sqlite database?
wapeto
wapeto2y ago
I do, this is were the texts and tokens are saved normally...
Brody
Brody2y ago
because railway doesn't have persistent storage, so on every deploy your sqlite database gets wiped you will want to use a database railway provides as a plugin
wapeto
wapeto2y ago
okay
Brody
Brody2y ago
have fun!
wapeto
wapeto2y ago
Thanks a lot for your help ! You are the proof humans are still smarter than machines (I spent 2 days on this problem and chatGPT cound't find any working solutions)
Brody
Brody2y ago
add a database of your choosing (use postgre) setup the variable references https://docs.railway.app/develop/variables#reference-variables use those variables in your code along with whatever postgre library you want
wapeto
wapeto2y ago
Will I still be able to run the project locally ?
Brody
Brody2y ago
i only know you used chatgpt because you had a railway.yml file, railway has never used a railway.yml file for anything
wapeto
wapeto2y ago
Well... It also made me create a whole lot of different Dockerfiles and other things
Brody
Brody2y ago
you will now run your app with railway run <your regular start command here> so that your app will have access to the database variables oh yeah that dockerfile was horrendous
wapeto
wapeto2y ago
in my local terminal I would type : railway run npm start ?
Brody
Brody2y ago
your frontend does not need the database variables, so you start that normally, your backend needs the database variables so you would use railway run <blah blah> to start your backend
wapeto
wapeto2y ago
okay thx a lot for that, one last question if I may ?
Brody
Brody2y ago
sure
wapeto
wapeto2y ago
This is how I created my original database in python
class Shard(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(500), nullable=False)
labels = db.Column(db.PickleType, nullable=False)
date = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now())
class Shard(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(500), nullable=False)
labels = db.Column(db.PickleType, nullable=False)
date = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now())
But I don't see the option for the label row in the postgre ui on railway labels would be lists of strings
Brody
Brody2y ago
now thats a question for google, i dont do too much with databases myself
wapeto
wapeto2y ago
Okay no problem, once again thanks for your help and time, you really saved me there
Brody
Brody2y ago
no problem 🙂
Want results from more Discord servers?
Add your server