[Debichem-devel] Bug#980703: qcelemental: FTBFS: dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.9 returned exit code 13
Lucas Nussbaum
lucas at debian.org
Wed Jan 20 20:47:22 GMT 2021
Source: qcelemental
Version: 0.17.0+dfsg-2
Severity: serious
Justification: FTBFS on amd64
Tags: bullseye sid ftbfs
Usertags: ftbfs-20210120 ftbfs-bullseye
Hi,
During a rebuild of all packages in sid, your package failed to build
on amd64.
Relevant part (hopefully):
> make[1]: Entering directory '/<<PKGBUILDDIR>>'
> dh_auto_test
> I: pybuild base:232: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9/build; python3.9 -m pytest
> ============================= test session starts ==============================
> platform linux -- Python 3.9.1+, pytest-6.0.2, py-1.10.0, pluggy-0.13.0
> rootdir: /<<PKGBUILDDIR>>
> plugins: cov-2.10.1
> collected 998 items
>
> qcelemental/molutil/test_molutil.py s..sss..sss.ss...s.................. [ 3%]
> . [ 3%]
> qcelemental/tests/test_constants.py .................................... [ 7%]
> ....x.... [ 8%]
> qcelemental/tests/test_covalentradii.py ......................... [ 10%]
> qcelemental/tests/test_datum.py ............. [ 12%]
> qcelemental/tests/test_importing.py .......................... [ 14%]
> qcelemental/tests/test_info.py ........................................ [ 18%]
> qcelemental/tests/test_model_general.py ........ [ 19%]
> qcelemental/tests/test_model_results.py ................................ [ 22%]
> ..... [ 23%]
> qcelemental/tests/test_molecule.py .............s....s........s......... [ 26%]
> .......s........... [ 28%]
> qcelemental/tests/test_molparse_align_chiral.py ssssssssss [ 29%]
> qcelemental/tests/test_molparse_from_schema.py ............ [ 30%]
> qcelemental/tests/test_molparse_from_string.py ......................... [ 33%]
> ........................................................................ [ 40%]
> .... [ 41%]
> qcelemental/tests/test_molparse_parse_nucleus_label.py ............. [ 42%]
> qcelemental/tests/test_molparse_pubchem.py FFF...FFF [ 43%]
> qcelemental/tests/test_molparse_reconcile_nucleus.py ................... [ 45%]
> ................................ [ 48%]
> qcelemental/tests/test_molparse_to_schema.py .............. [ 49%]
> qcelemental/tests/test_molparse_to_string.py ........................... [ 52%]
> .... [ 52%]
> qcelemental/tests/test_molparse_validate_and_fill_chgmult.py ........... [ 54%]
> ........................................................ [ 59%]
> qcelemental/tests/test_periodictable.py ................................ [ 62%]
> ........................................................................ [ 70%]
> ............x [ 71%]
> qcelemental/tests/test_testing.py ...................................... [ 75%]
> ...................... [ 77%]
> qcelemental/tests/test_units.py ........................................ [ 81%]
> ........................................................................ [ 88%]
> ........... [ 89%]
> qcelemental/tests/test_utils.py ........................................ [ 93%]
> ..................sssssssssssssss [ 96%]
> qcelemental/tests/test_vanderwaalsradii.py ........................ [ 99%]
> qcelemental/util/test_gph_uno_bipartite.py ssss [ 99%]
> qcelemental/util/test_scipy_hungarian.py .. [100%]
>
> =================================== FAILURES ===================================
> _______________________________ test_pubchem_4a ________________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c561520>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89cdd2430>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>, method = 'GET'
> url = '/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>, method = 'GET'
> url = '/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>
> data = b'GET /rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cdd2430>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = 'benzene'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89c561520>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89c561520>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89c561520>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c561520>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89cdd2430>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 15), match='pubchem:benzene'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = 'benzene'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_4a():
> subject = subject4
> fullans = copy.deepcopy(fullans4)
> fullans["provenance"] = _string_prov_stamp
>
> with xfail_on_pubchem_busy():
> > final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
>
> qcelemental/tests/test_molparse_pubchem.py:76:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 15), match='pubchem:benzene'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> Searching PubChem database for benzene (single best match returned)
> _______________________________ test_pubchem_4b ________________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89f57a2e0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>, method = 'GET'
> url = '/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>, method = 'GET'
> url = '/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>
> data = b'GET /rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = 'benzene'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89f57a2e0>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89f57a2e0>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89f57a2e0>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89f57a2e0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89cd8bf10>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 15), match='pubchem:benzene'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = 'benzene'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_4b():
> """user units potentially contradicting pubchem units"""
> subject = subject4 + "\nunits au"
>
> with pytest.raises(qcelemental.MoleculeFormatError):
> with xfail_on_pubchem_busy():
> > qcelemental.molparse.from_string(subject, return_processed=True)
>
> qcelemental/tests/test_molparse_pubchem.py:88:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 15), match='pubchem:benzene'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/benzene/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> Searching PubChem database for benzene (single best match returned)
> _______________________________ test_pubchem_4c ________________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c184be0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c184ac0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>, method = 'GET'
> url = '/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>, method = 'GET'
> url = '/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>
> data = b'GET /rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c184ac0>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = '241'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89c184be0>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89c184be0>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89c184be0>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c184be0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c184ac0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 14), match='pubchem : 241'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = '241'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_4c():
> subject = """
> pubchem : 241
> """
> ans = copy.deepcopy(ans4)
> ans["name"] = "benzene"
> fullans = copy.deepcopy(fullans4)
> fullans["name"] = "benzene"
> fullans["provenance"] = _string_prov_stamp
>
> with xfail_on_pubchem_busy():
> > final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, name="benzene", verbose=2)
>
> qcelemental/tests/test_molparse_pubchem.py:103:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 14), match='pubchem : 241'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/241/property/IUPACName,MolecularFormula,Charge/JSON
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> <<< FROM_STRING
>
> pubchem : 241
>
> >>>
> Searching PubChem database for CID 241
> ___________________________ test_pubchem_multiout_g ____________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1144f0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1148e0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>, method = 'GET'
> url = '/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>, method = 'GET'
> url = '/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>
> data = b'GET /rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1148e0>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = 'tropolone'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89c1144f0>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89c1144f0>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89c1144f0>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1144f0>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1148e0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 19), match='pubchem: tropolone*'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = 'tropolone'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_multiout_g():
> subject = """
> #pubchem: gobbledegook
> #pubchem: c6h12o
> #pubchem: formaldehyde*
> pubchem: tropolone*
> """
>
> with pytest.raises(qcelemental.ChoicesError) as e:
> with xfail_on_pubchem_busy():
> > qcelemental.molparse.from_string(subject, return_processed=True)
>
> qcelemental/tests/test_molparse_pubchem.py:151:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 19), match='pubchem: tropolone*'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/tropolone/property/IUPACName,MolecularFormula,Charge/JSON?name_type=word
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> Searching PubChem database for tropolone (all matches returned)
> _______________________________ test_pubchem_13h _______________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1f6640>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>, method = 'GET'
> url = '/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>, method = 'GET'
> url = '/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>
> data = b'GET /rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = 'ammonium'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89c1f6640>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89c1f6640>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89c1f6640>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1f6640>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1f66a0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 17), match='pubchem :ammonium'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = 'ammonium'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_13h():
> subject = subject13
> fullans = copy.deepcopy(fullans13)
> fullans["provenance"] = _string_prov_stamp
>
> with xfail_on_pubchem_busy():
> > final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
>
> qcelemental/tests/test_molparse_pubchem.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 17), match='pubchem :ammonium'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/ammonium/property/IUPACName,MolecularFormula,Charge/JSON?name_type=complete
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> Searching PubChem database for ammonium (single best match returned)
> _______________________________ test_pubchem_13i _______________________________
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1b4520>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> > h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
>
> /usr/lib/python3.9/urllib/request.py:1346:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>, method = 'GET'
> url = '/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
>
> def request(self, method, url, body=None, headers={}, *,
> encode_chunked=False):
> """Send a complete request to the server."""
> > self._send_request(method, url, body, headers, encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1255:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>, method = 'GET'
> url = '/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON'
> body = None
> headers = {'Connection': 'close', 'Host': 'pubchem.ncbi.nlm.nih.gov', 'User-Agent': 'Python-urllib/3.9'}
> encode_chunked = False
>
> def _send_request(self, method, url, body, headers, encode_chunked):
> # Honor explicitly requested Host: and Accept-Encoding: headers.
> header_names = frozenset(k.lower() for k in headers)
> skips = {}
> if 'host' in header_names:
> skips['skip_host'] = 1
> if 'accept-encoding' in header_names:
> skips['skip_accept_encoding'] = 1
>
> self.putrequest(method, url, **skips)
>
> # chunked encoding will happen if HTTP/1.1 is used and either
> # the caller passes encode_chunked=True or the following
> # conditions hold:
> # 1. content-length has not been explicitly set
> # 2. the body is a file or iterable, but not a str or bytes-like
> # 3. Transfer-Encoding has NOT been explicitly set by the caller
>
> if 'content-length' not in header_names:
> # only chunk body if not explicitly set for backwards
> # compatibility, assuming the client code is already handling the
> # chunking
> if 'transfer-encoding' not in header_names:
> # if content-length cannot be automatically determined, fall
> # back to chunked encoding
> encode_chunked = False
> content_length = self._get_content_length(body, method)
> if content_length is None:
> if body is not None:
> if self.debuglevel > 0:
> print('Unable to determine size of %r' % body)
> encode_chunked = True
> self.putheader('Transfer-Encoding', 'chunked')
> else:
> self.putheader('Content-Length', str(content_length))
> else:
> encode_chunked = False
>
> for hdr, value in headers.items():
> self.putheader(hdr, value)
> if isinstance(body, str):
> # RFC 2616 Section 3.7.1 says that text default has a
> # default charset of iso-8859-1.
> body = _encode(body, 'body')
> > self.endheaders(body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1301:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>
> message_body = None
>
> def endheaders(self, message_body=None, *, encode_chunked=False):
> """Indicate that the last header line has been sent to the server.
>
> This method sends the request to the server. The optional message_body
> argument can be used to pass a message body associated with the
> request.
> """
> if self.__state == _CS_REQ_STARTED:
> self.__state = _CS_REQ_SENT
> else:
> raise CannotSendHeader()
> > self._send_output(message_body, encode_chunked=encode_chunked)
>
> /usr/lib/python3.9/http/client.py:1250:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>
> message_body = None, encode_chunked = False
>
> def _send_output(self, message_body=None, encode_chunked=False):
> """Send the currently buffered request and clear the buffer.
>
> Appends an extra \\r\\n to the buffer.
> A message_body may be specified, to be appended to the request.
> """
> self._buffer.extend((b"", b""))
> msg = b"\r\n".join(self._buffer)
> del self._buffer[:]
> > self.send(msg)
>
> /usr/lib/python3.9/http/client.py:1010:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>
> data = b'GET /rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: pubchem.ncbi.nlm.nih.gov\r\nUser-Agent: Python-urllib/3.9\r\nConnection: close\r\n\r\n'
>
> def send(self, data):
> """Send `data' to the server.
> ``data`` can be a string object, a bytes object, an array object, a
> file-like object that supports a .read() method, or an iterable object.
> """
>
> if self.sock is None:
> if self.auto_open:
> > self.connect()
>
> /usr/lib/python3.9/http/client.py:950:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>
>
> def connect(self):
> "Connect to a host on a given (SSL) port."
>
> > super().connect()
>
> /usr/lib/python3.9/http/client.py:1417:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>
>
> def connect(self):
> """Connect to the host and port specified in __init__."""
> > self.sock = self._create_connection(
> (self.host,self.port), self.timeout, self.source_address)
>
> /usr/lib/python3.9/http/client.py:921:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> sock.connect(sa)
> # Break explicitly a reference cycle
> err = None
> return sock
>
> except error as _:
> err = _
> if sock is not None:
> sock.close()
>
> if err is not None:
> try:
> > raise err
>
> /usr/lib/python3.9/socket.py:843:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> address = ('127.0.0.1', 9), timeout = <object object at 0x7fc89f7644c0>
> source_address = None
>
> def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
> source_address=None):
> """Connect to *address* and return the socket object.
>
> Convenience function. Connect to *address* (a 2-tuple ``(host,
> port)``) and return the socket object. Passing the optional
> *timeout* parameter will set the timeout on the socket instance
> before attempting to connect. If no *timeout* is supplied, the
> global default timeout setting returned by :func:`getdefaulttimeout`
> is used. If *source_address* is set it must be a tuple of (host, port)
> for the socket to bind as a source address before making the connection.
> A host of '' or port 0 tells the OS to use the default.
> """
>
> host, port = address
> err = None
> for res in getaddrinfo(host, port, 0, SOCK_STREAM):
> af, socktype, proto, canonname, sa = res
> sock = None
> try:
> sock = socket(af, socktype, proto)
> if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
> sock.settimeout(timeout)
> if source_address:
> sock.bind(source_address)
> > sock.connect(sa)
> E ConnectionRefusedError: [Errno 111] Connection refused
>
> /usr/lib/python3.9/socket.py:831: ConnectionRefusedError
>
> During handling of the above exception, another exception occurred:
>
> name = '223'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> > response = urlopen(url)
>
> qcelemental/molparse/pubchem.py:154:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
> *, cafile=None, capath=None, cadefault=False, context=None):
> '''Open the URL url, which can be either a string or a Request object.
>
> *data* must be an object specifying additional data to be sent to
> the server, or None if no such data is needed. See Request for
> details.
>
> urllib.request module uses HTTP/1.1 and includes a "Connection:close"
> header in its HTTP requests.
>
> The optional *timeout* parameter specifies a timeout in seconds for
> blocking operations like the connection attempt (if not specified, the
> global default timeout setting will be used). This only works for HTTP,
> HTTPS and FTP connections.
>
> If *context* is specified, it must be a ssl.SSLContext instance describing
> the various SSL options. See HTTPSConnection for more details.
>
> The optional *cafile* and *capath* parameters specify a set of trusted CA
> certificates for HTTPS requests. cafile should point to a single file
> containing a bundle of CA certificates, whereas capath should point to a
> directory of hashed certificate files. More information can be found in
> ssl.SSLContext.load_verify_locations().
>
> The *cadefault* parameter is ignored.
>
>
> This function always returns an object which can work as a
> context manager and has the properties url, headers, and status.
> See urllib.response.addinfourl for more detail on these properties.
>
> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
> object slightly modified. In addition to the three new methods above, the
> msg attribute contains the same information as the reason attribute ---
> the reason phrase returned by the server --- instead of the response
> headers as it is specified in the documentation for HTTPResponse.
>
> For FTP, file, and data URLs and requests explicitly handled by legacy
> URLopener and FancyURLopener classes, this function returns a
> urllib.response.addinfourl object.
>
> Note that None may be returned if no handler handles the request (though
> the default installed global OpenerDirector uses UnknownHandler to ensure
> this never happens).
>
> In addition, if proxy settings are detected (for example, when a *_proxy
> environment variable like http_proxy is set), ProxyHandler is default
> installed and makes sure the requests are handled through the proxy.
>
> '''
> global _opener
> if cafile or capath or cadefault:
> import warnings
> warnings.warn("cafile, capath and cadefault are deprecated, use a "
> "custom context instead.", DeprecationWarning, 2)
> if context is not None:
> raise ValueError(
> "You can't pass both context and any of cafile, capath, and "
> "cadefault"
> )
> if not _have_ssl:
> raise ValueError('SSL support not available')
> context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
> cafile=cafile,
> capath=capath)
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif context:
> https_handler = HTTPSHandler(context=context)
> opener = build_opener(https_handler)
> elif _opener is None:
> _opener = opener = build_opener()
> else:
> opener = _opener
> > return opener.open(url, data, timeout)
>
> /usr/lib/python3.9/urllib/request.py:214:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> fullurl = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON'
> data = None, timeout = <object object at 0x7fc89f7644c0>
>
> def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
> # accept a URL or a Request object
> if isinstance(fullurl, str):
> req = Request(fullurl, data)
> else:
> req = fullurl
> if data is not None:
> req.data = data
>
> req.timeout = timeout
> protocol = req.type
>
> # pre-process request
> meth_name = protocol+"_request"
> for processor in self.process_request.get(protocol, []):
> meth = getattr(processor, meth_name)
> req = meth(req)
>
> sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
> > response = self._open(req, data)
>
> /usr/lib/python3.9/urllib/request.py:517:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> req = <urllib.request.Request object at 0x7fc89c1b4520>, data = None
>
> def _open(self, req, data=None):
> result = self._call_chain(self.handle_open, 'default',
> 'default_open', req)
> if result:
> return result
>
> protocol = req.type
> > result = self._call_chain(self.handle_open, protocol, protocol +
> '_open', req)
>
> /usr/lib/python3.9/urllib/request.py:534:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.OpenerDirector object at 0x7fc89c561400>
> chain = {'data': [<urllib.request.DataHandler object at 0x7fc89c5bcd30>], 'file': [<urllib.request.FileHandler object at 0x7fc...: [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPHandler object at 0x7fc89c561790>], ...}
> kind = 'https', meth_name = 'https_open'
> args = (<urllib.request.Request object at 0x7fc89c1b4520>,)
> handlers = [<urllib.request.ProxyHandler object at 0x7fc89c561580>, <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>]
> handler = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> func = <bound method HTTPSHandler.https_open of <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>>
>
> def _call_chain(self, chain, kind, meth_name, *args):
> # Handlers raise an exception if no one else should try to handle
> # the request, or return None if they can't but another handler
> # could. Otherwise, they return the response.
> handlers = chain.get(kind, ())
> for handler in handlers:
> func = getattr(handler, meth_name)
> > result = func(*args)
>
> /usr/lib/python3.9/urllib/request.py:494:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> req = <urllib.request.Request object at 0x7fc89c1b4520>
>
> def https_open(self, req):
> > return self.do_open(http.client.HTTPSConnection, req,
> context=self._context, check_hostname=self._check_hostname)
>
> /usr/lib/python3.9/urllib/request.py:1389:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> self = <urllib.request.HTTPSHandler object at 0x7fc89c5bc850>
> http_class = <class 'http.client.HTTPSConnection'>
> req = <urllib.request.Request object at 0x7fc89c1b4520>
> http_conn_args = {'check_hostname': None, 'context': None}, host = '127.0.0.1:9'
> h = <http.client.HTTPSConnection object at 0x7fc89c1b48e0>, tunnel_headers = {}
> proxy_auth_hdr = 'Proxy-Authorization'
>
> def do_open(self, http_class, req, **http_conn_args):
> """Return an HTTPResponse object for the request, using http_class.
>
> http_class must implement the HTTPConnection API from http.client.
> """
> host = req.host
> if not host:
> raise URLError('no host given')
>
> # will parse host:port
> h = http_class(host, timeout=req.timeout, **http_conn_args)
> h.set_debuglevel(self._debuglevel)
>
> headers = dict(req.unredirected_hdrs)
> headers.update({k: v for k, v in req.headers.items()
> if k not in headers})
>
> # TODO(jhylton): Should this be redesigned to handle
> # persistent connections?
>
> # We want to make an HTTP/1.1 request, but the addinfourl
> # class isn't prepared to deal with a persistent connection.
> # It will try to read all remaining data from the socket,
> # which will block while the server waits for the next request.
> # So make sure the connection gets closed after the (only)
> # request.
> headers["Connection"] = "close"
> headers = {name.title(): val for name, val in headers.items()}
>
> if req._tunnel_host:
> tunnel_headers = {}
> proxy_auth_hdr = "Proxy-Authorization"
> if proxy_auth_hdr in headers:
> tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
> # Proxy-Authorization should not be sent to origin
> # server.
> del headers[proxy_auth_hdr]
> h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
>
> try:
> try:
> h.request(req.get_method(), req.selector, req.data, headers,
> encode_chunked=req.has_header('Transfer-encoding'))
> except OSError as err: # timeout error
> > raise URLError(err)
> E urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
>
> /usr/lib/python3.9/urllib/request.py:1349: URLError
>
> The above exception was the direct cause of the following exception:
>
> matchobj = <re.Match object; span=(0, 11), match='PubChem:223'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> > results = pubchem.get_pubchem_results(pubsearch)
>
> qcelemental/molparse/from_string.py:307:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> name = '223'
>
> def get_pubchem_results(name):
> """Function to query the PubChem database for molecules matching the
> input string. Builds a PubChemObj object if found.
>
> """
> from urllib.request import urlopen
> from urllib.parse import quote
> from urllib.error import URLError
>
> if name.isdigit():
> print("\tSearching PubChem database for CID {}".format(name))
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON".format(
> quote(name)
> )
>
> else:
> if name.endswith("*"):
> name = name[:-1]
> loose = True
> else:
> loose = False
> print(
> "\tSearching PubChem database for {} ({} returned)".format(
> name, "all matches" if loose else "single best match"
> )
> )
> url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}".format(
> quote(name), "word" if loose else "complete"
> )
>
> try:
> response = urlopen(url)
> except URLError as e:
> # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable
> > raise ValidationError(
> """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n"""
> % (str(e), url)
> ) from e
> E qcelemental.exceptions.ValidationError: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/pubchem.py:157: ValidationError
>
> During handling of the above exception, another exception occurred:
>
> @using_web
> def test_pubchem_13i():
> subject = "PubChem:223"
> fullans = copy.deepcopy(fullans13)
> fullans["provenance"] = _string_prov_stamp
>
> with xfail_on_pubchem_busy():
> > final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
>
> qcelemental/tests/test_molparse_pubchem.py:226:
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> qcelemental/molparse/from_string.py:230: in from_string
> molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False)
> qcelemental/molparse/from_string.py:196: in parse_as_psi4_ish
> molstr, processed = _filter_pubchem(molstr)
> qcelemental/molparse/from_string.py:342: in _filter_pubchem
> line = re.sub(pubchemre, process_pubchem, line.strip())
> /usr/lib/python3.9/re.py:210: in sub
> return _compile(pattern, flags).sub(repl, string, count)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> matchobj = <re.Match object; span=(0, 11), match='PubChem:223'>
>
> def process_pubchem(matchobj):
> pubsearch = matchobj.group("pubsearch")
>
> # search pubchem for the provided string
> try:
> results = pubchem.get_pubchem_results(pubsearch)
> except Exception as e:
> > raise ValidationError(e.message)
> E qcelemental.exceptions.ValidationError: Input Error: PubchemError
> E <urlopen error [Errno 111] Connection refused>
> E received when trying to open
> E https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/223/property/IUPACName,MolecularFormula,Charge/JSON
> E Check your internet connection, and the above URL, and try again.
>
> qcelemental/molparse/from_string.py:309: ValidationError
> ----------------------------- Captured stdout call -----------------------------
> Searching PubChem database for CID 223
> =============================== warnings summary ===============================
> .pybuild/cpython3_3.9/build/qcelemental/tests/test_molparse_from_string.py: 10 warnings
> /usr/lib/python3/dist-packages/numpy/core/_asarray.py:83: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
> return array(a, dtype, copy=False, order=order)
>
> -- Docs: https://docs.pytest.org/en/stable/warnings.html
> =========================== short test summary info ============================
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_4a - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_4b - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_4c - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_multiout_g - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_13h - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> FAILED qcelemental/tests/test_molparse_pubchem.py::test_pubchem_13i - qcelemental.exceptions.ValidationError: Input Error: PubchemError
> ====== 6 failed, 947 passed, 43 skipped, 2 xfailed, 10 warnings in 4.88s =======
> E: pybuild pybuild:353: test: plugin distutils failed with: exit code=1: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9/build; python3.9 -m pytest
> dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.9 returned exit code 13
The full build log is available from:
http://qa-logs.debian.net/2021/01/20/qcelemental_0.17.0+dfsg-2_unstable.log
A list of current common problems and possible solutions is available at
http://wiki.debian.org/qa.debian.org/FTBFS . You're welcome to contribute!
If you reassign this bug to another package, please marking it as 'affects'-ing
this package. See https://www.debian.org/Bugs/server-control#affects
If you fail to reproduce this, please provide a build log and diff it with me
so that we can identify if something relevant changed in the meantime.
About the archive rebuild: The rebuild was done on EC2 VM instances from
Amazon Web Services, using a clean, minimal and up-to-date chroot. Every
failed build was retried once to eliminate random failures.
More information about the Debichem-devel
mailing list