You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google App Engine部署Python Web应用后图表无法加载,SSLCertVerificationError与URLError问题求助

Fixing SSL Certificate Verify Failed (Hostname Mismatch) on Google App Engine Deployment

Hey there, let’s break down why your charts aren’t loading after deploying to GAE and walk through how to fix it.

What’s Causing the Error?

The SSLCertVerificationError you’re seeing boils down to a hostname mismatch in SSL certificate validation:

  • The Orbital library you’re using is likely hardcoding requests to www.celestrak.org, but Celestrak’s current SSL certificate is only valid for the root domain (celestrak.org)—no www prefix.
  • Your local environment probably has looser SSL verification rules or already trusts the misconfigured cert, but GAE’s Python runtime enforces strict certificate checks for security, which triggers the error.

Step-by-Step Solutions

1. Manually Fetch TLE Data (Bypass Library’s Broken Request)

Instead of relying on the Orbital library’s internal data fetch (which uses the wrong domain), pull the TLE data yourself using the correct Celestrak domain, then pass it to the Orbital object. Here’s how to modify your callback code:

import requests
from orbital import Orbital
from datetime import datetime, timedelta
import pandas as pd
import plotly.graph_objects as go

def fetch_tle(sat_name):
    # Use Celestrak's root domain (no www) for valid SSL
    tle_url = f"https://celestrak.org/NORAD/elements/gp.php?NAME={sat_name}&FORMAT=TLE"
    # For temporary testing only: add verify=False to skip cert checks (not safe for production!)
    response = requests.get(tle_url)
    tle_lines = response.text.strip().split('\n')
    return tle_lines[0], tle_lines[1]

@app.callback(
    Output('satellite map', 'figure'), 
    Output('altitude chart', 'figure'),
    Input('interval-component', 'n_intervals'),
    Input('satellites dropdown', 'value')
)
def plot_map(n, satellite_name):
    try:
        # Fetch TLE data manually instead of using Orbital's internal call
        tle_line1, tle_line2 = fetch_tle(satellite_name)
        orb = Orbital(satellite_name, line1=tle_line1, line2=tle_line2)
        
        lon_list = []
        lat_list = []
        alt_list = []
        obj_name_list = []
        time_list = []
        time = datetime.now()
        
        lon, lat = orb.get_lonlatalt(time)[0], orb.get_lonlatalt(time)[1]
        lon_list.append(lon)
        lat_list.append(lat)
        obj_name_list.append(satellite_name)
        
        for i in range(121):
            time_list.append(time - timedelta(minutes=i))
        for i in time_list:
            alt_list.append(orb.get_lonlatalt(i)[2])
        
        df_4 = pd.DataFrame({'ObjectName': obj_name_list, 'Latitude': lat_list, 'Longitude': lon_list})
        df_5 = pd.DataFrame({'TimeStamp': time_list, 'Altitude': alt_list})
        
        # Your existing figure rendering code stays unchanged
        fig = go.Figure(go.Scattermapbox(
            lat=df_4['Latitude'],
            lon=df_4['Longitude'],
            marker={'size': 20, 'symbol':'rocket'},
            hovertext=df_4['ObjectName'],
        ))
        fig.update_layout(
            mapbox={'accesstoken': api_token, 'style': 'light', 'zoom': 0},
            margin=dict(l=0, r=0, t=0, b=0),
            height=800,
            hovermode='closest'
        )
        
        fig2 = go.Figure(go.Scatter(x=df_5['TimeStamp'], y=df_5['Altitude']))
        fig2.update_layout(
            margin=dict(l=20, r=20, t=20, b=20),
            plot_bgcolor='rgb(255,255,255)',
            paper_bgcolor='rgb(255,255,255)',
            height=800,
            title={'text': f'Altitude Trend of {satellite_name} in near real time', 'x':0.5, 'y':0.98},
        ).update_yaxes(gridcolor='rgb(243,243,243)', title='Altitude (km)').update_xaxes(title='Timestamp', linecolor='rgb(243,243,243)')
        
        return fig, fig2
    except NotImplementedError:
        pass
    except Exception as e:
        # Log errors for debugging in GAE
        print(f"Error encountered: {e}")
        # Return empty figures to avoid breaking the app
        return go.Figure(), go.Figure()

2. Update Your GAE Python Runtime

Ensure your app.yaml uses a recent Python runtime (3.9 or later). Older versions may have outdated root CA certificates that don’t recognize Celestrak’s current SSL cert. Example app.yaml snippet:

runtime: python311
service: default

3. Avoid Bypassing SSL Verification (Unless Testing)

While adding verify=False to the requests.get() call will temporarily fix the error, it’s a security risk and not recommended for production. Only use this to confirm the domain mismatch is the root cause.

Extra Tips

  • Check Celestrak’s official documentation to confirm their valid HTTPS endpoints—they may have updated their domain structure recently.
  • Enable detailed logging in GAE to see exactly which request is failing, helping you target fixes more precisely.
  • Cache TLE data locally (using GAE’s memcache or Datastore) to reduce repeated requests to Celestrak, avoiding rate limits and repeated SSL verification issues.

内容的提问来源于stack exchange,提问作者Oladayo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:02:45