20 import urllib.request, urllib.error, urllib.parse
23 from ost.io import LoadPDB, LoadMMCIF
27 A remote repository represents a structural database accessible through the
28 internet, e.g. the PDB or SWISS-MODEL template library.
30 :param name: Name of the repository
31 :param url_pattern: URL pattern for repository. Required format is described
33 :param type: Data format to expect at resolved URL must be in
35 :param id_transform: Transformation to apply to ID before resolving URL
36 in :func:`URLForID`. Must be in ('lower', 'upper')
38 :type name: :class:`str`
39 :type url_pattern: :class:`str`
40 :type type: :class:`str`
41 :type id_transform: :class:`str`
43 def __init__(self, name, url_pattern, type, id_transform='upper'):
47 if type
not in (
'cif',
'pdb'):
48 raise ValueError(
'only cif and pdb types are supported')
53 Resolves URL given *url_pattern* and *id_transform* provided at object
55 The *url_pattern* must contain substring '$ID'. Given *id*, the URL to
56 the structure gets constructed by applying *id_transform* and inserting it
57 at the location of '$ID'. e.g. 'https://files.rcsb.org/view/$ID.pdb' given
58 1ake as *id* and 'upper' as *id_transform* resolves to:
59 'https://files.rcsb.org/view/1AKE.pdb'
65 return self.url_pattern.replace(
'$ID', id)
69 Resolves URL with :func:`URLForID`, dumps the content in a temporary file
72 :param id: ID to resolve
73 :type id: :class:`str`
76 tmp_file_suffix =
'.%s' % self.
type
77 if remote_url.endswith(
'.gz'):
78 tmp_file_suffix+=
'.gz'
81 connection = urllib.request.urlopen(remote_url)
82 if hasattr(connection,
'code'):
83 status = connection.code
85 status = connection.getcode()
86 except urllib.error.HTTPError
as e:
89 raise IOError(
'Could not load %s from %s (status code %d, url %s)' \
90 % (id, self.
name, status, remote_url))
91 tmp_file = tempfile.NamedTemporaryFile(suffix=tmp_file_suffix)
92 tmp_file.write(connection.read())
98 Resolves URL with :func:`URLForID` and directly loads/returns the according
99 :class:`ost.mol.EntityHandle`. Loading invokes the
100 :func:`ost.io.LoadPDB`/:func:`ost.io.LoadMMCIF` with default parameterization. If you need
101 custom settings, you might want to consider to call :func:`Get` and do the
104 :param id: ID to resolve
105 :type id: :class:`str`
107 tmp_file = self.
Get(id)
108 if self.
type ==
'pdb':
110 if self.
type ==
'cif':
113 REMOTE_REPOSITORIES = {
114 'pdb' :
RemoteRepository(
'rcsb.org (PDB)',
'https://files.rcsb.org/download/$ID.pdb.gz',
115 type=
'pdb', id_transform=
'upper'),
116 'smtl' :
RemoteRepository(
'SMTL',
'https://swissmodel.expasy.org/templates/$ID.pdb',
117 type=
'pdb', id_transform=
'lower'),
118 'cif' :
RemoteRepository(
'rcsb.org (mmCIF)',
'https://files.rcsb.org/download/$ID.cif.gz',
119 type=
'cif', id_transform=
'lower'),
120 'pdb_redo' :
RemoteRepository(
'pdbredo',
'https://pdb-redo.eu/db/$ID/$ID_besttls.pdb.gz',
121 type=
'pdb', id_transform=
'lower'),
126 Invokes :func:`RemoteRepository.Get` on predefined repositories
127 ('pdb', 'smtl', 'cif', 'pdb_redo')
129 :param from_repo: One of the predefined repositories
130 :type from_repo: :class:`str`
132 remote_repo = REMOTE_REPOSITORIES.get(from_repo,
None)
134 raise ValueError(
'%s is not a valid repository' % from_repo)
135 return remote_repo.Get(id)
139 Invokes :func:`RemoteRepository.Load` on predefined repositories
140 ('pdb', 'smtl', 'cif', 'pdb_redo')
142 :param from_repo: One of the predefined repositories
143 :type from_repo: :class:`str`
145 remote_repo = REMOTE_REPOSITORIES.get(from_repo,
None)
147 raise ValueError(
'%s is not a valid repository' % from_repo)
148 return remote_repo.Load(id)