Python Flask can't host Backend on my machine - python

So I wanted to host my backed on my machine for my website.
The Problem is I can't the frontend works perfectly but the Flask backend doesn't.
The backend works when I use localhost or my local ip to access it.
But doesn't work when I try to use it with the link :
https://desktop-1234567.1234567890qwert.myfritz.net:3182
(this one is fake)
It displays this error message :
So basically it says that it can't find the backend the Flask backend also dosen't react.
Even though I port forwarded the port 3182 with my-Fritz :
I also turned off Windows Firewall and it dosen't help
My Fritz is basically a free service from avm for Firtz-Box users (that's my Router)
It generates a sub domain where all your traffic is routed through this is useful since this url is static.
I tried it with a simpler backend :
from flask import Flask
app = Flask(__name__)
#app.route("/test")
def test():
return "<h1>Test</h1>"
if __name__ == "__main__":
app.run(
debug=False,
host='0.0.0.0',
port=3182,
threaded=True
)
and it also doesn't work it gives the same error message as above.
I also tried using waitress to host this simple app but it also won't work.
It has to be Flask since I can access my Frontend with the link on port 80 and 443.
I'm on Windows 10 and I hope somebody knows why this isn't working.
So yeah pleas help me I searched and it appears that no one had this exact problem before (But you never know on Stack Overflow)

Well I found out what the issue is.
The Issue is that I used "0.0.0.0" as the host parameter to run the app.
This tells flask to use IPV4, however I looked in to it and found out that "My Fritz" uses IPV6 so I just had to change the host parameter to use IPV6 by replacing "0.0.0.0" with ::.
That's it hope it helps, if anyone runs into the same issue as me.

Related

How to develop in production and development mode of Flask website

This is not a pure technical issue but more methodologic question.
I've seen Q&A regarding configuration for DEBUG and PRODUCTION ENVs but my question is concerning other issue.
When I started working on the project on my local machine I edited the hosts file to redirect www.example.com (I used the same URL for my live website) to 127.0.0.1 as I used to and it's working great.
Now when www.example.com is live, I wanted to know what is the right configuration for keep developing the website?
The only idea I came up with is to use www.example.org (So I won't lose actual access to www.example.com) in my hosts file and on the code to use IF DEBUG to redirect traffic to example.org instead of example.com but I feel there are better options.
I also would love some tips about the right way of working with git to post local updates to the live server.
When I want to access the website I'm running locally I just use http://127.0.0.1:5000 in my browser to access it.
If you've hardwired the domain "www.example.com" into your flask logic somewhere, i.e. when passing a redirect link to an OAuth service I would consider removing that hardcoded logic. Instead use an environment variable which you set differently on production/dev or else access to the current domain of a request with request.url_root or request.headers['Host'].
Make use of Flask's SERVER_NAME and PREFERRED_URL_SCHEME builtin configuration values.
class Config(object):
# blah blah
class DevelopmentConfig(Config):
SERVER_NAME = "example.local"
PREFERRED_URL_SCHEME = 'http'
class ProductionConfig(Config):
SERVER_NAME = "example.com"
PREFERRED_URL_SCHEME = 'https'
On your development machine map example.local to 127.0.0.1 .

Python Streamlit running on Heroku - how to get remote/client ip?

I was able to deploy an Streamlit App to Heroku. I did that to compare Heroku and Streamlit Share. Both runs fine, but I want to log client's IP (remote IP) to understand where my app is getting accessed from.
I'm googling for two days now without success. I saw a lot of posts related to the subject, most discussing how to get the real IP, where is it HTTP_X_FORWARDED_FOR and so on.
At first I understood that ENV['HTTP_X_FORWARDED_FOR'] was a environment var which I could get and parse using os.environ['HTTP_X_FORWARDED_FOR'] but it is not the case. I even tried request.headers['X-Forwarded-For'] which requires Flask but I learnt that Flask and Streamlit do not get along. Other solutions dealing with PHP/Java are beyond my knowledge.
So, my question is: "Is it possible to get remote IP using a Python package, without Flask?"
You can make the client inform the IP address to the host by using the streamlit-javascript package and inserting a JavaScript code that access an external service, e.g. api.ipify.org.
import streamlit as st
from streamlit_javascript import st_javascript
def client_ip():
url = 'https://api.ipify.org?format=json'
script = (f'await fetch("{url}").then('
'function(response) {'
'return response.json();'
'})')
try:
result = st_javascript(script)
if isinstance(result, dict) and 'ip' in result:
return result['ip']
except:
pass
ip_address = client_ip() # now you have it in the host...
st.write(ip_address) # so you can log it, etc.
It's not a perfect solution (as it won't be of any use inside a NAT, for instance), but I think it's as far as you can go with Streamlit.
Of course, acquiring the request IP from Tornado (the webserver) could be a Streamlit feature, but it isn't just yet.

How do I deploy my Python Flask dev app so other devices across the network (Wifi) can also access it?

This is my app.py file:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return "Hello World!"
app.run(host = '192.168.2.18', debug=False)
I've used the netstat command in Windows and that's how I know to use '192.168.2.18' When I run the file, it appears to run on port 5000
Please see pic below:
However, when I try to access this url from another device over the network, I don't see it. I only see it on my machine.
I've tried various solutions most notably from this popular thread:
Configure Flask dev server to be visible across the network
If you update the host ip in your code to 0.0.0.0, then your app will start listening all the public IPs.
app.run(host='0.0.0.0')
You can read here in the flask docs.
Now for someone to access your page, they have to navigate to this url -
http://your.machine.ip:5000/
You can also give any specific port you want your application to run at, lets say 4000 (default port is 5000)
app.run(host='0.0.0.0', port=4000)
You can even give your machine name in place of your machine ip in the url, just incase your ip is not static.
I tell you a secret, run:
python3 -m http.server
and the directory in which you are will be available through all the network.
In this example I'm visiting my Pictures folder and as you can see is available at http://0.0.0.0:8000/
Since you have mentioned, you already tried the solutions from this post, here's something I think you can try because I was facing this same problem once and this is what I was missing, and it's overlooked a lot of times.
If you are a Windows user, check your Network and sharing settings, and turn it ON for sharing on a private network. Something like this:
Also, make sure your IP address in the code below is correct (because IP address changes all the time when you connect your laptop/computer over Wi-Fi), so check the current IP by running ipconfig in cmd right before running your code, not the one you wrote a week ago.
Few changes in the code:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return "Hello World!"
if __name__ == "__main__":
#app.run(host='0.0.0.0',port=5000) //doesn't work for me
app.run(host='192.168.2.18', port=5000)
And finally, run your code with flask run -h 192.168.X.X, in the screenshot you shared, you entered flask run --host 192.168.X.X, I m not sure why, but --h doesn't work for me.
And, I hope you also check you are entering the address properly, like http://192.168.2.18:5000, not https.
Sometimes silly stuff can get in the way too :|

Can a REST API built with Flask and Python be accessed from an external network?

I'm trying to use a REST API, built using Flask and Python, to create a server from my Raspberry Pi and access it from my iPhone. I have a very simple question: can I access the server from a network other than the one it is created on? So, for example, if the server is created on my home wifi, can I access it from my workplace wifi? If so, how?
Currently, I can access the server from any device connected to the same network. I have seen many similar posts online about similar problems, but I cannot find a direct answer to my question above.
Here is my code:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route("/test")
def hello():
return jsonify({"about":"Hello World"})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=2000,debug=True)
If I go onto Safari on my iPhone when connected to mobile data and type in "http://RaspberryPiIP:2000/test", then the page will not load and "take too long to respond." However, if I do the same thing on my home wifi, which the raspberry pi is also connected to, the page will load as expected.
This has nothing to do with your code. You just need to route the requests from your external (public) IP address to the internal IP address of the server in your network. If you are at home, you need to configurate your router. This is often called port forwarding or port mapping.
You may also want to use a dynamic dns service, because most external ips will be changed frequently by your ISP.
In order to access some thing on the internet you need static IP address which will not change like dynamic IPs that your ISP assigns to you. However there are services like this that will provide you with dns name pointed to your dynamic IP address also you need to do some port forwarding which is not safe.

Web.py routing when added nginx as upstream

I've been writing a client side app and a server side app as two separate apps and I want the client to use the server. The client is written in javascript and the server is written in python using web.py as the engine to deliver to the client. The client and server must be on the same web domain.
The server part has a route defined as:
'/data/(.*)', 'applicationserver.routes.Data.Data'
This works fine running it locally using http://buildserver/data/transform
I'm setting it up as a site in nginx like this:
upstream app {
server 127.0.0.1:8081
}
and adding it to the web application like this:
location /server {
...
proxy_pass
}
The new path to the route would be ` but for obvious reasons this will not work as the server app is listening for/dataand not/server/data`.
I have tried to change the route in python to (.*)/data/(.*) which sort of works except that it throws the error:
<type 'exceptions.TypeError'> at /data/transform
GET() takes exactly 2 arguments (3 given)
I figured out what was going on just before posting but I hope I can help someone else by posting this anyway.
web.py is sending the matched group to the GET and therefor using (.*)/data/(.*) sent both the start and the end of the path to the GET which is why it failed.
Setting the route to .*/data/(.*) gave me what I was after and only sent the part after data to the GET function.

Categories

Resources