[REF-3633] [main] Introduce a workaround for enterprise users who get stuck with httpx.get SSL (#3847)

* [REF-3633] Introduce a workaround for enterprise users who get stuck with httpx.get SSL

Setting SSL_NO_VERIFY=1 will disable SSL verification during `reflex init`

* Also install fnm using `reflex.utils.net.get`
This commit is contained in:
Masen Furer 2024-08-28 09:33:31 -07:00 committed by GitHub
parent be71254250
commit 3fa9f1fc06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 12 deletions

43
reflex/utils/net.py Normal file
View File

@ -0,0 +1,43 @@
"""Helpers for downloading files from the network."""
import os
import httpx
from . import console
def _httpx_verify_kwarg() -> bool:
"""Get the value of the HTTPX verify keyword argument.
Returns:
True if SSL verification is enabled, False otherwise
"""
ssl_no_verify = os.environ.get("SSL_NO_VERIFY", "").lower() in ["true", "1", "yes"]
return not ssl_no_verify
def get(url: str, **kwargs) -> httpx.Response:
"""Make an HTTP GET request.
Args:
url: The URL to request.
**kwargs: Additional keyword arguments to pass to httpx.get.
Returns:
The response object.
Raises:
httpx.ConnectError: If the connection cannot be established.
"""
kwargs.setdefault("verify", _httpx_verify_kwarg())
try:
return httpx.get(url, **kwargs)
except httpx.ConnectError as err:
if "CERTIFICATE_VERIFY_FAILED" in str(err):
# If the error is a certificate verification error, recommend mitigating steps.
console.error(
f"Certificate verification failed for {url}. Set environment variable SSL_CERT_FILE to the "
"path of the certificate file or SSL_NO_VERIFY=1 to disable verification."
)
raise

View File

@ -34,7 +34,7 @@ from reflex import constants, model
from reflex.base import Base
from reflex.compiler import templates
from reflex.config import Config, get_config
from reflex.utils import console, path_ops, processes
from reflex.utils import console, net, path_ops, processes
from reflex.utils.format import format_library_name
from reflex.utils.registry import _get_best_registry
@ -80,7 +80,7 @@ def check_latest_package_version(package_name: str):
# Get the latest version from PyPI
current_version = importlib.metadata.version(package_name)
url = f"https://pypi.org/pypi/{package_name}/json"
response = httpx.get(url)
response = net.get(url)
latest_version = response.json()["info"]["version"]
if (
version.parse(current_version) < version.parse(latest_version)
@ -670,7 +670,7 @@ def download_and_run(url: str, *args, show_status: bool = False, **env):
"""
# Download the script
console.debug(f"Downloading {url}")
response = httpx.get(url)
response = net.get(url)
if response.status_code != httpx.codes.OK:
response.raise_for_status()
@ -700,11 +700,11 @@ def download_and_extract_fnm_zip():
try:
# Download the FNM zip release.
# TODO: show progress to improve UX
with httpx.stream("GET", url, follow_redirects=True) as response:
response.raise_for_status()
with open(fnm_zip_file, "wb") as output_file:
for chunk in response.iter_bytes():
output_file.write(chunk)
response = net.get(url, follow_redirects=True)
response.raise_for_status()
with open(fnm_zip_file, "wb") as output_file:
for chunk in response.iter_bytes():
output_file.write(chunk)
# Extract the downloaded zip file.
with zipfile.ZipFile(fnm_zip_file, "r") as zip_ref:
@ -1222,7 +1222,7 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
"""
def get_release_by_tag(tag: str) -> dict | None:
response = httpx.get(constants.Reflex.RELEASES_URL)
response = net.get(constants.Reflex.RELEASES_URL)
response.raise_for_status()
releases = response.json()
for release in releases:
@ -1243,7 +1243,7 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
else:
templates_url = asset["browser_download_url"]
templates_data = httpx.get(templates_url, follow_redirects=True).json()["templates"]
templates_data = net.get(templates_url, follow_redirects=True).json()["templates"]
for template in templates_data:
if template["name"] == "blank":
@ -1286,7 +1286,7 @@ def create_config_init_app_from_remote_template(app_name: str, template_url: str
zip_file_path = Path(temp_dir) / "template.zip"
try:
# Note: following redirects can be risky. We only allow this for reflex built templates at the moment.
response = httpx.get(template_url, follow_redirects=True)
response = net.get(template_url, follow_redirects=True)
console.debug(f"Server responded download request: {response}")
response.raise_for_status()
except httpx.HTTPError as he:
@ -1417,7 +1417,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash:
generation_hash: The generation hash from reflex.build.
"""
# Download the reflex code for the generation.
resp = httpx.get(
resp = net.get(
constants.Templates.REFLEX_BUILD_CODE_URL.format(
generation_hash=generation_hash
)