[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:
parent
be71254250
commit
3fa9f1fc06
43
reflex/utils/net.py
Normal file
43
reflex/utils/net.py
Normal 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
|
@ -34,7 +34,7 @@ from reflex import constants, model
|
|||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.compiler import templates
|
from reflex.compiler import templates
|
||||||
from reflex.config import Config, get_config
|
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.format import format_library_name
|
||||||
from reflex.utils.registry import _get_best_registry
|
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
|
# Get the latest version from PyPI
|
||||||
current_version = importlib.metadata.version(package_name)
|
current_version = importlib.metadata.version(package_name)
|
||||||
url = f"https://pypi.org/pypi/{package_name}/json"
|
url = f"https://pypi.org/pypi/{package_name}/json"
|
||||||
response = httpx.get(url)
|
response = net.get(url)
|
||||||
latest_version = response.json()["info"]["version"]
|
latest_version = response.json()["info"]["version"]
|
||||||
if (
|
if (
|
||||||
version.parse(current_version) < version.parse(latest_version)
|
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
|
# Download the script
|
||||||
console.debug(f"Downloading {url}")
|
console.debug(f"Downloading {url}")
|
||||||
response = httpx.get(url)
|
response = net.get(url)
|
||||||
if response.status_code != httpx.codes.OK:
|
if response.status_code != httpx.codes.OK:
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
@ -700,7 +700,7 @@ def download_and_extract_fnm_zip():
|
|||||||
try:
|
try:
|
||||||
# Download the FNM zip release.
|
# Download the FNM zip release.
|
||||||
# TODO: show progress to improve UX
|
# TODO: show progress to improve UX
|
||||||
with httpx.stream("GET", url, follow_redirects=True) as response:
|
response = net.get(url, follow_redirects=True)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
with open(fnm_zip_file, "wb") as output_file:
|
with open(fnm_zip_file, "wb") as output_file:
|
||||||
for chunk in response.iter_bytes():
|
for chunk in response.iter_bytes():
|
||||||
@ -1222,7 +1222,7 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_release_by_tag(tag: str) -> dict | None:
|
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()
|
response.raise_for_status()
|
||||||
releases = response.json()
|
releases = response.json()
|
||||||
for release in releases:
|
for release in releases:
|
||||||
@ -1243,7 +1243,7 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
|
|||||||
else:
|
else:
|
||||||
templates_url = asset["browser_download_url"]
|
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:
|
for template in templates_data:
|
||||||
if template["name"] == "blank":
|
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"
|
zip_file_path = Path(temp_dir) / "template.zip"
|
||||||
try:
|
try:
|
||||||
# Note: following redirects can be risky. We only allow this for reflex built templates at the moment.
|
# 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}")
|
console.debug(f"Server responded download request: {response}")
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except httpx.HTTPError as he:
|
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.
|
generation_hash: The generation hash from reflex.build.
|
||||||
"""
|
"""
|
||||||
# Download the reflex code for the generation.
|
# Download the reflex code for the generation.
|
||||||
resp = httpx.get(
|
resp = net.get(
|
||||||
constants.Templates.REFLEX_BUILD_CODE_URL.format(
|
constants.Templates.REFLEX_BUILD_CODE_URL.format(
|
||||||
generation_hash=generation_hash
|
generation_hash=generation_hash
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user