Nice but I wouldn't install the whole of pyobjc - maybe change the import of the non standard python packages to - you would need to import subprocess:
import subprocess
try:
from CoreWLAN import CWWiFiClient
from CoreLocation import CLLocationManager
except ImportError:
frmwk = [
"pyobjc-framework-CoreLocation",
"pyobjc-framework-CoreWLAN"
]
subprocess.check_call([sys.executable, "-m", "pip", "install", frmwk, "-q"])
from CoreWLAN import CWWiFiClient
from CoreLocation import CLLocationManager
I'm also considering whether to use
location_manager.requestAlwaysAuthorization()
instead but to test it I have to create a new user each time, as once you give authorisation there appears to no way to delete it from the Location Services list - only disable it
or if you are brave, convert a system plist to xml - edit it - then convert it back to binary along with killing some processes and I am not wanting to muck around with system wide files like that on my main machine
I don't see how using homebrew installed python versus installing it from python.org can make any difference - but I would definitely ensure this was done in a venv so you don't muck around with the system wide version of python - 3.9 IIRC
I'm going to experiment with not even requiring CoreWLAN to give python Location Services authorisation as that is all I need for some scripts - but incorporate the full thing so I'm not using a subprocess.run() in the script I need it for
I still can't see this helping terminal having access though
as an aside I took the WiFi redactor Swift code and parsed it through the gemini CLI to turn it into python - which I've already got trained to check if non standard packages are installed so it added that and got
#!/usr/bin/env python3
import sys
import subprocess
import json
try:
import objc
from CoreLocation import CLLocationManager, kCLAuthorizationStatusAuthorizedAlways, kCLAuthorizationStatusAuthorized
from CoreWLAN import CWWiFiClient
from Foundation import NSObject, NSBundle
from AppKit import NSApplication
except ImportError:
print("Required pyobjc frameworks not found. Attempting to install...")
try:
required_frameworks = [
"pyobjc-core",
"pyobjc-framework-CoreLocation",
"pyobjc-framework-CoreWLAN",
"pyobjc-framework-Foundation",
"pyobjc-framework-AppKit"
]
for framework in required_frameworks:
subprocess.check_call([sys.executable, "-m", "pip", "install", framework, "-q"])
print("Required frameworks installed successfully.")
import objc
from CoreLocation import CLLocationManager, kCLAuthorizationStatusAuthorizedAlways, kCLAuthorizationStatusAuthorized
from CoreWLAN import CWWiFiClient
from Foundation import NSObject, NSBundle
from AppKit import NSApplication
except Exception as e:
print(f"Failed to install required frameworks: {e}")
sys.exit(1)
class LocationDelegate(NSObject):
def locationManager_didChangeAuthorizationStatus_(self, manager, status):
if status == kCLAuthorizationStatusAuthorizedAlways or status == kCLAuthorizationStatusAuthorized:
try:
interface = CWWiFiClient.sharedWiFiClient().interface()
json_output = {
"interface": interface.interfaceName(),
"ssid": interface.ssid() or "failed to retrieve SSID",
"bssid": interface.bssid() or "failed to retrieve BSSID",
}
except Exception as e:
json_output = {"error": str(e)}
else:
json_output = {"error": "location services denied"}
print(json.dumps(json_output, indent=4))
NSApplication.sharedApplication().terminate_(self)
def applicationDidFinishLaunching_(self, notification):
self.locationManager = CLLocationManager.alloc().init()
self.locationManager.setDelegate_(self)
self.locationManager.requestAlwaysAuthorization()
def main():
# Ensure the application bundle is recognized for command-line tools
bundle = NSBundle.mainBundle()
if not bundle:
info = {
'CFBundleIdentifier': 'com.renchu.ssidscript',
}
objc.lookUpClass('NSBundle')._setMainBundle_(objc.lookUpClass('NSBundle').bundleWithInfoDictionary_(info))
app = NSApplication.sharedApplication()
delegate = LocationDelegate.alloc().init()
app.setDelegate_(delegate)
app.run()
if __name__ == "__main__":
main()