We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Importing gloo should not automatically load the OpenGL library
I'm trying to run vispy on a headless server with docker, to use the ipynb webgl backend exclusively. I cannot `import vispy.gloo`:

```
  File "/opt/conda/lib/python3.4/site-packages/vispy/gloo/__init__.py", line 47, in <module>
    from . import gl  # noqa
  File "/opt/conda/lib/python3.4/site-packages/vispy/gloo/gl/__init__.py", line 213, in <module>
    from . import gl2 as default_backend  # noqa
  File "/opt/conda/lib/python3.4/site-packages/vispy/gloo/gl/gl2.py", line 46, in <module>
    raise RuntimeError('Could not load OpenGL library.')
RuntimeError: Could not load OpenGL library.
```

I should not need to have the OpenGL library on a headless server when using a remote backend.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `vispy/gloo/gl/gl2.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # Copyright (c) 2015, Vispy Development Team.
3 # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4 
5 """ GL ES 2.0 API implemented via desktop GL (i.e subset of normal OpenGL).
6 """
7 
8 import os
9 import sys
10 import ctypes.util
11 
12 from . import _copy_gl_functions
13 from ._constants import *  # noqa
14 
15 # Ctypes stuff
16 
17 
18 # Load the OpenGL library. We more or less follow the same approach
19 # as PyOpenGL does internally
20 
21 _have_get_proc_address = False
22 _lib = os.getenv('VISPY_GL_LIB', '')
23 if _lib != '':
24     if sys.platform.startswith('win'):
25         _lib = ctypes.windll.LoadLibrary(_lib)
26     else:
27         _lib = ctypes.cdll.LoadLibrary(_lib)
28 elif sys.platform.startswith('win'):
29     # Windows
30     _lib = ctypes.windll.opengl32
31     try:
32         wglGetProcAddress = _lib.wglGetProcAddress
33         wglGetProcAddress.restype = ctypes.CFUNCTYPE(
34             ctypes.POINTER(ctypes.c_int))
35         wglGetProcAddress.argtypes = [ctypes.c_char_p]
36         _have_get_proc_address = True
37     except AttributeError:
38         pass
39 else:
40     # Unix-ish
41     if sys.platform.startswith('darwin'):
42         _fname = ctypes.util.find_library('OpenGL')
43     else:
44         _fname = ctypes.util.find_library('GL')
45     if not _fname:
46         raise RuntimeError('Could not load OpenGL library.')
47     # Load lib
48     _lib = ctypes.cdll.LoadLibrary(_fname)
49 
50 
51 def _have_context():
52     return _lib.glGetError() != 1282  # GL_INVALID_OPERATION
53 
54 
55 def _get_gl_version(_lib):
56     """Helper to get the GL version string"""
57     try:
58         return _lib.glGetString(7938).decode('utf-8')
59     except Exception:
60         return 'unknown'
61 
62 
63 def _get_gl_func(name, restype, argtypes):
64     # Based on a function in Pyglet
65     try:
66         # Try using normal ctypes stuff
67         func = getattr(_lib, name)
68         func.restype = restype
69         func.argtypes = argtypes
70         return func
71     except AttributeError:
72         if sys.platform.startswith('win'):
73             # Ask for a pointer to the function, this is the approach
74             # for OpenGL extensions on Windows
75             fargs = (restype,) + argtypes
76             ftype = ctypes.WINFUNCTYPE(*fargs)
77             if not _have_get_proc_address:
78                 raise RuntimeError('Function %s not available '
79                                    '(OpenGL version is %s).'
80                                    % (name, _get_gl_version(_lib)))
81             if not _have_context():
82                 raise RuntimeError('Using %s with no OpenGL context.' % name)
83             address = wglGetProcAddress(name.encode('utf-8'))
84             if address:
85                 return ctypes.cast(address, ftype)
86         # If not Windows or if we did not return function object on Windows:
87         raise RuntimeError('Function %s not present in context '
88                            '(OpenGL version is %s).'
89                            % (name, _get_gl_version(_lib)))
90 
91 
92 # Inject
93 
94 from . import _gl2  # noqa
95 _copy_gl_functions(_gl2, globals())
96
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/vispy/gloo/gl/gl2.py b/vispy/gloo/gl/gl2.py
--- a/vispy/gloo/gl/gl2.py
+++ b/vispy/gloo/gl/gl2.py
@@ -11,6 +11,7 @@
 
 from . import _copy_gl_functions
 from ._constants import *  # noqa
+from ...util import logger
 
 # Ctypes stuff
 
@@ -43,9 +44,11 @@
     else:
         _fname = ctypes.util.find_library('GL')
     if not _fname:
-        raise RuntimeError('Could not load OpenGL library.')
-    # Load lib
-    _lib = ctypes.cdll.LoadLibrary(_fname)
+        logger.warning('Could not load OpenGL library.')
+        _lib = None
+    else:
+        # Load lib
+        _lib = ctypes.cdll.LoadLibrary(_fname)
 
 
 def _have_context():
@@ -62,6 +65,8 @@
 
 def _get_gl_func(name, restype, argtypes):
     # Based on a function in Pyglet
+    if _lib is None:
+        raise RuntimeError('Could not load OpenGL library, gl cannot be used')
     try:
         # Try using normal ctypes stuff
         func = getattr(_lib, name)

{"golden_diff": "diff --git a/vispy/gloo/gl/gl2.py b/vispy/gloo/gl/gl2.py\n--- a/vispy/gloo/gl/gl2.py\n+++ b/vispy/gloo/gl/gl2.py\n@@ -11,6 +11,7 @@\n \n from . import _copy_gl_functions\n from ._constants import *  # noqa\n+from ...util import logger\n \n # Ctypes stuff\n \n@@ -43,9 +44,11 @@\n     else:\n         _fname = ctypes.util.find_library('GL')\n     if not _fname:\n-        raise RuntimeError('Could not load OpenGL library.')\n-    # Load lib\n-    _lib = ctypes.cdll.LoadLibrary(_fname)\n+        logger.warning('Could not load OpenGL library.')\n+        _lib = None\n+    else:\n+        # Load lib\n+        _lib = ctypes.cdll.LoadLibrary(_fname)\n \n \n def _have_context():\n@@ -62,6 +65,8 @@\n \n def _get_gl_func(name, restype, argtypes):\n     # Based on a function in Pyglet\n+    if _lib is None:\n+        raise RuntimeError('Could not load OpenGL library, gl cannot be used')\n     try:\n         # Try using normal ctypes stuff\n         func = getattr(_lib, name)\n", "issue": "Importing gloo should not automatically load the OpenGL library\nI'm trying to run vispy on a headless server with docker, to use the ipynb webgl backend exclusively. I cannot `import vispy.gloo`:\n\n```\n  File \"/opt/conda/lib/python3.4/site-packages/vispy/gloo/__init__.py\", line 47, in <module>\n    from . import gl  # noqa\n  File \"/opt/conda/lib/python3.4/site-packages/vispy/gloo/gl/__init__.py\", line 213, in <module>\n    from . import gl2 as default_backend  # noqa\n  File \"/opt/conda/lib/python3.4/site-packages/vispy/gloo/gl/gl2.py\", line 46, in <module>\n    raise RuntimeError('Could not load OpenGL library.')\nRuntimeError: Could not load OpenGL library.\n```\n\nI should not need to have the OpenGL library on a headless server when using a remote backend.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2015, Vispy Development Team.\n# Distributed under the (new) BSD License. See LICENSE.txt for more info.\n\n\"\"\" GL ES 2.0 API implemented via desktop GL (i.e subset of normal OpenGL).\n\"\"\"\n\nimport os\nimport sys\nimport ctypes.util\n\nfrom . import _copy_gl_functions\nfrom ._constants import *  # noqa\n\n# Ctypes stuff\n\n\n# Load the OpenGL library. We more or less follow the same approach\n# as PyOpenGL does internally\n\n_have_get_proc_address = False\n_lib = os.getenv('VISPY_GL_LIB', '')\nif _lib != '':\n    if sys.platform.startswith('win'):\n        _lib = ctypes.windll.LoadLibrary(_lib)\n    else:\n        _lib = ctypes.cdll.LoadLibrary(_lib)\nelif sys.platform.startswith('win'):\n    # Windows\n    _lib = ctypes.windll.opengl32\n    try:\n        wglGetProcAddress = _lib.wglGetProcAddress\n        wglGetProcAddress.restype = ctypes.CFUNCTYPE(\n            ctypes.POINTER(ctypes.c_int))\n        wglGetProcAddress.argtypes = [ctypes.c_char_p]\n        _have_get_proc_address = True\n    except AttributeError:\n        pass\nelse:\n    # Unix-ish\n    if sys.platform.startswith('darwin'):\n        _fname = ctypes.util.find_library('OpenGL')\n    else:\n        _fname = ctypes.util.find_library('GL')\n    if not _fname:\n        raise RuntimeError('Could not load OpenGL library.')\n    # Load lib\n    _lib = ctypes.cdll.LoadLibrary(_fname)\n\n\ndef _have_context():\n    return _lib.glGetError() != 1282  # GL_INVALID_OPERATION\n\n\ndef _get_gl_version(_lib):\n    \"\"\"Helper to get the GL version string\"\"\"\n    try:\n        return _lib.glGetString(7938).decode('utf-8')\n    except Exception:\n        return 'unknown'\n\n\ndef _get_gl_func(name, restype, argtypes):\n    # Based on a function in Pyglet\n    try:\n        # Try using normal ctypes stuff\n        func = getattr(_lib, name)\n        func.restype = restype\n        func.argtypes = argtypes\n        return func\n    except AttributeError:\n        if sys.platform.startswith('win'):\n            # Ask for a pointer to the function, this is the approach\n            # for OpenGL extensions on Windows\n            fargs = (restype,) + argtypes\n            ftype = ctypes.WINFUNCTYPE(*fargs)\n            if not _have_get_proc_address:\n                raise RuntimeError('Function %s not available '\n                                   '(OpenGL version is %s).'\n                                   % (name, _get_gl_version(_lib)))\n            if not _have_context():\n                raise RuntimeError('Using %s with no OpenGL context.' % name)\n            address = wglGetProcAddress(name.encode('utf-8'))\n            if address:\n                return ctypes.cast(address, ftype)\n        # If not Windows or if we did not return function object on Windows:\n        raise RuntimeError('Function %s not present in context '\n                           '(OpenGL version is %s).'\n                           % (name, _get_gl_version(_lib)))\n\n\n# Inject\n\nfrom . import _gl2  # noqa\n_copy_gl_functions(_gl2, globals())\n", "path": "vispy/gloo/gl/gl2.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2015, Vispy Development Team.\n# Distributed under the (new) BSD License. See LICENSE.txt for more info.\n\n\"\"\" GL ES 2.0 API implemented via desktop GL (i.e subset of normal OpenGL).\n\"\"\"\n\nimport os\nimport sys\nimport ctypes.util\n\nfrom . import _copy_gl_functions\nfrom ._constants import *  # noqa\nfrom ...util import logger\n\n# Ctypes stuff\n\n\n# Load the OpenGL library. We more or less follow the same approach\n# as PyOpenGL does internally\n\n_have_get_proc_address = False\n_lib = os.getenv('VISPY_GL_LIB', '')\nif _lib != '':\n    if sys.platform.startswith('win'):\n        _lib = ctypes.windll.LoadLibrary(_lib)\n    else:\n        _lib = ctypes.cdll.LoadLibrary(_lib)\nelif sys.platform.startswith('win'):\n    # Windows\n    _lib = ctypes.windll.opengl32\n    try:\n        wglGetProcAddress = _lib.wglGetProcAddress\n        wglGetProcAddress.restype = ctypes.CFUNCTYPE(\n            ctypes.POINTER(ctypes.c_int))\n        wglGetProcAddress.argtypes = [ctypes.c_char_p]\n        _have_get_proc_address = True\n    except AttributeError:\n        pass\nelse:\n    # Unix-ish\n    if sys.platform.startswith('darwin'):\n        _fname = ctypes.util.find_library('OpenGL')\n    else:\n        _fname = ctypes.util.find_library('GL')\n    if not _fname:\n        logger.warning('Could not load OpenGL library.')\n        _lib = None\n    else:\n        # Load lib\n        _lib = ctypes.cdll.LoadLibrary(_fname)\n\n\ndef _have_context():\n    return _lib.glGetError() != 1282  # GL_INVALID_OPERATION\n\n\ndef _get_gl_version(_lib):\n    \"\"\"Helper to get the GL version string\"\"\"\n    try:\n        return _lib.glGetString(7938).decode('utf-8')\n    except Exception:\n        return 'unknown'\n\n\ndef _get_gl_func(name, restype, argtypes):\n    # Based on a function in Pyglet\n    if _lib is None:\n        raise RuntimeError('Could not load OpenGL library, gl cannot be used')\n    try:\n        # Try using normal ctypes stuff\n        func = getattr(_lib, name)\n        func.restype = restype\n        func.argtypes = argtypes\n        return func\n    except AttributeError:\n        if sys.platform.startswith('win'):\n            # Ask for a pointer to the function, this is the approach\n            # for OpenGL extensions on Windows\n            fargs = (restype,) + argtypes\n            ftype = ctypes.WINFUNCTYPE(*fargs)\n            if not _have_get_proc_address:\n                raise RuntimeError('Function %s not available '\n                                   '(OpenGL version is %s).'\n                                   % (name, _get_gl_version(_lib)))\n            if not _have_context():\n                raise RuntimeError('Using %s with no OpenGL context.' % name)\n            address = wglGetProcAddress(name.encode('utf-8'))\n            if address:\n                return ctypes.cast(address, ftype)\n        # If not Windows or if we did not return function object on Windows:\n        raise RuntimeError('Function %s not present in context '\n                           '(OpenGL version is %s).'\n                           % (name, _get_gl_version(_lib)))\n\n\n# Inject\n\nfrom . import _gl2  # noqa\n_copy_gl_functions(_gl2, globals())\n", "path": "vispy/gloo/gl/gl2.py"}]}