Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions reflex/utils/net.py
Original file line number Diff line number Diff line change
@@ -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
24 changes: 12 additions & 12 deletions reflex/utils/prerequisites.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -1243,7 +1243,7 @@ def get_release_by_tag(tag: str) -> dict | None:
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":
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
)
Expand Down
Loading