enzymetk 0.0.3__py3-none-any.whl → 0.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
enzymetk/__init__.py CHANGED
@@ -22,7 +22,7 @@ Date: March 2025
22
22
  __title__ = 'enzymetk'
23
23
  __description__ = 'Toolkit for enzymes and what not'
24
24
  __url__ = 'https://github.com/arianemora/enzyme-tk/'
25
- __version__ = '0.0.3'
25
+ __version__ = '0.0.6'
26
26
  __author__ = 'Ariane Mora'
27
27
  __author_email__ = 'ariane.n.mora@gmail.com'
28
28
  __license__ = 'GPL3'
@@ -11,16 +11,17 @@ logger.setLevel(logging.INFO)
11
11
 
12
12
  class Chai(Step):
13
13
 
14
- def __init__(self, id_col: str, seq_col: str, substrate_col: str, output_dir: str, num_threads: int):
14
+ def __init__(self, id_col: str, seq_col: str, substrate_col: str, cofactor_col: str, output_dir: str, num_threads: int):
15
15
  self.id_col = id_col
16
16
  self.seq_col = seq_col
17
17
  self.substrate_col = substrate_col
18
+ self.cofactor_col = cofactor_col
18
19
  self.output_dir = output_dir or None
19
20
  self.num_threads = num_threads or 1
20
21
 
21
22
  def __execute(self, df: pd.DataFrame, tmp_dir: str) -> pd.DataFrame:
22
23
  output_filenames = []
23
- for run_id, seq, substrate in df[[self.id_col, self.seq_col, self.substrate_col]].values:
24
+ for run_id, seq, substrate, cofactor in df[[self.id_col, self.seq_col, self.substrate_col, self.cofactor_col]].values:
24
25
  # Might have an issue if the things are not correctly installed in the same dicrectory
25
26
  if not isinstance(substrate, str):
26
27
  substrate = ''
@@ -28,7 +29,8 @@ class Chai(Step):
28
29
  run_chai(run_id, # name
29
30
  seq, # sequence
30
31
  substrate, # ligand as smiles
31
- tmp_dir)
32
+ tmp_dir,
33
+ cofactor) # cofactor as smiles
32
34
  output_filenames.append(f'{tmp_dir}/{run_id}/')
33
35
  return output_filenames
34
36
 
@@ -4,6 +4,7 @@ from docko.docko import *
4
4
  import logging
5
5
  import numpy as np
6
6
  import os
7
+ from pathlib import Path
7
8
  from multiprocessing.dummy import Pool as ThreadPool
8
9
 
9
10
  logger = logging.getLogger(__name__)
@@ -21,34 +22,66 @@ class Vina(Step):
21
22
  self.substrate_col = substrate_col
22
23
  self.substrate_name_col = substrate_name_col
23
24
  self.active_site_col = active_site_col # Expects active site residues as a string separated by |
24
- self.output_dir = output_dir or None
25
+ self.output_dir = Path( output_dir) or None
25
26
  self.num_threads = num_threads or 1
26
27
 
27
28
  def __execute(self, df: pd.DataFrame) -> pd.DataFrame:
28
29
  output_filenames = []
29
30
  # ToDo: update to create from sequence if the path doesn't exist.
30
31
  for label, structure_path, seq, substrate_smiles, substrate_name, residues in df[[self.id_col, self.structure_col, self.sequence_col, self.substrate_col, self.substrate_name_col, self.active_site_col]].values:
31
- os.system(f'mkdir {self.output_dir}{label}')
32
+
32
33
  try:
34
+ structure_path = str(structure_path)
33
35
  residues = str(residues)
34
36
  residues = [int(r) + 1 for r in residues.split('|')]
35
- if not os.path.exists(f'{structure_path}'):
36
- # Try get the AF2 structure we expect the label to be the uniprot id
37
- get_alphafold_structure(label, f'{self.output_dir}{label}/{label}_AF2.pdb')
38
- structure_path = f'{self.output_dir}{label}/{label}_AF2.pdb'
39
- clean_one_pdb(f'{structure_path}', f'{self.output_dir}{label}/{label}.pdb')
40
- pdb_to_pdbqt_protein(f'{self.output_dir}{label}/{label}.pdb', f'{self.output_dir}{label}/{label}.pdbqt')
41
- score = dock(sequence='', protein_name=label, smiles=substrate_smiles, ligand_name=substrate_name, residues=residues,
42
- protein_dir=f'{self.output_dir}', ligand_dir=f'{self.output_dir}', output_dir=f'{self.output_dir}{label}/', pH=7.4,
43
- method='vina', size_x=10.0, size_y=10.0, size_z=10.0)
44
- output_filename = f'{self.output_dir}{label}/{label}.pdb'
45
- output_filenames.append(output_filename)
37
+
38
+ label_dir = self.output_dir / label
39
+ label_dir.mkdir(parents=True, exist_ok=True)
40
+ structure_path = Path(structure_path)
41
+
42
+ if not structure_path.exists():
43
+ # Try to download AF2 structure
44
+ get_alphafold_structure(label, label_dir / f"{label}_AF2.pdb")
45
+ structure_path = label_dir / f"{label}_AF2.pdb"
46
+
47
+ # Skip if still not found
48
+ if not structure_path.exists():
49
+ print(f"Skipping {label}: AF2 structure not found.")
50
+ output_filenames.append(None)
51
+ continue
52
+
53
+ # Proceed with docking
54
+ pdb_path = label_dir / f"{label}.pdb"
55
+ pdbqt_path = label_dir / f"{label}.pdbqt"
56
+
57
+ clean_one_pdb(str(structure_path), str(pdb_path))
58
+ pdb_to_pdbqt_protein(str(pdb_path), str(pdbqt_path))
59
+
60
+ score = dock(
61
+ sequence='',
62
+ protein_name=label,
63
+ smiles=substrate_smiles,
64
+ ligand_name=substrate_name,
65
+ residues=residues,
66
+ protein_dir=str(self.output_dir),
67
+ ligand_dir=str(self.output_dir),
68
+ output_dir=str(label_dir),
69
+ pH=7.4,
70
+ method='vina',
71
+ size_x=10.0,
72
+ size_y=10.0,
73
+ size_z=10.0
74
+ )
75
+
76
+ output_filenames.append(str(pdb_path))
77
+
46
78
  except Exception as e:
47
79
  print(f'Error docking {label}: {e}')
48
80
  output_filenames.append(None)
81
+
49
82
  return output_filenames
50
-
51
-
83
+
84
+
52
85
  def execute(self, df: pd.DataFrame) -> pd.DataFrame:
53
86
  if self.output_dir:
54
87
  if self.num_threads > 1:
@@ -60,4 +93,4 @@ class Vina(Step):
60
93
  df['output_dir'] = results
61
94
  return df
62
95
  else:
63
- print('No output directory provided')
96
+ print('No output directory provided')
@@ -0,0 +1,71 @@
1
+ # ESM 3 script
2
+ from esm.sdk.api import ESMProtein
3
+ from tempfile import TemporaryDirectory
4
+ import torch
5
+ import os
6
+ import pandas as pd
7
+ from esm.models.esm3 import ESM3
8
+ from esm.sdk.api import ESMProtein, SamplingConfig
9
+ from huggingface_hub import login
10
+ from enzymetk.step import Step
11
+ import numpy as np
12
+ from tqdm import tqdm
13
+
14
+ # CUDA setup
15
+ os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" # see issue #152
16
+ cuda = True
17
+ DEVICE = torch.device("cuda" if cuda else "cpu")
18
+ device = DEVICE
19
+
20
+
21
+ class EmbedESM3(Step):
22
+
23
+ def __init__(self, id_col: str, seq_col: str, extraction_method='mean', num_threads=1,
24
+ tmp_dir: str = None, env_name: str = 'enzymetk', save_tensors=False): # type: ignore
25
+ login()
26
+ self.client = ESM3.from_pretrained("esm3-open").to("cuda")
27
+ self.seq_col = seq_col
28
+ self.id_col = id_col
29
+ self.num_threads = num_threads or 1
30
+ self.extraction_method = extraction_method
31
+ self.tmp_dir = tmp_dir
32
+ self.env_name = env_name
33
+ self.save_tensors = save_tensors
34
+
35
+ def __execute(self, df: pd.DataFrame, tmp_dir: str) -> pd.DataFrame:
36
+ client = self.client
37
+ means = []
38
+ for id, seq in tqdm(df[[self.id_col, self.seq_col]].values):
39
+ protein = ESMProtein(
40
+ sequence=(
41
+ seq
42
+ )
43
+ )
44
+ protein_tensor = client.encode(protein)
45
+ output = client.forward_and_sample(
46
+ protein_tensor, SamplingConfig(return_per_residue_embeddings=True)
47
+ )
48
+ if self.save_tensors:
49
+ torch.save(output.per_residue_embedding, os.path.join(tmp_dir, f'{id}.pt'))
50
+ means.append(np.array(output.per_residue_embedding.mean(dim=0).cpu()))
51
+ df['esm3_mean'] = means
52
+ return df
53
+
54
+ def execute(self, df: pd.DataFrame) -> pd.DataFrame:
55
+ if self.tmp_dir is None:
56
+ with TemporaryDirectory() as tmp_dir:
57
+ if self.num_threads > 1:
58
+ dfs = []
59
+ df_list = np.array_split(df, self.num_threads)
60
+ for df_chunk in tqdm(df_list):
61
+ dfs.append(self.__execute(df_chunk, tmp_dir))
62
+ df = pd.DataFrame()
63
+ for tmp_df in tqdm(dfs):
64
+ df = pd.concat([df, tmp_df])
65
+ return df
66
+ else:
67
+ df = self.__execute(df, tmp_dir)
68
+ return df
69
+ else:
70
+ df = self.__execute(df, self.tmp_dir)
71
+ return df
@@ -16,7 +16,8 @@ import os
16
16
 
17
17
  class LigandMPNN(Step):
18
18
 
19
- def __init__(self, pdb_column_name: str, ligand_mpnn_dir: str, output_dir: str, tmp_dir: str = None, args=None, num_threads: int = 1, env_name: str = 'ligandmpnn_env'):
19
+ def __init__(self, pdb_column_name: str, ligand_mpnn_dir: str, output_dir: str,
20
+ tmp_dir: str = None, args=None, num_threads: int = 1, env_name: str = 'ligandmpnn_env'):
20
21
  self.pdb_column_name = pdb_column_name
21
22
  self.ligand_mpnn_dir = ligand_mpnn_dir
22
23
  self.output_dir = output_dir
@@ -34,7 +35,7 @@ class LigandMPNN(Step):
34
35
  os.chdir(self.ligand_mpnn_dir)
35
36
 
36
37
  for pdb_file in df[ self.pdb_column_name].values:
37
- cmd = ['conda', 'run', '-n', self.env_name, 'python3', f'{self.ligand_mpnn_dir}run.py', '--pdb_path', pdb_file, '--out_folder', f'{self.output_dir}']
38
+ cmd = ['conda', 'run', '-n', self.env_name, 'python3', f'{self.ligand_mpnn_dir}run.py', '--pdb_path', pdb_file, '--out_folder', f'{self.output_dir}']
38
39
  if self.args is not None:
39
40
  cmd.extend(self.args)
40
41
  result = subprocess.run(cmd, check=True)
@@ -26,16 +26,16 @@ class ReactionDist(Step):
26
26
  def __execute(self, data: list) -> np.array:
27
27
  reaction_df = data
28
28
  rows = []
29
+ fp_params = rdChemReactions.ReactionFingerprintParams()
30
+ rxn = rdChemReactions.ReactionFromSmarts(self.smiles_string)
31
+ rxn_fp = rdChemReactions.CreateStructuralFingerprintForReaction(rxn, ReactionFingerPrintParams=fp_params) #rdChemReactions.CreateStructuralFingerprintForReaction(rxn, ReactionFingerPrintParams=fp_params)
32
+
29
33
  # compare all fp pairwise without duplicates
30
34
  for smile_id, smiles in tqdm(reaction_df[[self.id_column_name, self.smiles_column_name]].values): # -1 so the last fp will not be used
31
35
  mol_ = rdChemReactions.ReactionFromSmarts(smiles)
32
- fp_params = rdChemReactions.ReactionFingerprintParams()
33
36
  # Note: if you don't pass , ReactionFingerPrintParams=fp_params you get different results
34
37
  # i.e. reactions that don't appear to be the same are reported as similar of 1.0
35
38
  # https://github.com/rdkit/rdkit/discussions/5263
36
- rxn = rdChemReactions.ReactionFromSmarts(self.smiles_string)
37
-
38
- rxn_fp = rdChemReactions.CreateStructuralFingerprintForReaction(rxn, ReactionFingerPrintParams=fp_params)
39
39
  fps = rdChemReactions.CreateStructuralFingerprintForReaction(mol_, ReactionFingerPrintParams=fp_params)
40
40
  rows.append([smile_id,
41
41
  self.smiles_string,
@@ -1,3 +1,5 @@
1
+ import sys
2
+ sys.path.append('/disk1/ariane/vscode/enzyme-tk/')
1
3
  from enzymetk.step import Step
2
4
  import pandas as pd
3
5
  import numpy as np
@@ -8,6 +10,7 @@ from rdkit.Chem import rdChemReactions
8
10
  import pandas as pd
9
11
  import os
10
12
  from rdkit.DataStructs import FingerprintSimilarity
13
+ from rdkit.Chem import rdFingerprintGenerator
11
14
  from rdkit.Chem.Fingerprints import FingerprintMols
12
15
  import random
13
16
  import string
@@ -28,12 +31,15 @@ class SubstrateDist(Step):
28
31
  tmp_label = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
29
32
 
30
33
  rxn = Chem.MolFromSmiles(self.smiles_string)
31
- rxn_fp = FingerprintMols.FingerprintMol(rxn)
34
+ # Switched to using morgan fingerprints https://greglandrum.github.io/rdkit-blog/posts/2023-01-18-fingerprint-generator-tutorial.html
35
+ # followed this tutorial
36
+ mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=2,fpSize=2048)
37
+ rxn_fp = mfpgen.GetFingerprint(rxn)
32
38
  rows = []
33
39
  # compare all fp pairwise without duplicates
34
40
  for smile_id, smiles in tqdm(reaction_df[[self.id_column_name, self.smiles_column_name]].values): # -1 so the last fp will not be used
35
41
  mol_ = Chem.MolFromSmiles(smiles)
36
- fps = FingerprintMols.FingerprintMol(mol_)
42
+ fps = mfpgen.GetFingerprint(mol_)
37
43
  rows.append([smile_id,
38
44
  smiles,
39
45
  DataStructs.TanimotoSimilarity(fps, rxn_fp),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enzymetk
3
- Version: 0.0.3
3
+ Version: 0.0.6
4
4
  Home-page: https://github.com/arianemora/enzyme-tk/
5
5
  Author: Ariane Mora
6
6
  Author-email: ariane.n.mora@gmail.com
@@ -18,17 +18,12 @@ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
18
18
  Requires-Python: >=3.8
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
- Requires-Dist: fair-esm
22
21
  Requires-Dist: scikit-learn
23
22
  Requires-Dist: numpy
24
23
  Requires-Dist: seaborn
25
24
  Requires-Dist: sciutil
26
- Requires-Dist: pandas==2.1.4
25
+ Requires-Dist: pandas
27
26
  Requires-Dist: biopython
28
- Requires-Dist: sentence_transformers
29
- Requires-Dist: pubchempy
30
- Requires-Dist: pyfaidx
31
- Requires-Dist: spacy
32
27
  Dynamic: author
33
28
  Dynamic: author-email
34
29
  Dynamic: classifier
@@ -1,16 +1,17 @@
1
- enzymetk/__init__.py,sha256=M0RnPOHNcHlvlUeRzbaIZmDhumeBjnVxZHXs7s_4g7A,1575
1
+ enzymetk/__init__.py,sha256=q1VxzDTE-F13VrPzIJjRJmwyPEaPfZyqKdkIJx406Ag,1575
2
2
  enzymetk/annotateEC_CLEAN_step.py,sha256=Id4uMtETKjvsnz58SGXlw9r-5T0TYOcvhS3Mi9xhHTw,5448
3
3
  enzymetk/annotateEC_CREEP_step.py,sha256=CZ0mh1UhVp0VShAzHnr9iifB2h1bCeMaHmBUj__t80Y,4215
4
4
  enzymetk/annotateEC_proteinfer_step.py,sha256=GTy27Z5SyG2EPvlf9HTZZ-HRG8FrAs9p0G0OCPmcIW4,6245
5
5
  enzymetk/dock_boltz_step.py,sha256=pHkJSMTgKq0deEM-_cphXlQH1VL73BvRh8JEpv8ighA,1779
6
- enzymetk/dock_chai_step.py,sha256=3LFnsmxmkKWesbM1pXxCUlPDDD0E93ezpojBdEEdVzw,1871
7
- enzymetk/dock_vina_step.py,sha256=_pPJ9ClpMYwPUl6Y7udqzrRzBJeKhENk3U3zy238PVY,3220
6
+ enzymetk/dock_chai_step.py,sha256=YVHJHm1oAN6oOVfi7aV-6cqlQdA05yEIN0lhWAsj4oI,2011
7
+ enzymetk/dock_vina_step.py,sha256=o1M7En9DQPMTJx5Lh29cAPkZTvD3EkNrBvFMGlT-HAo,3826
8
8
  enzymetk/embedchem_chemberta_step.py,sha256=uS7qf_adO0X_sACnCp3ULakTtepx0soHL9y6WMnaaqk,2328
9
9
  enzymetk/embedchem_rxnfp_run.py,sha256=n6ERAhql947-L0-_xvsBHLFyixjUW5yknDPHdM4CNOQ,1061
10
10
  enzymetk/embedchem_rxnfp_step.py,sha256=fmkJcuKpHllDNxkq0zV1jM2R7KREyEEG1KrVngOcvC8,2111
11
11
  enzymetk/embedchem_selformer_run.py,sha256=ibN7pbSRl1YqpHgVVaQKWpUk0E80U5ue_2dDlttn10M,1566
12
12
  enzymetk/embedchem_selformer_step.py,sha256=UQkRc6V7N1Zk3p4gR_MEKALX45bhhGw_8_xc5kM44Yw,1461
13
13
  enzymetk/embedchem_unimol_step.py,sha256=9KL4bto2O1YujZy5UpauBtGlIEUwTRMa8raVqFnX0zQ,2133
14
+ enzymetk/embedprotein_esm3_step.py,sha256=l_8Bfyh0JgJ5R3xo2tPVgrfFBsHqoNGeIIwWwIXzPQI,2575
14
15
  enzymetk/embedprotein_esm_step.py,sha256=f99unRqyfw9Gsr2j7-7rwqtnxdYAZ3RXppLW549vpaE,5896
15
16
  enzymetk/esm-extract.py,sha256=W9n9--Pde2uUuIQP9LrPMHlLZGfpKvrJQ-SuTvGRYmc,5160
16
17
  enzymetk/filter_sequence_step.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -18,7 +19,7 @@ enzymetk/filter_structure_step.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
18
19
  enzymetk/generate_msa_step.py,sha256=w-CrKPMxAwqjsbPQcRq3HP12FyiyuDq0qnt0ObsVhPk,2325
19
20
  enzymetk/generate_oligopool_step.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
21
  enzymetk/generate_tree_step.py,sha256=eee2pILdm3lxVYTsO3CoTCwbY7MfdSK3ve84uMkLwnY,3130
21
- enzymetk/inpaint_ligandMPNN_step.py,sha256=t3A0znvgB44MnAQn_hebOMuhASN2qObbzYLGf8nTPbo,3013
22
+ enzymetk/inpaint_ligandMPNN_step.py,sha256=DOHXTo6BUeEqzYsoJrS5komi1R0yMybeh5ljyRQLIGs,3032
22
23
  enzymetk/main.py,sha256=aY9dEM0a_1jnIJaRTrysLD4KqD5vWMx2OTavh3s4ZxA,1789
23
24
  enzymetk/metagenomics_porechop_trim_reads_step.py,sha256=0-wEDqMRFr5c8TtzUmbgUL6S1UgigR5oOano1l_MYDU,2156
24
25
  enzymetk/metagenomics_prokka_annotate_genes.py,sha256=VdBTkzUUwq4dMHMm-fb7CBVjTH57gRULLfrGJzqBbWg,2572
@@ -33,13 +34,13 @@ enzymetk/save_step.py,sha256=g-1XvurzUNoIRO8pNOHlvVUyTU_87JW-ZFGf5asna2A,293
33
34
  enzymetk/sequence_search_blast.py,sha256=rqtse4lG2Zeg3UgtMIV6RLu7wyv7q7w0SxPia_4N4zE,5022
34
35
  enzymetk/similarity_foldseek_step.py,sha256=_Vrvv6UCwHBP94lS9V5QX61dyxsoAr10gjp1PubXUig,6185
35
36
  enzymetk/similarity_mmseqs_step.py,sha256=FSne7ATtkPBDJzk_-c6W-ZHfGStiGNEtpWMerXlEZZU,3494
36
- enzymetk/similarity_reaction_step.py,sha256=4hVUMLxxkhokoVFkVcWnFfV0H_-uoG7kHIv07g3f4ZQ,2856
37
- enzymetk/similarity_substrate_step.py,sha256=JknH0uhLc1OKVJbnXWtBIArgthXteijl7MuGWzBqVlA,2386
37
+ enzymetk/similarity_reaction_step.py,sha256=yQRyipdG2CyjEZ7hmr4Y-pGa32eAmxjWm4zqABCh6-g,2942
38
+ enzymetk/similarity_substrate_step.py,sha256=Sw8C2TCDHLMoYeay69bj6p_dKhmpMV4hBUkm4pYBBxQ,2732
38
39
  enzymetk/step.py,sha256=LmcIyUh7XFxyt2P2LwtFJZ8Ca9Nyo7nLz6dRejHxkoc,1762
39
- enzymetk-0.0.3.data/data/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- enzymetk-0.0.3.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- enzymetk-0.0.3.dist-info/METADATA,sha256=eFL4-SCDtyE50Admu1H5f29liYHXr04WDc31NBb-9Co,23068
42
- enzymetk-0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
- enzymetk-0.0.3.dist-info/entry_points.txt,sha256=RU3pSTXg2RyNLlc0asRpBYRkmv5GpRP7teeDY7Tr7e0,52
44
- enzymetk-0.0.3.dist-info/top_level.txt,sha256=Qct8wLw9EjZ4yfKaKeJHBjWWuoK_FwHZgbIBb6PwBgg,9
45
- enzymetk-0.0.3.dist-info/RECORD,,
40
+ enzymetk-0.0.6.data/data/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ enzymetk-0.0.6.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ enzymetk-0.0.6.dist-info/METADATA,sha256=vgGo4q5EI_j-lv9EMy16BJOIuiaTgZcC1xMGdLRAc80,22931
43
+ enzymetk-0.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ enzymetk-0.0.6.dist-info/entry_points.txt,sha256=RU3pSTXg2RyNLlc0asRpBYRkmv5GpRP7teeDY7Tr7e0,52
45
+ enzymetk-0.0.6.dist-info/top_level.txt,sha256=Qct8wLw9EjZ4yfKaKeJHBjWWuoK_FwHZgbIBb6PwBgg,9
46
+ enzymetk-0.0.6.dist-info/RECORD,,