WSGIPythonHome may indeed work on Windows now. It wasn't originally from memory as the Python C APIs to support it on Windows were broken. I use a hack to make it work now I think.
Environment variables are a thing mainly used on UNIX systems rather than on Windows. You don't have to use them to inject config into applications, but I think that is the only way Django supports DJANGO_SETTINGS_MODULE. Anyway, try not using WSGIPythonPath. Instead, at the start of the WSGI script file, what you reference using WSGIScriptAlias, set the Python module path explicitly in Python code before anything else. Thus one script file would use: import sys, os sys.path.insert(0, "C:/.../website_projects/example1.com <http://example1.com/>") os.environ["DJANGO_SETTINGS_MODULE"] = "main.settings" and the other: import sys, os sys.path.insert(0, "C:/.../website_projects/example2.com <http://example1.com/>") os.environ["DJANGO_SETTINGS_MODULE"] = "main.settings" Follow this will original contents of the file. This way the Python module path changes are specific to each Python sub interpreter context and not setting it globally such that all inherit the same. Graham > On 13 Feb 2025, at 6:08 am, SC <[email protected]> wrote: > > Thanks for the article. I followed through on making that one change to my > wsgi.py configuration, and (after making two other changes) things are > working on my end. > > One of the other changes was to move WSGIPythonPath outside of the virtual > hosts, then use both paths within the same directive (separated by a > semicolon). > > However, there is one point of a lack of understanding on my part that's > bothering me. What exactly is an environment variable, and why is it even > needed? (Why not just read a value from a text file? - I understand these > questions are on the topic of Django moreso than WSGI, so if it's too out of > scope, then I'll bring it up over there rather than here.) I'm asking because > each one of my website projects has the following file structure: > website-name-here1.com <http://website-name-here1.com/> > | > ---- manage.py > | > ---- main > | > ---- app1 > | > ---- app2 > | > ... > > Normally, when running Django's "startproject" command as per their tutorial, > you get: > websitenamehere1com > | > ---- manage.py > | > ---- websitenamehere1com > | > ---- app1 > | > ---- app2 > | > ... > > Personally, I found the semantics of this default way of naming things > unacceptable (to my mind), so I changed it to the above. This is a convention > I would strongly prefer to keep. However, this ended up with the very first > Django instance running fine, and the second Django instance throwing 400 > "Bad Request" errors to the client. > More specifically, if I configured WSGIPythonPath to > "C:/.../website_projects/example1.com;C:/.../website_projects/example2.com > <http://example2.com/>", it will be example2.com <http://example2.com/> that > throws 400 errors. If I reverse the order of that configuration, it will be > example1.com <http://example1.com/> that throws 400 errors. Both > website-projects had their folder named "main" (i.e. the same name), so > naturally, both of their wsgi.py files had: > os.environ['DJANGO_SETTINGS_MODULE'] = 'main.settings' > > While I had already suspected that this could cause problems (reusing the > same name, "main") when running multiple instances, I do not have a detailed > understanding of why. I thought that we would have one Apache process > spawning two Python processes (I should note that I have next to no > understanding of systems programming, Apache, WSGI, etc.), and each Python > process would have its own local set of environment variables and look only > within its own directory (as specified in WSGIPythonPath). It could > inexplicably be the case that setting the environment variable, > "DJANGO_SETTINGS_MODULE", is global, and therefore sets the value > "main.settings" for both Django instances, but even if this were the case, it > shouldn't matter. (I.e. they both use the same value for that variable - > unless it somehow gets resolved behind the scenes to an absolute filepath.) > So it might instead have to do with WSGIPythonPath being confused as to which > "main.settings" it should be picking from the two paths that I configured for > it. > > Either way, while I have a "fix", I would like to understand what is going on > here and whether the above convention can be kept with some workaround. > > Also, off-topic; the current docs state that the WSGIPythonHome directive is > not available on Windows > <https://www.modwsgi.org/en/latest/configuration-directives/WSGIPythonHome.html>, > but it appears to be required to have around, or else Django will throw an > error. > On Tuesday, February 11, 2025 at 2:12:41 AM UTC-6 Graham Dumpleton wrote: >> Have a read of: >> >> * http://blog.dscpl.com.au/2012/10/requests-running-in-wrong-django.html >> >> and see if it answers your questions. >> >> Most likely since using Django any problems will be due to how >> DJANGO_SETTINGS_MODULE is set. The default that project template generates >> causes problems and you need to change it. >> >> Graham >> >> >>> On 11 Feb 2025, at 2:30 pm, SC <[email protected] <>> wrote: >>> >> >>> Firstly, I'd like to thank you for maintaining this excellent utility. >>> >>> I should note that I am not a technically-versed person in these matters, >>> so apologies if I am slow to pick up on things. >>> >>> As for my problem, I want to host multiple Django-based websites from the >>> same httpd.exe process on Windows. I do not know how to go about this. >>> >>> Details on my setup: >>> - mod_wsgi (v5.0.0) >>> - Python (v3.9.2) >>> - Apache (v2.4.58), with the binaries being distributed by ApacheLounge >>> (2024-01-31 release) >>> - Windows Server 2012 R1 (and not R2) >>> - Django v4.2.10 >>> - I am hosting two distinct domain names (e.g. "someexample.com >>> <http://someexample.com/>" and "anotherexample.com >>> <http://anotherexample.com/>") >>> - Everything is set up from scratch in the sense that I have physical >>> access to the machine running the web server, access to the domain names, >>> access to the router, etc. >>> - Because I am running Windows, I am running mod_wsgi in embedded mode. My >>> installation of Apache is mostly standard, so something like mod_python is >>> not installed. >>> >>> Here is the relevant snippet of Apache configuration. I am aware that it >>> does not run (because WSGIPythonPath cannot be in a VirtualHost directive), >>> but it encapsulates the logic of what I am trying to go for: >>> >>> LoadFile >>> "C:/Users/Administrator/AppData/Local/Programs/Python/Python39/python39.dll" >>> LoadModule wsgi_module >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/python_virtual_environment/lib/site-packages/mod_wsgi/server/mod_wsgi.cp39-win_amd64.pyd" >>> >>> WSGIPythonHome >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/python_virtual_environment" >>> >>> >>> # VIRTUAL HOST: "someexample.com <http://someexample.com/>" >>> >>> <VirtualHost *:80> >>> ServerName someexample.com <http://someexample.com/> >>> ServerAlias www.someexample.com <http://www.someexample.com/> >>> Redirect permanent "/" "https://someexample.com/" >>> </VirtualHost> >>> >>> <VirtualHost *:443> >>> ServerName someexample.com <http://someexample.com/> >>> ServerAlias someexample.com <http://someexample.com/> >>> <If "%{HTTP_HOST} == 'www.someexample.com >>> <http://www.someexample.com/>'"> >>> Redirect "/" "https://someexample.com/" >>> </If> >>> >>> SSLEngine On >>> SSLCertificateFile "..." >>> SSLCertificateKeyFile "..." >>> >>> WSGIScriptAlias / >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/someexample.com/main/wsgi.py >>> <http://someexample.com/main/wsgi.py>" >>> WSGIPythonPath >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/someexample.com >>> <http://someexample.com/>" >>> >>> <Directory >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/someexample.com/main >>> <http://someexample.com/main>"> >>> <Files "wsgi.py"> >>> Require all granted >>> </Files> >>> </Directory> >>> >>> Alias "/assets/" >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/someexample.com/@assets/ >>> <http://someexample.com/@assets/>" >>> >>> <Directory >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/someexample.com/@assets/ >>> <http://someexample.com/@assets/>"> >>> Require all granted >>> </Directory> >>> >>> </VirtualHost> >>> >>> >>> # VIRTUAL HOST: "anotherexample.com <http://anotherexample.com/>" >>> >>> <VirtualHost *:80> >>> ServerName anotherexample.com <http://anotherexample.com/> >>> ServerAlias www.anotherexample.com <http://www.anotherexample.com/> >>> Redirect permanent "/" "https://anotherexample.com/" >>> </VirtualHost> >>> >>> <VirtualHost *:443> >>> ServerName anotherexample.com <http://anotherexample.com/> >>> ServerAlias www.anotherexample.com <http://www.anotherexample.com/> >>> <If "%{HTTP_HOST} == 'www.anotherexample.com >>> <http://www.anotherexample.com/>'"> >>> Redirect "/" "https://anotherexample.com/" >>> </If> >>> >>> SSLEngine On >>> SSLCertificateFile "..." >>> SSLCertificateKeyFile "..." >>> >>> WSGIScriptAlias / >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/anotherexample.com/main/wsgi.py >>> <http://anotherexample.com/main/wsgi.py>" >>> WSGIPythonPath >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/anotherexample.com >>> <http://anotherexample.com/>" >>> >>> <Directory >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/anotherexample.com/main >>> <http://anotherexample.com/main>"> >>> <Files "wsgi.py"> >>> Require all granted >>> </Files> >>> </Directory> >>> >>> Alias "/assets/" >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/anotherexample.com/@assets/ >>> <http://anotherexample.com/@assets/>" >>> >>> <Directory >>> "C:/Users/Administrator/Desktop/SERVERS/web_server_production/website_projects/anotherexample.com/@assets/ >>> <http://anotherexample.com/@assets/>"> >>> Require all granted >>> </Directory> >>> >>> </VirtualHost> >>> >>> >>> If further information is needed, such as what my file structure for these >>> website (Django) projects look like, or how wsgi.py is configured (I mostly >>> used the default generation given by Django), I can provide those too. >>> >>> Probably worth noting, but when starting a new project with Django, it >>> usually names the "main package" as whatever the project was named (usually >>> the name is just the website's name). Instead, I renamed that package to >>> "main" (and it has the same name across all websites) and updated the >>> appropriate references (e.g. "main.settings" inside of "wsgi.py" instead of >>> "someexamplecom.settings"). This is a convention I would prefer to keep, if >>> possible, though I am willing to revert to Django's default convention if >>> it is truly necessary. >>> >>> >> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "modwsgi" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to [email protected] <>. >>> To view this discussion visit >>> https://groups.google.com/d/msgid/modwsgi/d2b81c58-9d22-4720-a6d3-38eec28ca9a8n%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/modwsgi/d2b81c58-9d22-4720-a6d3-38eec28ca9a8n%40googlegroups.com?utm_medium=email&utm_source=footer>. >> > > > -- > You received this message because you are subscribed to the Google Groups > "modwsgi" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] > <mailto:[email protected]>. > To view this discussion visit > https://groups.google.com/d/msgid/modwsgi/39ecdbd5-5e04-4269-96df-86a998936e11n%40googlegroups.com > > <https://groups.google.com/d/msgid/modwsgi/39ecdbd5-5e04-4269-96df-86a998936e11n%40googlegroups.com?utm_medium=email&utm_source=footer>. -- You received this message because you are subscribed to the Google Groups "modwsgi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/modwsgi/A5319EDD-785D-4AEA-95A1-BD82A28C80DC%40gmail.com.
