Importing numpy remotely using importlib

44 Views Asked by At

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?

0

There are 0 best solutions below