I am currently working on a remote import system for numpy that uses the numpy folder in my sites-packages location being hosted on a web server. This is my current code:
class Finder(importlib.abc.MetaPathFinder):
def __init__(self, base_url) -> None:
self.base_url = base_url
def find_spec(self, fullname, path, target=None):
spec = self.find_py_file_spec(fullname)
if spec is not None:
return spec
spec = self.find_package_spec_init(fullname)
if spec is not None:
return spec
return None
def find_py_file_spec(self, fullname):
if len(fullname.split(".")) == 1:
url = "{}/{}/{}.py".format(self.base_url,fullname.split(".")[0],fullname.replace(".","/"))
else:
url = "{}/{}.py".format(self.base_url,fullname.replace(".","/"))
print(url)
source = self.get_source_code(url)
if source is None:
print("no thing found")
return None
loader = Loader(fullname,source,url)
return importlib.machinery.ModuleSpec(fullname, loader)
def find_package_spec_init(self,fullname):
url = "{}/{}/__init__.py".format(self.base_url,fullname.replace(".","/"))
source = self.get_source_code(url)
if source is None:
print("no init found")
return None
loader = Loader(fullname,source,url,zip=True)
return importlib.machinery.ModuleSpec(fullname, loader,is_package=True,)
def get_source_code(self, url):
try:
response = requests.get("http://"+url)
response.raise_for_status()
except requests.HTTPError:
return None
print("import failed due to HTTP")
source = response.text
return source
class Loader(importlib.abc.Loader):
def __init__(self, name, source_code, url,zip=False) -> None:
self.name = name
self.source_code = source_code
self.url = url
self.zip = zip
def create_module(self, spec: ModuleSpec) -> ModuleType | None:
module = sys.modules.get(spec.name)
if module is None:
module = ModuleType(spec.name)
sys.modules[spec.name] = module
return module
def exec_module(self, module: ModuleType) -> None:
module.__file__ = self.url
print("url is {}".format(self.url))
exec(self.source_code, module.__dict__)
return module
def get_source(self,name):
return self.source_code
def add_server(ip,port):
sys.meta_path.append(Finder(f"{ip}:{port}"))
add_server("127.0.0.1",5002)
for f in sys.meta_path:
print(f)
import numpy
This code will work for packages that only contain .py files. But numpy contains .pyd and .pyi files. How can I handle those types of files so that I can successfully import numpy remotely?