Python Heroku 上的 Streamlit 运行 - 如何获取 remote/client ip?

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

我能够将 Streamlit 应用程序部署到 Heroku。我这样做是为了比较 Heroku 和 Streamlit Share。两者都运行良好,但我想记录客户端的 IP(远程 IP)以了解从何处访问我的应用程序。

我在谷歌上搜索了两天,但没有成功。看了很多跟这个话题相关的帖子,大部分都是在讨论如何获取真实IP,在哪HTTP_X_FORWARDED_FOR之类的

起初我知道 ENV['HTTP_X_FORWARDED_FOR'] 是一个环境变量,我可以使用 os.environ['HTTP_X_FORWARDED_FOR'] 获取和解析它,但事实并非如此。我什至尝试了需要 Flask 的 request.headers['X-Forwarded-For'],但我了解到 Flask 和 Streamlit 不能相处。处理 PHP/Java 的其他解决方案不在我的知识范围内。

所以,我的问题是:“是否可以在没有 Flask 的情况下使用 Python 包获取远程 IP?”

您可以通过使用 streamlit-javascript 包并插入一个 JavaScript 访问外部服务的代码,使客户端将 IP 地址告知主机,例如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.

这不是一个完美的解决方案(因为它在 NAT 中没有任何用处,例如),但我认为这是您可以使用 Streamlit 的极限。

当然,从 Tornado(网络服务器)获取请求 IP 可能是 Streamlit 的一项功能,but it isn't just yet