Homology analysis using BLAST, Ete3 and Flags2¶
Description¶
This notebook performs an exemplary homology analysis using (remote) BLAST, Ete3, and Flags2. It identifies homologous sequences, constructs phylogenetic trees, and visualizes the gene neighborhood (gene context) of the target gene in various target strains.
Requirements¶
biopythonfor sequence import and transformationsmatplotlibfor plottingete3for phylogenetic tree construction and visualizationflags2(optional) for gene neighborhood visualization
To create a fresh conda environment and activate it:
conda create -p myenv -c conda-forge -c bioconda python=3.12 biopython matplotlib ete3
conda activate myenv
Or select the newly created environment as the kernel in Jupyter Notebook / Jupyter Lab.
Input data¶
- for this example, all input data that is necessary is a protein sequence.
- we use the
input_pblast.fastafile indata/containing a single sequence:
>ORF002752
MKVRPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG*
Remote (p)BLAST search (NCBI)¶
- the script
remote_blast.pycontains functions to perform remote BLAST searches against NCBI - it uses Biopython's
Blast.qblastfunction to submit the query and retrieve results - the user can specify the BLAST program (e.g.,
blastp,blastn, etc.), the target database (e.g.,nr,refseq_protein, etc.), and an optional taxonomicfilterargument to limit the search to specific organisms/taxids - the results are stored as an XML file, identical to the output that can be downloaded from the NCBI BLAST web page
In [1]:
%run -i ../source/remote_blast.py \
-i ../data/input_pblast.fasta \
-o ../output \
-u example@gmail.com \
-f "txid1301[ORGN]"
Started blastp for input: ../data/input_pblast.fasta
Input sequence has length: 39
Submitting BLASTP request to NCBI...
BLASTP result saved to: ../output/results.xml
Total hits found: 32
Top 3 BLASTP hits:
****Alignment****
protein: WP_000868345
description: MULTISPECIES: 50S ribosomal protein L36 [Bacteria]
length: 38
e value: 9.67109e-22
identity: 38
Query : Query_2048673 Length: 39 Strand: Plus
unnamed protein product
Target: ref|WP_000868345.1| Length: 38 Strand: Plus
MULTISPECIES: 50S ribosomal protein L36 [Bacteria]
Score:82 bits(262), Expect:1e-21,
Identities:38/38(100%), Positives:38/38(100%), Gaps:0.38(0%)
ref|WP_00 0 MKVRPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG 38
0 |||||||||||||||||||||||||||||||||||||| 38
Query_204 0 MKVRPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG 38
****Alignment****
protein: WP_136301433
description: 50S ribosomal protein L36 [Streptococcus pyogenes]
length: 38
e value: 2.34347e-21
identity: 37
Query : Query_2048673 Length: 39 Strand: Plus
unnamed protein product
Target: ref|WP_136301433.1| Length: 38 Strand: Plus
50S ribosomal protein L36 [Streptococcus pyogenes]
Score:81 bits(259), Expect:2e-21,
Identities:37/38(97%), Positives:37/38(97%), Gaps:0.38(0%)
ref|WP_13 0 MKVRPSVKPICEYCKAIRRNGRVMVICPTNPKHKQRQG 38
0 |||||||||||||||.|||||||||||||||||||||| 38
Query_204 0 MKVRPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG 38
****Alignment****
protein: WP_082306383
description: 50S ribosomal protein L36 [Streptococcus thermophilus]
length: 38
e value: 2.44435e-21
identity: 37
Query : Query_2048673 Length: 39 Strand: Plus
unnamed protein product
Target: ref|WP_082306383.1| Length: 38 Strand: Plus
50S ribosomal protein L36 [Streptococcus thermophilus]
Score:81 bits(258), Expect:2e-21,
Identities:37/38(97%), Positives:38/38(100%), Gaps:0.38(0%)
ref|WP_08 0 MKVKPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG 38
0 |||.|||||||||||||||||||||||||||||||||| 38
Query_204 0 MKVRPSVKPICEYCKVIRRNGRVMVICPTNPKHKQRQG 38
- in order to work with the BLAST result, we can parse it to FASTA sequences
- this is done using the script
parse_blast_result.py - it extracts all hits from the XML file and saves sequences as
.fastaand protein IDs (WP_numbers) to.txtfiles
In [2]:
%run -i ../source/parse_blast_result.py \
-i ../output/results.xml \
-o ../output/results.fasta
Prepare FASTA file from input: ../output/results.xml Total hits found: 32 Total hits after filtering: 23 Filtered BLASTP results saved to: ../output/results.fasta
- now that results are parsed to FASTA, we can align the sequences using
muscle - install it into the kernel env using
conda install -c bioconda muscle - the aligned sequences are saved to a new, aligned FASTA file
In [3]:
%%bash
muscle -align ../output/results.fasta \
-output ../output/results_aligned.fasta
muscle 5.3.linux64 [] 32.5Gb RAM, 22 cores Built Jul 30 2025 21:13:04 (C) Copyright 2004-2021 Robert C. Edgar. https://drive5.com [align ../output/results.fasta] Input: 23 seqs, avg length 33, max 38, min 18 00:00 9.0Mb 100.0% Derep 23 uniques, 0 dupes 00:00 9.0Mb CPU has 22 cores, running 22 threads 00:00 1.6Gb 100.0% Calc posteriors 00:00 1.6Gb 100.0% UPGMA5 00:00 1.6Gb 100.0% Consistency (1/2) 00:00 1.6Gb 100.0% Consistency (2/2)Consistency (2/2) rt C. Edgar. 1.0% Refining https://drive5.com [align ../output/results.fasta] Input: 23 seqs, avg length 33, max 38, min 18 00:00 9.0Mb 100.0% Derep 23 uniques, 0 dupes 00:00 9.0Mb CPU has 22 cores, running 22 threads 00:00 1.6Gb 100.0% Calc posteriors 00:00 1.6Gb 100.0% UPGMA5 00:00 1.6Gb 100.0% Consistency (1/2) 00:00 1.6Gb 100.0% Consistency (2/2)Consistency (2/2) 00:00 1.6Gb 100.0% Refining
In [4]:
!head -n 6 ../output/results_aligned.fasta
>WP_417159705 50S ribosomal protein L36, partial [Streptococcus pneumoniae] length=25 evalue=1.93602e-06 identity=20 MKVRPSVKPICEKCKVIRRRGKV--------------- >WP_214250541 50S ribosomal protein L36, partial [Streptococcus infantarius] length=29 evalue=1.49855e-13 identity=28 MKVRPSVKPICEYCKVIRRNGRVMVICPS--------- >WP_214250533 50S ribosomal protein L36, partial [Streptococcus infantarius] length=29 evalue=3.98306e-13 identity=27 MKVKPSVKPICEYCKVIRRNGRVMVICPS---------
Cluster aligned sequences¶
- a recurring problem in homology searches is the presence of many highly similar sequences (e.g., from closely related strains/species)
- the following step uses a custom script
cluster_alignment.pyto cluster aligned sequences and prune redundant hits - pruning works by selecting one representative sequence from each cluster based on a similarity threshold (e.g., 85%)
- the threshold means that e.g. all sequences with >85% identity are grouped in the same cluster
In [5]:
%run -i ../source/cluster_alignment.py \
-i ../output/results_aligned.fasta \
-o ../output/results_filtered_085.xml \
--threshold 0.95
Reading alignment: ../output/results_aligned.fasta Aligned sequences: 23 Cluster 1: 2 seqs -> representative WP_161512536 Cluster 2: 3 seqs -> representative WP_172060537 Cluster 3: 1 seqs -> representative WP_136301238 Cluster 4: 1 seqs -> representative WP_086163178 Cluster 5: 1 seqs -> representative WP_082306383 Cluster 6: 1 seqs -> representative WP_268768601 Cluster 7: 1 seqs -> representative WP_093651587 Cluster 8: 1 seqs -> representative WP_083899769 Cluster 9: 1 seqs -> representative WP_136301433 Cluster 10: 1 seqs -> representative WP_269761000 Cluster 11: 1 seqs -> representative WP_449160728 Cluster 12: 1 seqs -> representative WP_195187621 Cluster 13: 2 seqs -> representative WP_214250541 Cluster 14: 1 seqs -> representative WP_195187625 Cluster 15: 1 seqs -> representative WP_301833130 Cluster 16: 1 seqs -> representative WP_417159705 Cluster 17: 1 seqs -> representative WP_192804357 Cluster 18: 1 seqs -> representative WP_455168452 Cluster 19: 1 seqs -> representative WP_431769443 Exported phylogenetic tree as: ../output/results_filtered_085.xml Exported phylogenetic tree as: ../output/results_filtered_085.svg Filtered alignment with 19 records written to: ../output/results_filtered_085.fasta File with 19 protein IDs written to: ../output/results_filtered_085.txt
Plot phylogenetic trees¶
- the previous step has exported a tree in
phyloxmlformat based on the protein alignment - we import
phyloxmlfiles and visualize trees using Ete3'sTreeclass - all tree style options for Ete3 can be passed as a string using the
-sargument - each option is separated by a space, and key-value pairs are connected using
=
In [6]:
!export QT_QPA_PLATFORM=offscreen
%run -i ../source/phylogenetic_tree.py \
-i ../output/results_filtered_085.xml \
-o ../output/results_filtered_085_ete.svg \
-t phylogram \
-s "mode=c show_leaf_name=True arc_start=-90 arc_span=360 scale=600"
Legend written to: ../output/results_filtered_085_ete_legend.svg Tree written to: ../output/results_filtered_085_ete.svg
qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in ""
In [7]:
from IPython.display import SVG, display
display(SVG(filename='../output/results_filtered_085_ete.svg'))
Analyse gene neighborhoods with Flags2¶
- also called gene context or synteny analysis
- Flags2 is a tool to visualize gene neighborhoods around a target gene in multiple genomes
- it can not be installed via conda, but requires manual installation from source (not covered here)
Dependencies¶
- Flags2 requires the following dependencies which can be saved as a conda environment definition
flags2.yml:
yml
name: flags2
channels:
- conda-forge
- bioconda
- etetoolkit
dependencies:
- python=3.6.15
- biopython=1.79
- hmmer=3.4
- mafft=6.861
- ete3=3.1.2
- ete_toolchain=3.0.0
- fasttree=2.1.11
- matplotlib=3.3.4
- pandas=1.1.5
- qt=5.12.9
- pyqt=5.12.3
- trimal=1.4.1
- slr=1.4.3
- to create and activate the environment, run:
conda env create -f flags2.yml
conda activate flags2
Flags2 usage¶
- TODO: example on how to run Flags2
Session info¶
In [8]:
!pip freeze
anyio @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_anyio_1767719033/work argon2-cffi @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi_1749017159514/work argon2-cffi-bindings @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi-bindings_1762509342190/work arrow @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_arrow_1760831179/work asttokens @ file:///home/conda/feedstock_root/build_artifacts/asttokens_1763409923949/work async-lru @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_async-lru_1768752884/work attrs @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_attrs_1764875182/work babel @ file:///home/conda/feedstock_root/build_artifacts/babel_1738490167835/work backports.zstd @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_backports.zstd_1767044984/work beautifulsoup4 @ file:///home/conda/feedstock_root/build_artifacts/beautifulsoup4_1764520477956/work biopython @ file:///home/conda/feedstock_root/build_artifacts/biopython_1768646498748/work bleach @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_bleach_1763589981/work Brotli @ file:///home/conda/feedstock_root/build_artifacts/brotli-split_1764016952863/work cached-property @ file:///home/conda/feedstock_root/build_artifacts/cached_property_1615209429212/work certifi @ file:///home/conda/feedstock_root/build_artifacts/certifi_1767500808759/work/certifi cffi @ file:///home/conda/feedstock_root/build_artifacts/cffi_1761202849623/work charset-normalizer @ file:///home/conda/feedstock_root/build_artifacts/charset-normalizer_1760437218288/work comm @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_comm_1753453984/work contourpy @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_contourpy_1769155975/work cycler @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_cycler_1764466758/work debugpy @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_debugpy_1765840814/work decorator @ file:///home/conda/feedstock_root/build_artifacts/decorator_1740384970518/work defusedxml @ file:///home/conda/feedstock_root/build_artifacts/defusedxml_1615232257335/work entrypoints @ file:///home/conda/feedstock_root/build_artifacts/entrypoints_1733327148154/work ete3 @ file:///home/conda/feedstock_root/build_artifacts/ete3_1688510053282/work exceptiongroup @ file:///home/conda/feedstock_root/build_artifacts/exceptiongroup_1763918002538/work executing @ file:///home/conda/feedstock_root/build_artifacts/executing_1756729339227/work fastjsonschema @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_python-fastjsonschema_1755304154/work/dist fonttools @ file:///home/conda/feedstock_root/build_artifacts/fonttools_1765632549069/work fqdn @ file:///home/conda/feedstock_root/build_artifacts/fqdn_1733327382592/work/dist h11 @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_h11_1767729720/work h2 @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_h2_1756364871/work hpack @ file:///home/conda/feedstock_root/build_artifacts/hpack_1737618293087/work httpcore @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_httpcore_1745602916/work httpx @ file:///home/conda/feedstock_root/build_artifacts/httpx_1733663348460/work hyperframe @ file:///home/conda/feedstock_root/build_artifacts/hyperframe_1737618333194/work idna @ file:///home/conda/feedstock_root/build_artifacts/idna_1760286409563/work importlib_metadata @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_importlib-metadata_1747934053/work importlib_resources @ file:///home/conda/feedstock_root/build_artifacts/importlib_resources_1736252299705/work ipykernel @ file:///home/conda/feedstock_root/build_artifacts/ipykernel_1719845459717/work ipython @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_ipython_1767621166/work ipython_pygments_lexers @ file:///home/conda/feedstock_root/build_artifacts/ipython_pygments_lexers_1737123620466/work isoduration @ file:///home/conda/feedstock_root/build_artifacts/isoduration_1733493628631/work/dist jedi @ file:///home/conda/feedstock_root/build_artifacts/jedi_1733300866624/work Jinja2 @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jinja2_1764517220/work json5 @ file:///home/conda/feedstock_root/build_artifacts/json5_1767324980649/work jsonpointer @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jsonpointer_1765026384/work jsonschema @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jsonschema_1767839954/work jsonschema-specifications @ file:///tmp/tmptzik3dqa/src jupyter-events @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_events_1738765986/work jupyter-lsp @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter-lsp_1756388269/work/jupyter-lsp jupyter_client @ file:///home/conda/feedstock_root/build_artifacts/jupyter_client_1673615989977/work jupyter_core @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_core_1760643864/work jupyter_server @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_server_1755870522/work jupyter_server_terminals @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_server_terminals_1768574057/work jupyterlab @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_1769189931916/work jupyterlab_pygments @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_pygments_1733328101776/work jupyterlab_server @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyterlab_server_1761145478/work kiwisolver @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_kiwisolver_1762488745/work lark @ file:///home/conda/feedstock_root/build_artifacts/lark_1761596826058/work lxml @ file:///home/conda/feedstock_root/build_artifacts/lxml_1762506185769/work MarkupSafe @ file:///home/conda/feedstock_root/build_artifacts/markupsafe_1759055168201/work matplotlib==3.10.8 matplotlib-inline @ file:///home/conda/feedstock_root/build_artifacts/matplotlib-inline_1761214490209/work mistune @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_mistune_1766504456/work munkres==1.1.4 nbclient @ file:///home/conda/feedstock_root/build_artifacts/nbclient_1766485478710/work nbconvert @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_nbconvert-core_1760797634/work nbformat @ file:///home/conda/feedstock_root/build_artifacts/nbformat_1733402752141/work nest_asyncio @ file:///home/conda/feedstock_root/build_artifacts/nest-asyncio_1733325553580/work notebook @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_notebook_1769434091/work notebook_shim @ file:///home/conda/feedstock_root/build_artifacts/notebook-shim_1733408315203/work numpy @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_numpy_1768085749/work/dist/numpy-2.4.1-cp311-cp311-linux_x86_64.whl#sha256=784b36d314f5bb003decb17cb79e0a7c0d98fe7df48b01d41b3f310c3559c206 overrides @ file:///home/conda/feedstock_root/build_artifacts/overrides_1734587627321/work packaging @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_packaging_1769093650/work pandocfilters @ file:///home/conda/feedstock_root/build_artifacts/pandocfilters_1631603243851/work parso @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_parso_1755974222/work pexpect @ file:///home/conda/feedstock_root/build_artifacts/pexpect_1733301927746/work pillow @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_pillow_1767353193/work platformdirs @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_platformdirs_1764950726/work ply @ file:///home/conda/feedstock_root/build_artifacts/ply_1733239724146/work prometheus_client @ file:///home/conda/feedstock_root/build_artifacts/prometheus_client_1768476496023/work prompt_toolkit @ file:///home/conda/feedstock_root/build_artifacts/prompt-toolkit_1756321756983/work psutil @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_psutil_1767012395/work ptyprocess @ file:///home/conda/feedstock_root/build_artifacts/ptyprocess_1733302279685/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl#sha256=92c32ff62b5fd8cf325bec5ab90d7be3d2a8ca8c8a3813ff487a8d2002630d1f pure_eval @ file:///home/conda/feedstock_root/build_artifacts/pure_eval_1733569405015/work pycparser @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_pycparser_1733195786/work Pygments @ file:///home/conda/feedstock_root/build_artifacts/pygments_1750615794071/work pyparsing @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_pyparsing_1769003998/work PyQt5==5.15.11 PyQt5_sip==12.17.0 PySide6==6.10.1 PySocks @ file:///home/conda/feedstock_root/build_artifacts/pysocks_1733217236728/work python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_python-dateutil_1751104122/work python-json-logger @ file:///home/conda/feedstock_root/build_artifacts/python-json-logger_1677079630776/work pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1742920838005/work PyYAML @ file:///home/conda/feedstock_root/build_artifacts/pyyaml_1758891829620/work pyzmq @ file:///home/conda/feedstock_root/build_artifacts/pyzmq_1666828549901/work referencing @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_referencing_1760379115/work requests @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_requests_1766926974/work rfc3339_validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3339-validator_1733599910982/work rfc3986-validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3986-validator_1598024191506/work rfc3987-syntax @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_rfc3987-syntax_1752876729/work rpds-py @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_rpds-py_1764543197/work scipy @ file:///home/conda/feedstock_root/build_artifacts/scipy-split_1768799463219/work/dist/scipy-1.17.0-cp311-cp311-linux_x86_64.whl#sha256=67d34becc84e05628e2b2c0ea857c10bb8618f3284c3065fbe1a6d0bfec9cc14 Send2Trash @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_send2trash_1768402421/work shiboken6==6.10.1 sip @ file:///home/conda/feedstock_root/build_artifacts/sip_1759437862753/work six @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_six_1753199211/work sniffio @ file:///home/conda/feedstock_root/build_artifacts/sniffio_1762941432086/work soupsieve @ file:///home/conda/feedstock_root/build_artifacts/soupsieve_1769034399263/work stack_data @ file:///home/conda/feedstock_root/build_artifacts/stack_data_1733569443808/work terminado @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_terminado_1766513766/work tinycss2 @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_tinycss2_1764621508/work toml @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_toml_1764486833/work tomli @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_tomli_1768146676/work tornado @ file:///home/conda/feedstock_root/build_artifacts/tornado_1765836374256/work traitlets @ file:///home/conda/feedstock_root/build_artifacts/traitlets_1733367359838/work typing_extensions @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_typing_extensions_1756220668/work typing_utils @ file:///home/conda/feedstock_root/build_artifacts/typing_utils_1733331286120/work tzdata @ file:///home/conda/feedstock_root/build_artifacts/python-tzdata_1765719872007/work unicodedata2 @ file:///home/conda/feedstock_root/build_artifacts/unicodedata2_1763054814805/work uri-template @ file:///home/conda/feedstock_root/build_artifacts/uri-template_1733323593477/work/dist urllib3 @ file:///home/conda/feedstock_root/build_artifacts/urllib3_1767817748113/work wcwidth @ file:///home/conda/feedstock_root/build_artifacts/wcwidth_1769601107579/work webcolors @ file:///home/conda/feedstock_root/build_artifacts/webcolors_1761899299899/work webencodings @ file:///home/conda/feedstock_root/build_artifacts/webencodings_1733236011802/work websocket-client @ file:///home/conda/feedstock_root/build_artifacts/websocket-client_1759928050786/work zipp @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_zipp_1764460141/work