From cdec8d1af306b1409773c5b260daab18e5e70721 Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sat, 5 Apr 2025 11:09:11 +0000 Subject: [PATCH 1/7] Configure Dockerfile to install system dependencies --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ccc4552..dd9fba3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM cs50/cli -RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader postgresql +RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader postgresql build-essential pkg-config libpq-dev RUN sudo pip3 install mysqlclient psycopg2-binary +RUN sudo rm -rf /var/lib/apt/lists/* WORKDIR /mnt From eca10037c8cd4d971017b9ea2ff9810df059e2cd Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sat, 5 Apr 2025 11:10:31 +0000 Subject: [PATCH 2/7] Remove the deprecated `version` attribute --- docker-compose.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8608080..1db4a9b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: container_name: python-cs50 depends_on: - mysql - - postgres + - postgres environment: MYSQL_HOST: mysql POSTGRESQL_HOST: postgres @@ -30,5 +30,4 @@ services: POSTGRES_PASSWORD: postgres POSTGRES_DB: test ports: - - 5432:5432 -version: "3.6" + - 5432:5432 From 752cb7bbae7af5da4add80ebcc79c663e699faef Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sat, 5 Apr 2025 12:10:04 +0000 Subject: [PATCH 3/7] Added foo.db test file to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd3ffcc..161abdc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ build/ *.db *.egg-info/ *.pyc +foo.db From a52d0c7d966e700bf6ba903367373ffab6da7aaa Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sat, 5 Apr 2025 12:14:15 +0000 Subject: [PATCH 4/7] Fix deprecated warnings from pkgutil.get_loader --- src/cs50/flask.py | 84 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/src/cs50/flask.py b/src/cs50/flask.py index 6e38971..4599eaf 100644 --- a/src/cs50/flask.py +++ b/src/cs50/flask.py @@ -1,47 +1,101 @@ import os -import pkgutil +# import pkgutil # Removed pkgutil import sys +import importlib.util # Added importlib.util def _wrap_flask(f): + """ + Wraps the Flask class's __init__ method if necessary, + primarily to add ProxyFix for CS50 IDE online environments. + """ if f is None: return - from packaging.version import Version, InvalidVersion - from .cs50 import _formatException + # Dynamically import packaging only when needed + try: + from packaging.version import Version, InvalidVersion + except ImportError: + # If packaging is not installed, cannot check version, so assume we can't wrap + return + + # Avoid importing cs50 unless absolutely necessary (within the version check) + # from .cs50 import _formatException # _formatException is not used in this function try: + # Check Flask version compatibility if Version(f.__version__) < Version("1.0"): return - except InvalidVersion: + except (InvalidVersion, AttributeError): + # Handle invalid version strings or if Flask doesn't have __version__ + return + except Exception: + # Chnage `except:` to `except Exception:` to align with best practices + # Catch any other unexpected errors during version check return + # Apply ProxyFix only in CS50 IDE online environment if os.getenv("CS50_IDE_TYPE") == "online": - from werkzeug.middleware.proxy_fix import ProxyFix + try: + from werkzeug.middleware.proxy_fix import ProxyFix + except ImportError: + # If werkzeug (a Flask dependency) is missing or ProxyFix moved, cannot apply fix + return + # Get the original Flask.__init__ _flask_init_before = f.Flask.__init__ + # Define the wrapped __init__ method def _flask_init_after(self, *args, **kwargs): _flask_init_before(self, *args, **kwargs) + # Apply ProxyFix for handling reverse proxies (like the one in CS50 IDE) + # x_proto=1 tells ProxyFix to trust the X-Forwarded-Proto header self.wsgi_app = ProxyFix( self.wsgi_app, x_proto=1 - ) # For HTTPS-to-HTTP proxy + ) + # Monkey-patch Flask's __init__ f.Flask.__init__ = _flask_init_after -# If Flask was imported before cs50 +# --- Main Logic --- + +# Check if Flask was already imported before cs50 library was imported if "flask" in sys.modules: _wrap_flask(sys.modules["flask"]) -# If Flask wasn't imported +# If Flask hasn't been imported yet, set up patching for when it *is* imported else: - flask_loader = pkgutil.get_loader("flask") - if flask_loader: - _exec_module_before = flask_loader.exec_module + # Find the module specification for Flask using the recommended importlib utility + # This replaces the deprecated pkgutil.get_loader + flask_spec = importlib.util.find_spec("flask") + + # Check if the spec was found and if it has a loader + # (Some namespace packages might not have a loader, but Flask should) + if flask_spec and flask_spec.loader: + + # Ensure the loader has the exec_module method (standard loaders do) + if hasattr(flask_spec.loader, 'exec_module'): + + # Get the original exec_module method from the loader + _exec_module_before = flask_spec.loader.exec_module + + # Define a wrapper function for exec_module + # This function will be called by the import system when Flask is loaded + def _exec_module_after(module): + # Execute the original module loading logic first + _exec_module_before(module) + # Now that the module ('flask') is fully loaded and present in sys.modules, + # apply our custom wrapping logic. + _wrap_flask(module) # Pass the loaded module object to _wrap_flask + + # Monkey-patch the loader's exec_module method with our wrapper + flask_spec.loader.exec_module = _exec_module_after - def _exec_module_after(*args, **kwargs): - _exec_module_before(*args, **kwargs) - _wrap_flask(sys.modules["flask"]) + # else: + # Optional: Handle the unlikely case where the loader doesn't have exec_module + # pass or log a warning if necessary - flask_loader.exec_module = _exec_module_after + # else: + # Optional: Handle the case where Flask spec wasn't found (Flask not installed?) + # pass or log a warning if necessary \ No newline at end of file From 7257d5696ac8cfaf1ea57be93601b0e33a760d25 Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sun, 13 Apr 2025 03:54:15 +0000 Subject: [PATCH 5/7] resolve Dockerfile --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index dd9fba3..cd01b8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,6 @@ FROM cs50/cli -RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader postgresql build-essential pkg-config libpq-dev +RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader postgresql pkg-config && sudo rm -rf /var/lib/apt/lists/* RUN sudo pip3 install mysqlclient psycopg2-binary -RUN sudo rm -rf /var/lib/apt/lists/* WORKDIR /mnt From 99ce28bf7aaa8acbd934364436ebf29d163d8b28 Mon Sep 17 00:00:00 2001 From: Shoaib-Programmer Date: Sun, 13 Apr 2025 04:02:12 +0000 Subject: [PATCH 6/7] resolve flask.py --- src/cs50/flask.py | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/cs50/flask.py b/src/cs50/flask.py index 4599eaf..f79e6e5 100644 --- a/src/cs50/flask.py +++ b/src/cs50/flask.py @@ -1,7 +1,7 @@ import os -# import pkgutil # Removed pkgutil import sys -import importlib.util # Added importlib.util +import importlib.util +import warnings def _wrap_flask(f): @@ -19,8 +19,6 @@ def _wrap_flask(f): # If packaging is not installed, cannot check version, so assume we can't wrap return - # Avoid importing cs50 unless absolutely necessary (within the version check) - # from .cs50 import _formatException # _formatException is not used in this function try: # Check Flask version compatibility @@ -30,8 +28,6 @@ def _wrap_flask(f): # Handle invalid version strings or if Flask doesn't have __version__ return except Exception: - # Chnage `except:` to `except Exception:` to align with best practices - # Catch any other unexpected errors during version check return # Apply ProxyFix only in CS50 IDE online environment @@ -42,17 +38,12 @@ def _wrap_flask(f): # If werkzeug (a Flask dependency) is missing or ProxyFix moved, cannot apply fix return - # Get the original Flask.__init__ _flask_init_before = f.Flask.__init__ - # Define the wrapped __init__ method def _flask_init_after(self, *args, **kwargs): _flask_init_before(self, *args, **kwargs) - # Apply ProxyFix for handling reverse proxies (like the one in CS50 IDE) - # x_proto=1 tells ProxyFix to trust the X-Forwarded-Proto header - self.wsgi_app = ProxyFix( - self.wsgi_app, x_proto=1 - ) + # Apply ProxyFix to handle reverse proxies in CS50 IDE (x_proto=1 trusts X-Forwarded-Proto header) + self.wsgi_app = ProxyFix(self.wsgi_app, x_proto=1) # Monkey-patch Flask's __init__ f.Flask.__init__ = _flask_init_after @@ -92,10 +83,10 @@ def _exec_module_after(module): # Monkey-patch the loader's exec_module method with our wrapper flask_spec.loader.exec_module = _exec_module_after - # else: - # Optional: Handle the unlikely case where the loader doesn't have exec_module - # pass or log a warning if necessary + else: + # Handle the unlikely case where the loader doesn't have exec_module + warnings.warn("Flask loader doesn't support the expected exec_module interface") - # else: - # Optional: Handle the case where Flask spec wasn't found (Flask not installed?) - # pass or log a warning if necessary \ No newline at end of file + else: + # Handle the case where Flask spec wasn't found (Flask not installed?) + warnings.warn("Flask module specification not found. Flask may not be installed.") \ No newline at end of file From 089a18afb56035ddc33bda725a36296f141f5c60 Mon Sep 17 00:00:00 2001 From: Shoaib Nigam Shaik Date: Wed, 23 Apr 2025 10:20:17 +0530 Subject: [PATCH 7/7] Alphabetized imports in flask.py --- src/cs50/flask.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cs50/flask.py b/src/cs50/flask.py index f79e6e5..c079cb5 100644 --- a/src/cs50/flask.py +++ b/src/cs50/flask.py @@ -1,6 +1,6 @@ +import importlib.util import os import sys -import importlib.util import warnings @@ -89,4 +89,4 @@ def _exec_module_after(module): else: # Handle the case where Flask spec wasn't found (Flask not installed?) - warnings.warn("Flask module specification not found. Flask may not be installed.") \ No newline at end of file + warnings.warn("Flask module specification not found. Flask may not be installed.")