From 7528d28279420aa52d2297580d9c7aff60e64d76 Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Wed, 25 Oct 2023 00:54:18 -0500 Subject: [PATCH 1/5] docs: Update installation guide and compatibility matrix --- README.md | 3 +- docs/installation.md | 111 ++++++++++++++++++------------------------- 2 files changed, 47 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 8f2f7cff..2ed247b5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ _An Efficient and Ergonomic Python Binding Library for BLAT_ [![c](https://img.shields.io/badge/C-A8B9CC.svg?style=for-the-badge&logo=C&logoColor=black)](https://www.gnu.org/software/gnu-c-manual/) [![pypi](https://img.shields.io/pypi/v/pxblat.svg?style=for-the-badge)][pypi] [![conda](https://img.shields.io/conda/vn/bioconda/pxblat?style=for-the-badge)][conda] -![platform](https://img.shields.io/static/v1?style=for-the-badge&label=platform&message=macos%20%7C%20linux&color=brightgreen) +![Linux](https://img.shields.io/badge/-Linux-grey?logo=linux&style=for-the-badge) +![macOS](https://img.shields.io/badge/-OSX-black?logo=apple&style=for-the-badge) [![pyversion](https://img.shields.io/pypi/pyversions/pxblat?style=for-the-badge)][pypi] [![tests](https://img.shields.io/github/actions/workflow/status/cauliyang/pxblat/tests.yml?style=for-the-badge&logo=github&label=Tests)](https://github.com/cauliyang/pxblat/actions/workflows/tests.yml) [![Codecov](https://img.shields.io/codecov/c/github/cauliyang/pxblat/main?style=for-the-badge)](https://app.codecov.io/gh/cauliyang/pxblat) diff --git a/docs/installation.md b/docs/installation.md index 02a0116e..9c7dfb4e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,95 +1,74 @@ -# Install +# Installation Guide -## **Prerequisites** +Welcome to the installation guide for **PxBLAT**! +Below, you'll find straightforward instructions on how to install **PxBLAT** on your system. +You can choose between `CONDA` and `PyPI` for installation, depending on your preference. -```{tip} -I highly recommend to install `PxBLAT` via `CONDA` such that you do not need to -install dependencies [goto ➡️](#get-started). -``` +## Get started -Before you begin with the installation and use of **PxBLAT**, there are certain prerequisites that need to be met. -The following sections detail the necessary software, hardware, and knowledge prerequisites that you should have before you start. -**PxBLAT** has been tested and runs on the following operating systems **Linux** and **MacOS**. -Choosing appropriate dependencies manager according to the operating systems. -You should have an active and stable internet connection for downloading and installing the software: +Installing **PxBLAT** is a breeze, whether you prefer using `CONDA` or `PyPI`. +Simply follow the tabs below to choose your preferred installation method. `````{md-tab-set} -````{md-tab-item} Brew +````{md-tab-item} Pip + +To install using `pip`, run the following command in your terminal: + ```{code-block} bash -brew install htslib openssl +pip install pxblat ``` + +This will fetch the latest version of **PxBLAT** and install it on your system. ```` ````{md-tab-item} Conda + +To install using `conda`, execute the following command: + ```{code-block} bash -conda install htslib openssl -``` -```` -````{md-tab-item} Apt-get -```{code-block} bash -apt-get update && apt-get install libhts-dev libssl-dev +conda install pxblat ``` +This command will install **PxBLAT** from the [conda] repository. ```` ````` -## **Get Started** +## Compatibility and Support -Installing **PxBLAT** via `CONDA` **do not requires** the prerequisites. -Installing **PxBLAT** via `PyPI` requires the prerequisites. -Once you have confirmed the prerequisites, you can proceed with the software installation: +Below is a compatibility matrix that shows the support status of **PxBLAT** across different platforms and Python versions. -`````{md-tab-set} +### [Conda Support][conda] -````{md-tab-item} Conda -```{code-block} bash -conda install pxblat -``` -```` - -````{md-tab-item} Pip -```{code-block} bash -pip install pxblat -``` -```` - -````` +| Python Version | Linux x86_64 | macOS Intel | +| :------------: | :----------: | :---------: | +| 3.9 | ✅ | ✅ | +| 3.10 | ✅ | ✅ | +| 3.11 | ✅ | ✅ | +| 3.12 | ⚫ | ⚫ | -``````{warning} -You meet the issue _*.h cannot found_ or _undefined symbol **_ If you install `pxblat` by `pip`. -If you have installed the prerequisites, the problem is caused by incorrect environment variable {envvar}`CFLAGS`, `CXXFLAGS`, -and `LDFLAGS`, which direct compiler and linker find right location of -dependencies so as to compile and link code properly. -**The easy solution** is to install **PxBLAT** via `conda`. -You can also set proper environment variable if `conda` is not accessible. +### [PyPI Support][pypi] +| Python Version | Linux x86_64 | macOS Intel | macOS Apple Silicon | +| :------------: | :----------: | :---------: | :-----------------: | +| 3.9 | ✅ | ✅ | ✅ | +| 3.10 | ✅ | ✅ | ✅ | +| 3.11 | ✅ | ✅ | ✅ | +| 3.12 | ⚫ | ⚫ | ⚫ | -`````{md-tab-set} +## Frequently Asked Questions (FAQ) -````{md-tab-item} Bash/Zsh -```{code-block} bash -export CFLAGS="-Idependencies" -export CXXFLAGS="-Idependencies" -... -``` -```` +- **Q1**: I'm unable to install `PxBLAT` via `Conda` on my macOS device with an Arm-based processor (M1 or M2). What should I do? -````{md-tab-item} Fish -```{code-block} fish -set -x CFLAGS="-Idependencies" -set -x CXXLAGS="-Idependencies" -... -``` -```` -````` + > **A**: Currently, `Conda` provides **PxBLAT** built for x86 architectures. For Arm-based macOS devices, we recommend installing **PxBLAT** via `PyPI` instead: -`````` + ```bash + pip install pxblat + ``` -## **FAQ (Frequently Asked Questions)** +You've successfully installed **PxBLAT**! Feel free to dive into a real usage case ({doc}`tutorial`) to start exploring its functionalities. -1. I cannot download `PxBLAT` via `Conda` in MacOS with Arm (M1 or M2). + -A: So far, conda build `PxBLAT` in x86 instead of arrch64. -Hence we can install [prerequisites](#prerequisites) manually via `brew` or `Conda`. -Then, we can use `pip install pxblat` to install `PxBLAT`. +[conda]: https://anaconda.org/bioconda/pxblat +[pypi]: https://pypi.org/project/pxblat/ From e3c4650ae833085d26e3d931369e2f60b585efab Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Wed, 25 Oct 2023 03:20:21 -0500 Subject: [PATCH 2/5] docs: rewrite toturial --- docs/installation.md | 2 +- docs/tutorial.md | 294 ++++++++++++++++++++------- docs/tutorial_data/2bit.py | 10 + docs/tutorial_data/query_context.py | 28 +++ docs/tutorial_data/test_case1.fa | 5 + docs/tutorial_data/test_ref.2bit | Bin 0 -> 3911 bytes docs/tutorial_data/test_ref.fa | 301 ++++++++++++++++++++++++++++ poetry.lock | 8 +- pyproject.toml | 1 + 9 files changed, 568 insertions(+), 81 deletions(-) create mode 100644 docs/tutorial_data/2bit.py create mode 100644 docs/tutorial_data/query_context.py create mode 100644 docs/tutorial_data/test_case1.fa create mode 100644 docs/tutorial_data/test_ref.2bit create mode 100644 docs/tutorial_data/test_ref.fa diff --git a/docs/installation.md b/docs/installation.md index 9c7dfb4e..ee814a27 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,4 +1,4 @@ -# Installation Guide +# **Installation Guide** Welcome to the installation guide for **PxBLAT**! Below, you'll find straightforward instructions on how to install **PxBLAT** on your system. diff --git a/docs/tutorial.md b/docs/tutorial.md index 7a920985..2ff4f2c5 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -1,60 +1,122 @@ # **Tutorial** -`PxBLAT` binds the codebase of [BLAT(v.37x1)][BLAT(v.37x1)], and aims to provide efficient and -ergonomic APIs. Let's take the journey to show features `PxBLAT` provides. +```{warning} +Make sure you have installed PxBLAT, otherwise please go-to ({doc}`installation`). +``` -## APIs Compared to `BLAT` +```{tip} +We do not assume you already know common formats and BLAT, which is a standout within the bioinformatics landscape and is recognized for its capability to conduct genome sequence alignments. +BLAT can help us know where one or several sequences can be mapped to the reference for nucleotide or peptide sequences. +Assume we have multiple sequences, and want to know where these sequences can be mapped in reference sequence. +After reading the tutorial, you are supported to know how to use PxBLAT to align your sequences. +``` -So far, `PxBLAT` provides four main APIs, including {class}`.Client`, {class}`.Server`, {func}`.two_bit_to_fa` and {func}`.fa_to_two_bit`, -as well as other useful functions ({doc}`reference`). -`PxBLAT` is able to finish the most significant features of `BLAT`. -Here is a table in which the features are compared. +**PxBLAT** binds the codebase of [BLAT(v.37x1)][BLAT(v.37x1)], and aims to provide efficient and +ergonomic APIs. Let's take the journey to show features **PxBLAT** provides. -| PxBLAT | BLAT | -| :--------------------- | :----------------------- | -| {class}`.Client` | [gfClient][gfClient] | -| {class}`.Server` | [gfServer][gfServer] | -| {func}`.two_bit_to_fa` | [twoBitToFa][twoBitToFa] | -| {func}`.fa_to_two_bit` | [faToTwoBit][faToTwoBit] | +## 1. Understanding the FASTA Format -## Options Design +In bioinformatics, the FASTA format is a widely used text-based format for representing nucleotide sequences or peptide sequences and their associated information. +Below, we will introduce the FASTA format, its structure, and how it is utilized in bioinformatics applications. -`PxBLAT` uses a extra class to hold and change parameters for {class}`.Server` -and {class}`.TwoBitToFaOption`. -The design is a trick to mimic named parameter, and is used in Cpp and Rust. -Python may not need to the design but it still benefit if the parameters are too -long. -For example, `PxBLAT` can create and change parameters of {class}`.Server` via {meth}`.Server.create_option`. -The chain methods of options is builder pattern which is used in Cpp and Rust. +The FASTA format is a simple, text-based format for representing biological sequences. +Each entry in a FASTA file begins with a single-line description, followed by the sequence data. +The description line is distinguished from the sequence data by a greater-than (`>`) symbol at the beginning. -```{tip} -Click the blinking circle cross, and you will be blessed and get more information. +### Structure of a FASTA File + +Here is an example to illustrate the structure of a FASTA file: + +``` +>sequence1 +ATGCTAGCTAGCTAGCTAGCTAGCTA +GCTAGCTAGCTAGCTAGCTAGCTAGC +TAGCTAGCTAGCTAGCTAGCTAGCTA ``` -```{eval-rst} -.. code-block:: python - :linenos: +In this example: - from pxblat import Server +- `>sequence1` are description lines for two different sequences. +- The sequences themselves are represented in the lines following the description lines. +- Sequences can span multiple lines for readability, and there are no line length restrictions. - server_option = Server.create_option().withStepSize(3).withTileSize(10).build() # (1)! - server = Server("localhost", port, two_bit, server_option) +In bioinformatics, the FASTA format is used to represent sequences for various applications, such as: -.. code-annotations:: - #. we change step size and tile size +- Sequence alignment: Comparing sequences to find similarities and differences. +- Database search: Searching for sequences in large databases. +- Phylogenetics: Studying the evolutionary relationships between sequences. + +The FASTA format is a fundamental part of bioinformatics, providing a simple and efficient way to represent biological sequences. +Understanding this format is crucial for anyone looking to work in the field or use bioinformatics tools, including **PxBLAT**. + +## 2. Prepare Example Data + +### Download sequences and reference examples + +- Let's create a new directory first. + +```bash +mkdir tutorial +cd tutorial ``` -The options have same parameter as its command line version of `BLAT`. -{doc}`reference` includes all possible parameters the option will accept. +- Download reference data `test_ref.fa`, which is fasta format. -## From FASTA to 2bit +```bash +wget https://raw.githubusercontent.com/ylab-hi/pxblat/main/tests/data/test_ref.fa +``` -Before we query certain sequence to a reference, we need to generate [.2bit][.2bit] file from [fasta][fasta] format. -`PxBLAT` provides a free function {func}`.fa_to_two_bit`. -Also, `PxBLAT` support to convert the `.2bit` file back to fasta format via {func}`.two_bit_to_fa`, for example, +Let's check the reference data + +```console +$ head test_ref.fa +>chr1 +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +taaccctaaccctaaccctaaccctaaccctaaccctaaccctaacccta +accctaaccctaaccctaaccctaaccctaaccctaaccctaaccctaac +cctaacccaaccctaaccctaaccctaaccctaaccctaaccctaacccc +taaccctaaccctaaccctaaccctaacctaaccctaaccctaaccctaa +ccctaaccctaaccctaaccctaaccctaacccctaaccctaaccctaaa +ccctaaaccctaaccctaaccctaaccctaaccctaaccccaaccccaac +cccaaccccaaccccaaccccaaccctaacccctaaccctaaccctaacc +ctaccctaaccctaaccctaaccctaaccctaaccctaacccctaacccc + +$ wc -l test_ref.fa +301 test_ref.fa +``` + +- Download test sequences `test_case1.fa`, which is fasta format. + +```bash +wget https://raw.githubusercontent.com/ylab-hi/pxblat/main/tests/data/test_case1.fa +``` + +Let's check test reference + +```bash +$ head test_case1.fa +>case1 +TGAGAGGCATCTGGCCCTCCCTGCGCTGTGCCAGCAGCTTGGAGAACCCA +CACTCAATGAACGCAGCACTCCACTACCCAGGAAATGCCTTCCTGCCCTC +TCCTCATCCCATCCCTGGGCAGGGGACATGCAACTGTCTACAAGGTGCCA +A +``` + +Now we already have `test_case1.fa` and `test_ref.fa` for following analysis. + +```bash +$ ls +test_case1.fa test_ref.fa +``` + +## 3. Convert FASTA to 2bit + +Before we query certain sequence to a reference `test_ref.fa`, we need to convert [fasta][fasta] format to [.2bit][.2bit] file for reference sequence `test_ref.fa`. +**PxBLAT** provides a function {func}`.fa_to_two_bit`. +Also, **PxBLAT** supports to convert the `.2bit` file back to fasta format via {func}`.two_bit_to_fa`, for example, ```{tip} -The source code includes [chr20.fa] and [chr20.2bit] as well, making it easy for users to give it a try. +Click the blinking circle cross, and you will be blessed and get more information. ``` ```{eval-rst} @@ -64,8 +126,8 @@ The source code includes [chr20.fa] and [chr20.2bit] as well, making i from pxblat import fa_to_two_bit fa_to_two_bit( - ["fasta1.fa"], # (1)! - "out.2bit", # (2)! + ["test_ref.fa"], # (1)! + "test_ref.2bit", # (2)! noMask=False, stripVersion=False, ignoreDups=False, @@ -77,6 +139,21 @@ The source code includes [chr20.fa] and [chr20.2bit] as well, making i #. Output file path ``` +Let's create a Python file named `2bit.py`, and copy and past code above to `2bit.py`. +Then, execute the `2bit.py` + +```bash +python 2bit.py +``` + +After, we will get a new file named `test_ref.2bit`, which is the 2bit file we +need to align sequences to reference. + +```bash +$ ls +2bit.py test_case1.fa test_ref.2bit test_ref.fa +``` + The code equals `faToTwoBit fasta1.fa out.2bit` by `BLAT(v. 37x1)`. ```bash @@ -91,49 +168,76 @@ options: -stripVersion Strip off version number after '.' for GenBank accessions. -ignoreDups Convert first sequence only if there are duplicate sequence names. Use 'twoBitDup' to find duplicate sequences. -$ faToTwoBit fasta1.fa out.2bit +$ faToTwoBit test_ref.fa test_ref.2bit $ ls -out.2bit fasta1.fa +test_ref.2bit test_ref.fa ``` -Moreover, `PxBLAT` provides flexible options to allow conducting the conversion in {doc}`cli`. +Moreover, **PxBLAT** provides flexible options to allow conducting the conversion in {doc}`cli`. -## Query Sequences +## 4. Query Sequences -Most simple method to query sequence is to open {class}`pxblat.Server` in context mode +**PxBLAT** contains {class}`pxblat.Server` and {class}`pxblat.Client`. +We use them to align our sequences in two steps. + +1. start {class}`pxblat.Server` +2. {class}`pxblat.Client` send our sequence to {class}`pxblat.Server` for + alignment + +Generally, {class}`pxblat.Server` has three status including `preparing`, `ready`, and `stop`. +It only accepts sequence alignment task in `ready` status. +Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready` status before {class}`pxblat.Client`send sequences. +**PxBLAT** allow this process more smooth without bothering intermediate file. + +**PxBLAT** provide several ways to start the {class}`pxblat.Server`. + +### 4.1 Start {class}`pxblat.Server` in context mode ```{eval-rst} .. code-block:: python :linenos: - from pxblat import Server, Client + from pxblat import Client, Server - client = Client( - host="localhost", - port=65000, # (1)! - seq_dir=two_bit, # (2)! - min_score=20, - min_identity=90, - ) - server_option = Server.create_option().withCanStop(True).withStepSize(5).build() # (3)! - with Server("localhost", port, two_bit, server_option) as server: - work() # (4)! - server.wait_for_ready() # (5)! - result1 = client.query("ATCG") # (6)! - result2 = client.query("AtcG") # (7)! - result3 = client.query(["ATCG", "ATCG"]) # (8)! - result4 = client.query(["fasta1.fa", "fasta2.fa"]) # (9)! - result5 = client.query(["cgTA", "fasta.fa"]) # (10)! + def query_context(): + host = "localhost" # (1)! + port = 65000 # (2)! + seq_dir = "." # (3)! + two_bit = "./test_ref.2bit" # (4)! + + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, # (5)! + min_identity=90, # (6)! + ) + + with Server(host, port, two_bit, can_stop=True, step_size=5) as server: + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() # (7)! + result1 = client.query("ATCG") # (8)! + result2 = client.query("AtcG") # (9)! + result3 = client.query(["ATCG", "ATCG"]) # (10)! + result4 = client.query(["test_case1.fa"]) # (11)! + result5 = client.query(["cgTA", "test_case1.fa"]) # (12)! + print(result4[0]) + + + if __name__ == "__main__": + query_context() .. code-annotations:: - #. The port number of current running :class:`.Server` - #. The two bit files from reference, and we can get it via :func:`.fa_to_two_bit` or via :doc:`cli` - #. Create :class:`.ServerOption` with specific parameters for :class:`.Server` - #. We can do some other stuffs that consuming time - #. Block current thread to wait server to be ready + #. :attr:`.Client.host` is the hostname or IP address of the current running :class:`.Server`. + #. :attr:`.Client.post` is the port number of the current running :class:`.Server`. + #. :attr:`.Client.seq_dir` is the directory including `test_ref.fa` and `test_ref.2bit` + #. `two_bit` is the 2bit file [we already create](#3-convert-fasta-to-2bit) + #. :attr:`.Client.min_score` is the minimum score for the alignment. + #. :attr:`.Client.min_identity` is the minimum identity for the alignment. + #. block current thread to wait server to be ready #. :meth:`.Client.query` accepts a :class:`str` consisting of DNA or Protein Sequences, e.g. `"ATCG"` - #. :meth:`.Client.query` accepts a path of Fasta file, e.g. `"data/fasta1.fa"` + #. :meth:`.Client.query` accepts a path of Fasta file, e.g. `"./test_case1.fa"` #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` consisting of DNA or Protein Sequences, e.g. `["ATCG","CTGAG"]` #. :meth:`.Client.query` accepts a :class:`list` of path of Fasta files, e.g. `["data/fasta1.fa", "data/fasta2.fa"]` #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` and path, e.g. `["ATCG", "data/fasta1.fa"]` @@ -141,15 +245,31 @@ Most simple method to query sequence is to open {class}`pxblat.Server` in contex {meth}`.Client.query` accepts parameters of several types: -1. Path of Fasta file e.g. `data/fasta1.fa` +1. Path of fasta file e.g. `data/fasta1.fa` 2. {class}`list` of {class}`str` consisting of DNA or Protein Sequences, e.g. `["ATCG","CTGAG"]` -3. {class}`list` of path of Fasta files, e.g. `["data/fasta1.fa", "data/fasta2.fa"]` +3. {class}`list` of path of fasta files, e.g. `["data/fasta1.fa", "data/fasta2.fa"]` 4. {class}`list` of `str` and path, e.g. `["ATCG", "data/fasta1.fa"]` 5. {meth}`.Client.query` accepts a {class}`list` of {class}`str` and path, e.g. `["ATCG", "data/fasta1.fa"]` -{meth}`.Client.query` return [Bio.SearchIO.QueryResult](#query-result). +{meth}`.Client.query` return [`QueryResult`](#query-result). + +Let's Create a new Python script named `query_context.py`, and copy above to the +script. +Then execute the Python script. + +```bash +$ python query_context.py +Program: blat (v.37x1) + Query: case1 (151) + + Target: + Hits: ---- ----- ---------------------------------------------------------- + # # HSP ID + description + ---- ----- ---------------------------------------------------------- + 0 1 chr1 +``` -We may need to query sequences in more general way, for example, +### 4.2 Start {class}`pxblat.Server` in general mode ```{eval-rst} .. code-block:: python @@ -357,6 +477,32 @@ Hence, we can manipulate the query result as shown below. ``` +## APIs Compared to `BLAT` + +So far, **PxBLAT** provides APIs, including {class}`.Client`, {class}`.Server`, {func}`.two_bit_to_fa` and {func}`.fa_to_two_bit`, +as well as other useful functions ({doc}`reference`). +**PxBLAT** is able to finish the most significant features of `BLAT`. +Here is a table in which the features are compared. + +| PxBLAT | BLAT | +| :--------------------- | :----------------------- | +| {class}`.Client` | [gfClient][gfClient] | +| {class}`.Server` | [gfServer][gfServer] | +| {func}`.two_bit_to_fa` | [twoBitToFa][twoBitToFa] | +| {func}`.fa_to_two_bit` | [faToTwoBit][faToTwoBit] | + +```{eval-rst} +.. code-block:: python + :linenos: + + from pxblat import Server + + server = Server("localhost", port, two_bit, server_option) # (1)! + +.. code-annotations:: + #. we change step size and tile size +``` + ## Beyond APIs Even though `PxBLAT` is designed as library, it provides command-line tools @@ -364,10 +510,6 @@ using its APIs. That could provide more choices for user according to different situations. {doc}`reference` contain more details, and do not hesitate to check. -## Caveats - -{class}`.ServerOption` hold most important parameters that are passed to {class}`.Server`. - [gfclient]: https://genome.ucsc.edu/goldenpath/help/blatSpec.html#gfClientUsage diff --git a/docs/tutorial_data/2bit.py b/docs/tutorial_data/2bit.py new file mode 100644 index 00000000..4b1b37da --- /dev/null +++ b/docs/tutorial_data/2bit.py @@ -0,0 +1,10 @@ +from pxblat import fa_to_two_bit + +fa_to_two_bit( + ["test_ref.fa"], + "test_ref.2bit", + noMask=False, + stripVersion=False, + ignoreDups=False, + useLong=False, +) diff --git a/docs/tutorial_data/query_context.py b/docs/tutorial_data/query_context.py new file mode 100644 index 00000000..71556cad --- /dev/null +++ b/docs/tutorial_data/query_context.py @@ -0,0 +1,28 @@ +from pxblat import Client, Server + +def query_context(): + host = "localhost" + port = 65000 + seq_dir = "." + two_bit = "./test_ref.2bit" + + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, + min_identity=90, + ) + + with Server(host, port, two_bit, can_stop=True, step_size=5) as server: + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() + result1 = client.query("ATCG") + result2 = client.query("AtcG") + result3 = client.query(["ATCG", "ATCG"]) + result4 = client.query(["test_case1.fa"]) + result5 = client.query(["cgTA", "test_case1.fa"]) + print(result4[0]) + +if __name__ == "__main__": + query_context() diff --git a/docs/tutorial_data/test_case1.fa b/docs/tutorial_data/test_case1.fa new file mode 100644 index 00000000..7f77c66c --- /dev/null +++ b/docs/tutorial_data/test_case1.fa @@ -0,0 +1,5 @@ +>case1 +TGAGAGGCATCTGGCCCTCCCTGCGCTGTGCCAGCAGCTTGGAGAACCCA +CACTCAATGAACGCAGCACTCCACTACCCAGGAAATGCCTTCCTGCCCTC +TCCTCATCCCATCCCTGGGCAGGGGACATGCAACTGTCTACAAGGTGCCA +A diff --git a/docs/tutorial_data/test_ref.2bit b/docs/tutorial_data/test_ref.2bit new file mode 100644 index 0000000000000000000000000000000000000000..f819b533af878fbc213d0b7beb3e5c961a4a847b GIT binary patch literal 3911 zcmZ{idt6gjw#P$x%qT?-B&opk*0$>Sm?~)!R6>Gj60Dj-5^{)yQv{j^&m?we?X^}> zE4Eb;93BPJjhNdl91$Prqk)?-p}W*&-(7Q z_HRA*Kb!h{N(>@kLH|4g7Q)Z_BQ`pae39_0hz;CV1^8z~h9MB@0KF&#!h}H}@&n_Z z*AR&HzegZAn-PeKZ3x6690KvXcm!hS4g}&iI}wO)LlKDPz-(>+C;&ddx&Rjf+zPy0 z9f&0XmIKTMs1I-{!2h+CV8g!u$MaLGH~;LvH2nMetJs+O%XC^p#?KBm{Hwg-KU-6) z|C8=Z`+395&p`39%*-t9G|^Ux&!i|fd~uy&QRiFe#+PAQmUfV6`|4`up>fs3hgpXg zCH4<9M<-Mk<;3U*i_*ik#SbQqStgYKyI5ED#@|YGD&4Q`U9}H0`!xTS4*zRIK$`eP z`mr#zq~xjJ`{15bapUl@QHQ_8x4ig{d7}H`m$|wRCzO{58e%scY|eT-ZKP7gB?8&> z`}o{J9JH7Qkft>G@m^#^_-!5Z0jQrSF~@t^5i8#O18g4UFvZ(vA~Yy!a?b!s@qrNU z()$FXP8vR=sPczX+h>Kx$I9XolLs#D`^*=b^g{EN>(|e(3{FT{k<36bwbmhUCo7HK&Gx9e$1pw+^u-NHBQq!KZhdI{n|B&* z5#leNt&PqOLL9nE=r;rfS5boE_-_U?Xm3Cj2e7+&B`ji(Xqj4u)2;=2v{RUIfW$B@ zkLwl8+w(yTkJ?1orkiwr61Ik!7N;Hi{;khNHLmUMPO`gm-ZqvWlAOQa^!)%HmyD$9 zcYf(~?x8F6)2WMnf4$@JlDn#I=S?oYI z7T{6BTWrTI)u$fI2^(R410lF}a zwAS68P$iK^(Oj}w)z#gX$<^Zwg%B$fm7v%1Wca7=2tls;)&f!dB1ezq$0{y!+moXF zZg{OHZSN!QebjsOC=Ln#1IcCAl(+Bt%G*3b_kuz>)E5MG8a(c{l%eIPu)8`D4W%8Q z+Op9-+a{HLeF4>>hBaSh{A(kzo}gH;`bq<+b` zt68jnR+!xQ?jYm>-nUGsKFz5s(*7-4;aXcH$Jp6D5OT{mNVUU4+Ldh}XRdMGZ|y`f zidO02j&1g4`kzSXMroV;9M|P>*sGW%r*s(N6ZZQQeu!D9@arti!jG3?9Uh0 z;6b1Ty+ z9-6~gBa2ow3QoMpSN0}9aKo-%ayda`(YVS=j6KKdHxlo!&Kq?tsCv}o+Pq{J$JoOZZM)SQwFI<= zTb9n-VA&F&v1Alh;o{lp%kHh-3^BFR=ApS%9A~8vi(zAVAeY0y=xH?kh*8fem_DNk6JsCRA>6H0TSST@Z+^CUIVnMFqzmA2CpAIvyDn{XNJv2dP)!;3(v1l12pvsX&8`*&OJqGx; zPLZ9dr}NnHLe%g+u@aC%#@KOh)D3BWDiv}*UQH;~I3o-Hae6v_`RM#EIHi{(NFG>H zrQ%JTjrh}ZGX}^dvX`&h$QSV+rX-Dg1cg{dcQ_8=Nz9MNqK-i~=0v}yu(qA0ZIHY`w!}pz7b+N^< zH7RAG8%8PAoYE=qPvmoMJNevGw#;5O&();YJ9Q^kh6eQ}7ur7?@mF%y^n+~F?m+b>nWAWHPrKrI@MX&8rZoeXCatggSF3Hc=Vq@c zGcMGKxozf~PwJ;0K`gW9IaAVCdNVt}>S^~?KO~a6ms=9Uc77D&kmMnnP4!L6;FSxVg1vm>|s`&!O#I(D{soOpV>Sw_zU zDFjMsNZ1+6Qn7$WHu1Wz+2b*0(X32fBWYB^m21;5TA&WyVUbwuN`)Ax-xmy7qXD3w zY3?!&IhCW1!6bvVB+;*IM}kHM?WK5+_54cz<=$pybSdwnW-d8@Rxaqk7MY})ah=-J zvp9$r@CfbwOd5y|LmdK7_os(q?+4L-(h31KhgyhcFyztT{Z~`=ej}qKVL4+wB$7o% zhYlSl5T8)ES1H(Z(1f`hxwHL-WWqr!Fy}K_f_!wiDjg-BJ|aK~WTc3fjFQW}L(gV)?J+AYWF6qm`5%KfqJc zVkl{KE+X;g0EA`%5GP=xgMeinv!x=D4Q$Fh~B|4S*W(^x|oE+ zX3Sn_mJmvyu}gC}E`RMfV{aSbM$MACt@*2hD`Gt;nRC?~?n|eRyX(GwNmGA^L_fI| zzf=yJHZeOUM^<(LrE9>RzCEt&H!gLyTxtval;9QXV9T8g<@p7!2bcRhU%lp2p36qf z4X478IW8R)aX$FeiEm!G{`FpI%Z5`cL=~d?ZlV1x`_pAY;a!P)R_4<`CT6%|=xv+9 zB0)3`3qGw}I=QM~kGJLH`69o)B6hB48GRF$wR-dgLu!i`vp|}u@o8i(A8B>XQB~Ev zv`DlbUAerMPaK1jN|V~U3fU)$B7W;^mQCX}9BJSz?XGER9k0t42>9V=>xc>cOnKqd zpgmS#`n6<^S0r`i_ePpLAL_HEi6R<-8C{3ckXm_3t+=AmtPs`z9*qwd=NBu0de!9PVbl zpdcm@mwV^4pH2;}Xj*sXTov{bW8K`xG3NBp^9Ifq`w$;ta1A>;LhZEmQT^a+xxHy@9;cL;c9fo;ztdJ^mq`xVlQ;ipAJiKu@J~EHekc|ru5XmZDT eQaF$YKgO2L^9LEr$49OGR$*>UR&JWG_J08F%DsC4 literal 0 HcmV?d00001 diff --git a/docs/tutorial_data/test_ref.fa b/docs/tutorial_data/test_ref.fa new file mode 100644 index 00000000..d221cbac --- /dev/null +++ b/docs/tutorial_data/test_ref.fa @@ -0,0 +1,301 @@ +>chr1 +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +taaccctaaccctaaccctaaccctaaccctaaccctaaccctaacccta +accctaaccctaaccctaaccctaaccctaaccctaaccctaaccctaac +cctaacccaaccctaaccctaaccctaaccctaaccctaaccctaacccc +taaccctaaccctaaccctaaccctaacctaaccctaaccctaaccctaa +ccctaaccctaaccctaaccctaaccctaacccctaaccctaaccctaaa +ccctaaaccctaaccctaaccctaaccctaaccctaaccccaaccccaac +cccaaccccaaccccaaccccaaccctaacccctaaccctaaccctaacc +ctaccctaaccctaaccctaaccctaaccctaaccctaacccctaacccc +taaccctaaccctaaccctaaccctaaccctaaccctaacccctaaccct +aaccctaaccctaaccctcgcggtaccctcagccggcccgcccgcccggg +tctgacctgaggagaactgtgctccgccttcagagtaccaccgaaatctg +tgcagaggacaacgcagctccgccctcgcggtgctctccgggtctgtgct +gaggagaacgcaactccgccgttgcaaaggcgcgccgcgccggcgcaggc +gcagagaggcgcgccgcgccggcgcaggcgcagagaggcgcgccgcgccg +gcgcaggcgcagagaggcgcgccgcgccggcgcaggcgcagagaggcgcg +ccgcgccggcgcaggcgcagagaggcgcgccgcgccggcgcaggcgcaga +cacatgctagcgcgtcggggtggaggcgtggcgcaggcgcagagaggcgc +gccgcgccggcgcaggcgcagagacacatgctaccgcgtccaggggtgga +ggcgtggcgcaggcgcagagaggcgcaccgcgccggcgcaggcgcagaga +cacatgctagcgcgtccaggggtggaggcgtggcgcaggcgcagagacgc +aagcctacgggcgggggttgggggggcgtgtgttgcaggagcaaagtcgc +acggcgccgggctggggcggggggagggtggcgccgtgcacgcgcagaaa +ctcacgtcacggtggcgcggcgcagagacgggtagaacctcagtaatccg +aaaagccgggatcgaccgccccttgcttgcagccgggcactacaggaccc +gcttgctcacggtgctgtgccagggcgccccctgctggcgactagggcaa +ctgcagggctctcttgcttagagtggtggccagcgccccctgctggcgcc +ggggcactgcagggccctcttgcttactgtatagtggtggcacgccgcct +gctggcagctagggacattgcagggtcctcttgctcaaggtgtagtggca +gcacgcccacctgctggcagctggggacactgccgggccctcttgctCCA +ACAGTACTGGCGGATTATAGGGAAACACCCGGAGCATATGCTGTTTGGTC +TCAGtagactcctaaatatgggattcctgggtttaaaagtaaaaaataaa +tatgtttaatttgtgaactgattaccatcagaattgtactgttctgtatc +ccaccagcaatgtctaggaatgcctgtttctccacaaagtgtttactttt +ggatttttgccagtctaacaggtgaAGccctggagattcttattagtgat +ttgggctggggcctggccatgtgtatttttttaaatttccactgatgatt +ttgctgcatggccggtgttgagaatgactgCGCAAATTTGCCGGATTTCC +TTTGCTGTTCCTGCATGTAGTTTAAACGAGATTGCCAGCACCGGGTATCA +TTCACCATTTTTCTTTTCGTTAACTTGCCGTCAGCCTTTTCTTTGACCTC +TTCTTTCTGTTCATGTGTATTTGCTGTCTCTTAGCCCAGACTTCCCGTGT +CCTTTCCACCGGGCCTTTGAGAGGTCACAGGGTCTTGATGCTGTGGTCTT +CATCTGCAGGTGTCTGACTTCCAGCAACTGCTGGCCTGTGCCAGGGTGCA +AGCTGAGCACTGGAGTGGAGTTTTCCTGTGGAGAGGAGCCATGCCTAGAG +TGGGATGGGCCATTGTTCATCTTCTGGCCCCTGTTGTCTGCATGTAACTT +AATACCACAACCAGGCATAGGGGAAAGATTGGAGGAAAGATGAGTGAGAG +CATCAACTTCTCTCACAACCTAGGCCAGTAAGTAGTGCTTGTGCTCATCT +CCTTGGCTGTGATACGTGGCCGGCCCTCGCTCCAGCAGCTGGACCCCTAC +CTGCCGTCTGCTGCCATCGGAGCCCAAAGCCGGGCTGTGACTGCTCAGAC +CAGCCGGCTGGAGGGAGGGGCTCAGCAGGTCTGGCTTTGGCCCTGGGAGA +GCAGGTGGAAGATCAGGCAGGCCATCGCTGCCACAGAACCCAGTGGATTG +GCCTAGGTGGGATCTCTGAGCTCAACAAGCCCTCTCTGGGTGGTAGGTGC +AGAGACGGGAGGGGCAGAGCCGCAGGCACAGCCAAGAGGGCTGAAGAAAT +GGTAGAACGGAGCAGCTGGTGATGTGTGGGCCCACCGGCCCCAGGCTCCT +GTCTCCCCCCAGGTGTGTGGTGATGCCAGGCATGCCCTTCCCCAGCATCA +GGTCTCCAGAGCTGCAGAAGACGACGGCCGACTTGGATCACACTCTTGTG +AGTGTCCCCAGTGTTGCAGAGGTGAGAGGAGAGTAGACAGTGAGTGGGAG +TGGCGTCGCCCCTAGGGCTCTACGGGGCCGGCGTCTCCTGTCTCCTGGAG +AGGCTTCGATGCCCCTCCACACCCTCTTGATCTTCCCTGTGATGTCATCT +GGAGCCCTGCTGCTTGCGGTGGCCTATAAAGCCTCCTAGTCTGGCTCCAA +GGCCTGGCAGAGTCTTTCCCAGGGAAAGCTACAAGCAGCAAACAGTCTGC +ATGGGTCATCCCCTTCACTCCCAGCTCAGAGCCCAGGCCAGGGGCCCCCA +AGAAAGGCTCTGGTGGAGAACCTGTGCATGAAGGCTGTCAACCAGTCCAT +AGGCAAGCCTGGCTGCCTCCAGCTGGGTCGACAGACAGGGGCTGGAGAAG +GGGAGAAGAGGAAAGTGAGGTTGCCTGCCCTGTCTCCTACCTGAGGCTGA +GGAAGGAGAAGGGGATGCACTGTTGGGGAGGCAGCTGTAACTCAAAGCCT +TAGCCTCTGTTCCCACGAAGGCAGGGCCATCAGGCACCAAAGGGATTCTG +CCAGCATAGTGCTCCTGGACCAGTGATACACCCGGCACCCTGTCCTGGAC +ACGCTGTTGGCCTGGATCTGAGCCCTGGTGGAGGTCAAAGCCACCTTTGG +TTCTGCCATTGCTGCTGTGTGGAAGTTCACTCCTGCCTTTTCCTTTCCCT +AGAGCCTCCACCACCCCGAGATCACATTTCTCACTGCCTTTTGTCTGCCC +AGTTTCACCAGAAGTAGGCCTCTTCCTGACAGGCAGCTGCACCACTGCCT +GGCGCTGTGCCCTTCCTTTGCTCTGCCCGCTGGAGACGGTGTTTGTCATG +GGCCTGGTCTGCAGGGATCCTGCTACAAAGGTGAAACCCAGGAGAGTGTG +GAGTCCAGAGTGTTGCCAGGACCCAGGCACAGGCATTAGTGCCCGTTGGA +GAAAACAGGGGAATCCCGAAGAAATGGTGGGTCCTGGCCATCCGTGAGAT +CTTCCCAGGGCAGCTCCCCTCTGTGGAATCCAATCTGTCTTCCATCCTGC +GTGGCCGAGGGCCAGGCTTCTCACTGGGCCTCTGCAGGAGGCTGCCATTT +GTCCTGCCCACCTTCTTAGAAGCGAGACGGAGCAGACCCATCTGCTACTG +CCCTTTCTATAATAACTAAAGTTAGCTGCCCTGGACTATTCACCCCCTAG +TCTCAATTTAAGAAGATCCCCATGGCCACAGGGCCCCTGCCTGGGGGCTT +GTCACCTCCCCCACCTTCTTCCTGAGTCATTCCTGCAGCCTTGCTCCCTA +ACCTGCCCCACAGCCTTGCCTGGATTTCTATCTCCCTGGCTTGGTGCCAG +TTCCTCCAAGTCGATGGCACCTCCCTCCCTCTCAACCACTTGAGCAAACT +CCAAGACATCTTCTACCCCAACACCAGCAATTGTGCCAAGGGCCATTAGG +CTCTCAGCATGACTATTTTTAGAGACCCCGTGTCTGTCACTGAAACCTTT +TTTGTGGGAGACTATTCCTCCCATCTGCAACAGCTGCCCCTGCTGACTGC +CCTTCTCTCCTCCCTCTCATCCCAGAGAAACAGGTCAGCTGGGAGCTTCT +GCCCCCACTGCCTAGGGACCAACAGGGGCAGGAGGCAGTCACTGACCCCG +AGACGTTTGCATCCTGCACAGCTAGAGATCCTTTATTAAAAGCACACTGT +TGGTTTCTGCTCAGTTCTTTATTGATTGGTGTGCCGTTTTCTCTGGAAGC +CTCTTAAGAACACAGTGGCGCAGGCTGGGTGGAGCCGTCCCCCCATGGAG +CACAGGCAGACAGAAGTCCCCGCCCCAGCTGTGTGGCCTCAAGCCAGCCT +TCCGCTCCTTGAAGCTGGTCTCCACACAGTGCTGGTTCCGTCACCCCCTC +CCAAGGAAGTAGGTCTGAGCAGCTTGTCCTGGCTGTGTCCATGTCAGAGC +AACGGCCCAAGTCTGGGTCTGGGGGGGAAGGTGTCATGGAGCCCCCTACG +ATTCCCAGTCGTCCTCGTCCTCCTCTGCCTGTGGCTGCTGCGGTGGCGGC +AGAGGAGGGATGGAGTCTGACACGCGGGCAAAGGCTCCTCCGGGCCCCTC +ACCAGCCCCAGGTCCTTTCCCAGAGATGCCTGGAGGGAAAAGGCTGAGTG +AGGGTGGTTGGTGGGAAACCCTGGTTCCCCCAGCCCCCGGAGACTTAAAT +ACAGGAAGAAAAAGGCAGGACAGAATTACAAGGTGCTGGCCCAGGGCGGG +CAGCGGCCCTGCCTCCTACCCTTGCGCCTCATGACCAGCTTGTTGAAGAG +ATCCGACATCAAGTGCCCACCTTGGCTCGTGGCTCTCACTGCAACGGGAA +AGCCACAGACTGGGGTGAAGAGTTCAGTCACATGCGACCGGTGACTCCCT +GTCCCCACCCCCATGACACTCCCCAGCCCTCCAAGGCCACTGTGTTTCCC +AGTTAGCTCAGAGCCTCAGTCGATCCCTGACCCAGCACCGGGCACTGATG +AGACAGCGGCTGTTTGAGGAGCCACCTCCCAGCCACCTCGGGGCCAGGGC +CAGGGTGTGCAGCAccactgtacaatggggaaactggcccagagaggtga +ggcagcttgcctggggtcacagagcaaggcaaaagcagcgctgggtacaa +gctcaAAACCATAGTGCCCAGGGCACTGCCGCTGCAGGCGCAGGCATCGC +ATCACACCAGTGTCTGCGTTCACAGCAGGCATCATCAGTAGCCTCCAGAG +GCCTCAGGTCCAGTCTCTAAAAATATCTCAGGAGGCTGCAGTGGCTGACC +ATTGCCTTGGACCGCTCTTGGCAGTCGAAGAAGATTCTCCTGTCAGTTTG +AGCTGGGTGAGCTTAGAGAGGAAAGCTCCACTATGGCTCCCAAACCAGGA +AGGAGCCATAGCCCAGGCAGGAGGGCTGAGGACCTCTGGTGGCGGCCCAG +GGCTTCCAGCATGTGCCCTAGGGGAAGCAGGGGCCAGCTGGCAAGAGCAG +GGGGTGGGCAGAAAGCACCCGGTGGACTCAGGGCTGGAGGGGAGGAGGCG +ATCTTGCCCAAGGCCCTCCGACTGCAAGCTCCAGGGCCCGCTCACCTtgc +tcctgctccttctgctgctgcttctccagctttcgctccttcatgctgcG +CAGCTTGGCCTTGCCGATGCCCCCAGCTTGGCGGATGGACTCTAGCAGAG +TGGCCAGCCACCGGAGGGGTCAACCACTTCCCTGGGAGCTCCCTGGACTG +GAGCCGGGAGGTGGGGAACAGGGCAAGGAGGAAAGGCTGCTCAGGCAGGG +CTGGGGAAGCTTACTGTGTCCAAGAGCCTGCTGGGAGGGAAGTCACCTCC +CCTCAAACGAGGAGCCCTGCGCTGGGGAGGCCGGACCTTTGGAGACTGTG +TGTGGGGGCCTGGGCACTGACTTCTGCAACCACCTGAGCGCGGGCATCCT +GTGTGCAGATACTCCCTGCTTCCTCTCTAGCCCCCACCCTGCAGAGCTGG +ACCCCTGAGCTAGCCATGCTCTGACAGTCTCAGTTGCACACACGAGCCAG +CAGAGGGGTTTTGTGCCACTTCTGGATGCTAGGGTTACACTGGGAGACAC +AGCAGTGAAGCTGAAATGAAAAATGTGTTGCTGTAGTTTGTTATTAGACC +CCTTCTTTCCATTGGTTTAATTAGGAATGGGGAACCCAGAGCCTCACTTG +TTCAGGCTCCCTCTGCCCTAGAAGTGAGAAGTCCAGAGCTCTACAGTTTG +AAAACCACTATTTTATGAACCAAGTAGAACAAGATATTTGAAATGGAAAC +TATTCAAAAAATTGAGAATTTCTGACCACTTAACAAACCCACAGAAAATC +CACCCGAGTGCACTGAGCACGCCAGAAATCAGGTGGCCTCAAAGAGCTGC +TCCCACCTGAAGGAGACGCGCTGCTGCTGCTGTCGTCCTGCCTGGCGCCT +TGGCCTACAGGGGCCGCGGTTGAGGGTGGGAGTGGGGGTGCACTGGCCAG +CACCTCAGGAGCtgggggtggtggtgggggcggtgggggtggtgTTAGTA +CCCCATCTTGTAGGTCTGAAACACAAAGTGTGGGGTGTCTAGGGAAGAAG +GTGTGTGACCAGGGAGGTCCCCGGCCCAGCTCCCATCCCAGAACCCAGCT +CACCTACCTTGAGAGGCTCGGCTACCTCAGTGTGGAAGGTGGGCAGTTCT +GGAATGGTGCCAGGGGCAGAGGGGGCAATGCCGGGGCCCAGGTCGGCAAT +GTACATGAGGTCGTTGGCAATGCCGGGCAGGTCAGGCAGGTAGGATGGAA +CATCAATCTCAGGCACCTGGCCCAGGTCTGGCACATAGAAGTAGTTCTCT +GGGACCTGCAAGATTAGGCAGGGACATGTGAGAGGTGACAGGGACCTGCA +GGGGCAGCCAACAAGACCTTGTGTGCACCTCCCATGGGTGGAATAAGGGG +CCCAACAGCCTTGACTGGAGAGGAGCTCTGGCAAGGCCCTGGGCCACTGC +ACCTGTCTCCACCTCTGTCCCACCCCTCCCACCTGCTGTTCCAGCTGCTC +TCTCTTGCTGATGGACAAGGGGGCATCAAACAGCTTCTCCTCTGTCTCTG +CCCCCAGCATCACATGGGTCTTTGTTACAGCACCAGCCAGGGGGTCCAGG +AAGACATACTTCTTCTACCTACAGAGGCGACATGGGGGTCAGGCAAGCTG +ACACCCGCTGTCCTGAGCCCATGTTCCTCTCCCACATCATCAGGGGCACA +GCGTGCACTGTGGGGTCCCAGGCCTCCCGAGCCGAGCCACCCGTCACCCC +CTGGCTCCTGGCCTATGTGCTGTACCTGTGTCTGATGCCCTGGGTCCCCA +CTAAGCCAGGCCGGGCCTCCCGCCCACACCCCTCGGCCCTGCCCTCTGGC +CATACAGGTTCTCGGTGGTGTTGAAGAGCAGCAAGGAGCTGACAGAGCTG +ATGTTGCTGGGAAGACCCCCAAGTCCCTCTTCTGCATCGTCCTCGGGCTC +CGGCTTGGTGCTCACGCACACAGGAAAGTCCTTCAGCTTCTCCTGAGAGG +GCCAGGATGGCCAAGGGATGGTGAATATTTGGTGCTGGGCCTAATCAGCT +GCCATCCCATCCCAGTCAGCCTCCTCTGGGGGACAGAACCCTATGGTGGC +CCCGGCTCCTCCCCAGTATCCAGTCCTCCTGGTGTGTGACAGGCTATATG +CGCGGCCAGCAGACCTGCAGGGCCCGCTCGTCCAGGGGGCGGTGCTTGCT +CTGGATCCTGTGGCGGGGGCGTCTCTGCAGGCCAGGGTCCTGGGCGCCCG +TGAAGATGGAGCCATATTCCTGCAGGCGCCCTGGAGCAGGGTACTTGGCA +CTGGAGAACACCTGTGGACACAGGGACAAGTCTGAGGGGGCCCCAAGAGG +CTCAGAGGGCTAGGATTGCTTGGCAGGAGAGGGTGGAGTTGGAAGCCTGG +GCGAGAAGAAAGCTCAAGGTACAGGTGGGCAGCAGGGCAGAGACTGGGCA +GCCTCAGAGGCACGGGGAAATGGAGGGACTGCCCAGTAGCCTCAGGACAC +AGGGGTATGGGGACTACCTTGATGGCCTTCTTGCTGCCCTTGATCTTCTC +AATCTTGGCCTGGGCCAAGGAGACCTTCTCTCCAATGGCCTGCACCTGGC +TCCGGCTCTGCTCTACCTGCTGGGAGATCCTGCCATGGAGAAGATCACAG +AGGCTGGGCTGCTCCCCACCCTCTGCACACCTCCTGCTTCTAACAGCAGA +GCTGCCAGGCCAGGCCCTCAGGCAAGGGCTCTGAAGTCAGGGTCACCTAC +TTGCCAGGGCCGATCTTGGTGCCATCCAGGGGGCCTCTACAAGGATAATC +TGACCTGCAGGGTCGAGGAGTTGACGGTGCTGAGTTCCCTGCACTCTCAG +TAGGGACAGGCCCTATGCTGCCACCTGTACATGCTATCTGAAGGACAGCC +TCCAGGGCACACAGAGGATGGTATTTACACATGCACACATGGCTACTGAT +GGGGCAAGCACTTCACAACCCCTCATGATCACGTGCAGCAGACAATGTGG +CCTCTGCAGAGGGGGAACGGAGACCGGAGGCTGAGACTGGCAAGGCTGGA +CCTGAGTGTCGTCACCTAAATTCAGACGGGGAACTGCCCCTGCACATACT +GAACGGCTCACTGAGCAAACCCCGAGTCCCGACCACCGCCTCAGTGTGGT +CTAGCTcctcacctgcttccatcctccctggtgcggggtgggcccagtga +tatcagctgcctgctgttccccagatgtgccaagtgcattcttgtgtgct +tgcatctcatggaacgccatttccccagacatccctgtggctggctccTG +ATGCCCGAGGCCCAAGTGTCTGATGCTTTAAGGCACATCACCCCACTCAT +GCTTTTCCATGTTCTTTGGCCGCAGCAAGGCCGCTCTCACTGCAAAGTTA +ACTCTGATGCGTGTGTAACACAACATCCTCCTCCCAGTCGCCCCTGTAGC +TCCCCTACCTCCAAGAGCCCAGCCCTTGCCCACAGGGCCACACTCCACGT +GCAGAGCAGCCTCAGCACTCACCGGGCACGAGCGAGCCTGTGTGGTGCGC +AGGGATGAGAAGGCAGAGGCGCGACTGGGGTTCATGAGGAAGGGCAGGAG +GAGGGTGTGGGATGGTGGAGGGGTTTGAGAAGGCAGAGGCGCGACTGGGG +TTCATGAGGAAAGGGAGGGGGAGGATGTGGGATGGTGGAGGGGCTGCAGA +CTCTGGGCTAGGGAAAGCTGGGATGTCTCTAAAGGTTGGAATGAATGGCC +TAGAATCCGACCCAATAAGCCAAAGCCACTTCCACCAACGTTAGAAGGCC +TTGGCCCCCAGAGAGCCAATTTCACAATCCAGAAGTCCCCGTGCCCTAAA +GGGTCTGCCCTGATTACTCCTGGCTCCTTGTGTGCAGGGGGCTCAGGCAT +GGCAGGGCTGGGAGTACCAGCAGGCACTCAAGCGGCTTAAGTGTTCCATG +ACAGACTGGTATGAAGGTGGCCACAATTCAGAAAGAAAAAAGAAGAGCAC +CATCTCCTTCCAGTGAGGAAGCGGGACCACCACCCAGCGTGTGCTCCATC +TTTTCTGGCTGGGGAGAGGCCTTCATCTGCTGTAAAGGGTCCTCCAGCAC +AAGCTGTCTTAATTGACCCTAGTTCCCAGGGCAGCCTCGTTCTGCCTTGG +GTGCTGACACGACCTTCGGTAGGTGCATAAGCTCTGCATTCGAGGTCCAC +AGGGGCAGTGGGAGGGAACTGagactggggagggacaaaggctgctctgt +cctggtgctcccacaaaggagaagggctgatcactcaaagttgcgaacac +caagctcaacaatgagccctggaaaatttctggaatggattattaaacag +agagtctgtaagcacttagaaaaggccgcggtgagtcccaggggccagca +ctgctcgaaatgtacagcatttctctttgtaacaggattattagcctgct +gtgcccggggaaaacatgcagcacagtgcatctcgagtcagcaggatttt +gacggcttctaacaaaatcttgtagacaagatggagctatgggggttgga +ggagagaacatataggaaaaatcagagccaaatgaaccacagccccaaag +ggcacagttgaacaatggactgattccagccttgcacggagggatctggc +agagtCCATCCAGTTCATTCAACACCTGGTTAGAAAACTGGGGCCAGCAC +ACAGGGGAAGGGTAAGCTGGTTTCATGATCGAATCAAGGCTCAGACAATT +TTTAAAGGCCAGAGGGTAGACTGCAATCACcaagatgaaatttacaagga +acaaatgtgaagcccaacatttaggttttaaaaatcaagcgtataaatac +agaaggtggagggaacttgctttagacacagttcaggtgaagaaagacct +ggaaacttctgttaactataagctcagtaGGGGCTAAAAGCATGTTAATC +GGCATAAAAAGGCAATGAGATCTTAGGGCACACAGCTCCCCGCCCCTCTT +CTGCCCTTCATCCTTCTTTCAATCAGCAGGGACCGTGCACTCTCTTGGAG +CCACCACAGAAAACAGAGGTGCATCCAGCACCACAGAAAACAGAGCCACC +ACAGAAAACAGAGGGTGACTGTCATCCCCTCCAGTCTCTGCACACTCCCA +GCTGCAGCAGAGCAGGAGGAGAGAGCACAGCCTGCAATGCTAATTTGCCA +GGAGCTCACCTGCCTGCGTCACTGGGCACAGACGCCAGTGAGGCCAGAGG +CCGGGCTGTGCTGGGGCCTGAGCCGGGTGGTGGGGAGAGAGTCTCTCCCC +TGCCCCTGTCTCTTCCGTGCAGGAGGAGCATGTTTAAGGGGACGGGTTCA +AAGCTGGTCACATCCCCACCGAAAAAGCCCATGGACAACGAAAAGCCCAC +TAGCTTGTCCAGTGCCACAGGAGGGGCAAGTGGAGGAGGAGAGGTGGCGG +TGCTCCCCACTCCACTGCCAGTCGTCACTGGCTCTCCCTTCCCTTCATCC +TCGTTCCCTATCTGTCACCATTTCCTGTCGTCGTTTCCTCTGAATGTCTC +ACCCTGCCCTCCCTGCTTGCAAGTCCCCTGTCTGTAGCCTCACCCCTGTC +GTATCCTGACTACAATAACAGCTTCTGGGTGTCCCTGGCATCCACTCTCT +CTCCCTTCTTGTCCCTTCCGTGACGGATGCCTGAGGAACCTTCCCCAAAC +TCTTCTGTCCCATCCCTGCCCTGCTCAAAATCCAATCACAGCTCCCTAAC +ACGCCTGAATCAACTTGAAGTCCTGTCTTGAGTAATCCGTGGGCCCTAAC +TCACTCATCCCAACTCTTCACTCACTGCCCTGCCCCACACCCTGCCAGGG +AGCCTCCCGTGGCACCGTGGGGACACAAAGGAACCAGGGCAAAGCTCCCT +CAGCCCCATTCAAAGAGGCCTGGCCCACAGGCTCACGGAAAGTCAGCCTC +TCATGCCCCGAGAGCTGAGTGCAAGGGAGAGGCAGCGCTGTCTGTGCTTC +CCATGCAGAAGCACCCCCCTCCCACCCCTGTGCAGGCCGGCCTTCGCGGC +AGACCACCATACACCACGTTCCAAGCCACACTGAGGCCTCCCTCCAAGCC +TGCAGCCCCCATTTCCAGACCCTGCCAGGGCAACCTGCATATCCACCTCC +CTACCCTGCCCCCCTCTTCCAGGAGTCTGCCCTATGTGGAGTAAGCACgt +ggttttcctcttcagcaactatttcctttttactcaagcaatggccccat +ttcccttggggaatccatctctctcgcaggcttagtcccagagcttcagg +tggggctgcccacagagctcctcagTCTAAGCCAAGTGGTGTGTCATAGT +CCCCTGGCCCCATTAATGGATTCTGGGATAGACATGAGGACCAAGCCAGG +TGGGATGAGTGAGTGTGGCTTCTGGAGGAAGTGGGGACACAGGACAGCAT +TCTTTCCTGCTGGACCTGACCCTGTGTCATGTCACCTTGCTACCACGAGA +GCATGGCCTGTCTGGGAATGCAGCCAGACCCAAAGAAGCAAACTGACATG +GAAGGAAAGCAAAACCAGGCCCTGAGGACATCATTTTAGCCCTTACTCCG +AAGGCTGCTCTACTGATTGGTTAATTTTTGCTTAGCTTGGTCTGGGGAGT +TCTGACAGGCGTGCCACCAATTCTTACCGATTTCTCTCCACTCTAGACCC +TGAGAAGCCCACGCGGTTCATGCTAGCAATTAACAATCAATCTCGCCCTA +TGTGTTCCCATTCCAGCCTCTAGGACACAGTGGCAGCCACATAATTGGTA +TCTCTTAAGGTCCAGCACGAGGTGGAGCACATGGTGGAGAGACAGATGCA +GTGACCTGGAACCCAGGAGTGAGGGAGCCAGGACTCAGGCCCAAGGCTCC +TGAGAGGCATCTGGCCCTCCCTGCGCTGTGCCAGCAGCTTGGAGAACCCA +CACTCAATGAACGCAGCACTCCACTACCCAGGAAATGCCTTCCTGCCCTC +TCCTCATCCCATCCCTGGGCAGGGGACATGCAACTGTCTACAAGGTGCCA +AGTACCAGGACAGGAAAGGAAAGACGCCAAAAATCCAGCGCTGCCCTCAG +AGAAGGGCAACCACGCAGTCCCCATCTTGGCAAGGAAACACAATTTCCGA +GGGAATGGTTTTGGCCTCCATTCTAAGTGCTGGACATGGGGTGGCCATAA +TCTGGAGCTGATGGCTCTTAAAGACCTGCATCCTCTTCCCTAGGTGTCCC +TCGGGCACATTTAGCACAAAGATAAGCACAAAAGGTGCATCCAGCACTTT +GTTACTATTGGTGGCAGGTTTATGAATGGCAACCAAAGGCAGTGTACGGG +TCAAGATTATCAACAGGGAagagatagcatttcctgaaggcttcctaggt +gccaggcactgttccattcctttgcatgttttgattaatttaatatttaa +aataattctaccaggaagctaccattattaccacaacttcacaaatgaga +acaccgaggcttagaggggttgggttgcccaaggttacagaggaagaaaa +caggggagctggatctgagccaaggcatcaactccaaggtaacccctcag +tcacttcactgtgtgtcccctGGTTACTGGGACATTCTTGACAAACTCGG +GGCAAGCCGGTGAGTCAGTGGGGGAGGACTTTCAGGAAGAGGTGGGTTCC +CAGTTGGTGACAGAAGAGGAGGCTGCAAAGTGAAGGAGCAGGGGCTCCAG +GTCTGGCGACAACCAGGGAAGGGACAGGGCAGGGATGGCTTGGACCACGA +GAGGCACCTGAGTCAGGCAGTCACATACTTCCCACTGGGGTCTACCATGT +GAGGCATGGTGTGGGATCCTGGGAAGGAGACCAAGCCTCATTTCAGTTTG +CTTATGGCCAAAGACAGGACCTGTGTACCCGACAACCCCTGGGACCTTTA +CCAAAAAAAGAGCAAACACCATTCACTCACTCATGTTAGATAAACACTGA +GTGAAGTCACTGGAGCCCAAGGACTGTGCGAGGTCAGCACTGCCAATACA +AGAagctgcagccctccagctcgcctccctcaatggccactccgtgctcc +agccatgctggcttccttttaggtcctccacctccaggctgtagttcatg +tgcttctttctggaatgttcttcccaacctacccactcaaccctcagact +ttaccataaatgtcatttcctcacgtctgccttccctgacctgagaccaa +gccaggcttcccatgacgagcctcacagtaccccatctCCCCTGAACAGA +TGCAGTAATAACCTACATAACCCGGGGCCATGATCTAtggctttgaatcc +tggctctgtcactaggccaggtctctcagcccttctgtgcctcagtttcc +tcatctataaaatgagatgacggcagtgcctgctcatgaagtgtgagtta +atgcactcaaatcaatggttgtgcacggtttatatgaatattagtgatta +CAAAATATTATCAATAGACCTTGTCACAACTGTTATTGAAGAACtaatca +tctattgcttatttaggtctttctctcctgccagaatgtgcgctccaggt +ggagaggtatgttgccttatccgtggctggatatatagagattcccacac +tgccttgcacacgagcactgctgggtaaatatttgttggctgcaggaaAA +CGTGAAGGAATAGGCCCTCCAATGGGAGGAAAAGCATGAGTTGTGAGAGC +AGAGCCACCACAGGAAACCAGGAGGCTAAGTGGGGTGGAAGGGAGTGAGC +TCTCGGACTCCCAGGAGTAAAAGCTTCCAAGTTGGGCTCTCACTTCAGCC +CCTCCCACACAGGGAAGCCAGATGGGTTCCCCAGGACCGGGATTCCCCAA +GGGGGCTGCTCCCAGAGGGTGTGTTGCTGGGATTGCCCAGGACAGGGATG +GCCCTCTCATCAGGTGGGGGTGAGTGGCAGCACCCACCTGCTGAAGATGT +CTCCAGAGACCTTCTGCAGGTACTGCAGGGCATCCGCCATCTGCTGGACG +GCCTCCTCTCGCCGCAGGTCTGGCTGGATGAAGGGCACGGCATAGGTCTG +ACCTGCCAGGGAGTGCTGCATCCTCACAGGAGTCATGGTGCCTGTGGGTC +GGAGCCGGAGCGTCAGAGCCACCCACGACCACCGGCACGCCCCCACCACA diff --git a/poetry.lock b/poetry.lock index bc9fcfbd..0600903b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3135,18 +3135,18 @@ files = [ [[package]] name = "traitlets" -version = "5.11.2" +version = "5.12.0" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"}, - {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"}, + {file = "traitlets-5.12.0-py3-none-any.whl", hash = "sha256:81539f07f7aebcde2e4b5ab76727f53eabf18ad155c6ed7979a681411602fa47"}, + {file = "traitlets-5.12.0.tar.gz", hash = "sha256:833273bf645d8ce31dcb613c56999e2e055b1ffe6d09168a164bcd91c36d5d35"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "typer" diff --git a/pyproject.toml b/pyproject.toml index 70e85ac5..ee3f38f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,6 +169,7 @@ ignore = [ 'W191', ] exclude = [ + "docs/tutorial_data/*", "src/pxblat/extc/__init__.pyi", "src/pxblat/__init__.py", "tasks.py", From df3b7a0628b79eecc688330bb335270e81e16795 Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Wed, 25 Oct 2023 10:40:50 -0500 Subject: [PATCH 3/5] docs: update tutorial and conf.py --- docs/conf.py | 1 + docs/tutorial.md | 53 +++++++++++++++++------------ docs/tutorial_data/query_context.py | 18 +++++++--- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d16a780e..6af9b600 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -82,6 +82,7 @@ # so a file named 'default.css' will overwrite the builtin 'default.css'. html_static_path = ["_static"] + myst_heading_anchors = 3 myst_enable_extensions = [ "dollarmath", diff --git a/docs/tutorial.md b/docs/tutorial.md index 2ff4f2c5..2b4ff51b 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -4,7 +4,7 @@ Make sure you have installed PxBLAT, otherwise please go-to ({doc}`installation`). ``` -```{tip} +```{important} We do not assume you already know common formats and BLAT, which is a standout within the bioinformatics landscape and is recognized for its capability to conduct genome sequence alignments. BLAT can help us know where one or several sequences can be mapped to the reference for nucleotide or peptide sequences. Assume we have multiple sequences, and want to know where these sequences can be mapped in reference sequence. @@ -60,12 +60,17 @@ mkdir tutorial cd tutorial ``` -- Download reference data `test_ref.fa`, which is fasta format. +- Download reference data {download}`⬇️ test_ref.fa `, which is fasta format. + +````{example} Download via wget +:collapsible: close ```bash wget https://raw.githubusercontent.com/ylab-hi/pxblat/main/tests/data/test_ref.fa ``` +```` + Let's check the reference data ```console @@ -85,11 +90,15 @@ $ wc -l test_ref.fa 301 test_ref.fa ``` -- Download test sequences `test_case1.fa`, which is fasta format. +- Download test sequences {download}`⬇️ test_case1.fa `, which is fasta format. + +````{example} Download via wget +:collapsible: close ```bash wget https://raw.githubusercontent.com/ylab-hi/pxblat/main/tests/data/test_case1.fa ``` +```` Let's check test reference @@ -121,6 +130,7 @@ Click the blinking circle cross, and you will be blessed and get more informatio ```{eval-rst} .. code-block:: python + :name: fa_to_two_bit_block :linenos: from pxblat import fa_to_two_bit @@ -139,7 +149,7 @@ Click the blinking circle cross, and you will be blessed and get more informatio #. Output file path ``` -Let's create a Python file named `2bit.py`, and copy and past code above to `2bit.py`. +Let's create a Python file named `2bit.py`, and copy and paste [code above](#fa_to_two_bit_block) to `2bit.py`. Then, execute the `2bit.py` ```bash @@ -180,7 +190,7 @@ Moreover, **PxBLAT** provides flexible options to allow conducting the conversio **PxBLAT** contains {class}`pxblat.Server` and {class}`pxblat.Client`. We use them to align our sequences in two steps. -1. start {class}`pxblat.Server` +1. Start {class}`pxblat.Server` 2. {class}`pxblat.Client` send our sequence to {class}`pxblat.Server` for alignment @@ -219,10 +229,11 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready server.wait_ready() # (7)! result1 = client.query("ATCG") # (8)! result2 = client.query("AtcG") # (9)! - result3 = client.query(["ATCG", "ATCG"]) # (10)! - result4 = client.query(["test_case1.fa"]) # (11)! - result5 = client.query(["cgTA", "test_case1.fa"]) # (12)! - print(result4[0]) + result3 = client.query("test_case1.fa") # (10)! + result4 = client.query(["ATCG", "ATCG"]) # (11)! + result5 = client.query(["test_case1.fa"]) # (12)! + result6 = client.query(["cgTA", "test_case1.fa"]) # (13)! + print(result3[0]) if __name__ == "__main__": @@ -236,25 +247,25 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready #. :attr:`.Client.min_score` is the minimum score for the alignment. #. :attr:`.Client.min_identity` is the minimum identity for the alignment. #. block current thread to wait server to be ready - #. :meth:`.Client.query` accepts a :class:`str` consisting of DNA or Protein Sequences, e.g. `"ATCG"` - #. :meth:`.Client.query` accepts a path of Fasta file, e.g. `"./test_case1.fa"` - #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` consisting of DNA or Protein Sequences, e.g. `["ATCG","CTGAG"]` - #. :meth:`.Client.query` accepts a :class:`list` of path of Fasta files, e.g. `["data/fasta1.fa", "data/fasta2.fa"]` - #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` and path, e.g. `["ATCG", "data/fasta1.fa"]` + #. :meth:`.Client.query` accepts a :class:`str` consisting of nucleotide or peptide sequences, e.g. `"ATCG"` + #. :meth:`.Client.query` accepts nucleotide or peptide sequences that are case-insensitive, e.g. `"AtcG"` + #. :meth:`.Client.query` accepts a path of fasta file, e.g. `"./test_case1.fa"` + #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` consisting of nucleotide or peptide sequences, e.g. `["ATCG","CTGAG"]` + #. :meth:`.Client.query` accepts a :class:`list` of path of fasta files, e.g. `["test_case1.fa"]` + #. :meth:`.Client.query` accepts a :class:`list` of :class:`str` and path, e.g. `["ATCG", "test_case1.fa"]` ``` {meth}`.Client.query` accepts parameters of several types: -1. Path of fasta file e.g. `data/fasta1.fa` -2. {class}`list` of {class}`str` consisting of DNA or Protein Sequences, e.g. `["ATCG","CTGAG"]` -3. {class}`list` of path of fasta files, e.g. `["data/fasta1.fa", "data/fasta2.fa"]` -4. {class}`list` of `str` and path, e.g. `["ATCG", "data/fasta1.fa"]` -5. {meth}`.Client.query` accepts a {class}`list` of {class}`str` and path, e.g. `["ATCG", "data/fasta1.fa"]` +- Path of fasta file e.g. `./test_case1.fa` +- {class}`str` consisting of nucleotide or peptide sequences that are case-insensitive, e.g. `ATCG`, or `ATcg` +- {class}`list` of {class}`str` consisting of nucleotide or peptide sequences that are case-insensitive, e.g. `["AtcG","CTGAG"]` +- {class}`list` of path of fasta files, e.g. `["data/fasta1.fa", "./test_case1.fa"]` +- {class}`list` of `str` and path, e.g. `["ATCG", "data/fasta1.fa"]` {meth}`.Client.query` return [`QueryResult`](#query-result). -Let's Create a new Python script named `query_context.py`, and copy above to the -script. +Let's Create a new Python script named `query_context.py`, and copy above to the script. Then execute the Python script. ```bash diff --git a/docs/tutorial_data/query_context.py b/docs/tutorial_data/query_context.py index 71556cad..c0d7216e 100644 --- a/docs/tutorial_data/query_context.py +++ b/docs/tutorial_data/query_context.py @@ -19,10 +19,20 @@ def query_context(): server.wait_ready() result1 = client.query("ATCG") result2 = client.query("AtcG") - result3 = client.query(["ATCG", "ATCG"]) - result4 = client.query(["test_case1.fa"]) - result5 = client.query(["cgTA", "test_case1.fa"]) - print(result4[0]) + result3 = client.query("test_case1.fa") + result4 = client.query(["ATCG", "ATCG"]) + result5 = client.query(["test_case1.fa"]) + result6 = client.query(["cgTA", "test_case1.fa"]) + # print results + print(f"{result1=}") + print(f"{result2=}") + print(f"{result3=}") + print(f"{result3[0]=}") + print(f"{result3[0]=!s}") + print(f"{result4=}") + print(f"{result4[0]=}") + print(f"{result5=}") + print(f"{result6=}") if __name__ == "__main__": query_context() From 5f578acd884f48c26c20497925f57ee92e1dfc92 Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Wed, 25 Oct 2023 13:33:03 -0500 Subject: [PATCH 4/5] docs: add code example for turorial --- .pre-commit-config.yaml | 1 + docs/_templates/base.html | 1 - docs/tutorial.md | 453 +++++++++++++++------------- docs/tutorial_data/2bit.py | 1 + docs/tutorial_data/query_context.py | 2 + docs/tutorial_data/query_general.py | 32 ++ docs/tutorial_data/query_result.py | 72 +++++ pyproject.toml | 5 +- 8 files changed, 355 insertions(+), 212 deletions(-) create mode 100644 docs/tutorial_data/query_general.py create mode 100644 docs/tutorial_data/query_result.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6cb3d906..7e35eefd 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,6 +30,7 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs + exclude: docs/tutorial.md - repo: https://github.com/crate-ci/typos rev: typos-dict-v0.11.2 diff --git a/docs/_templates/base.html b/docs/_templates/base.html index 5884beaf..8a40e363 100644 --- a/docs/_templates/base.html +++ b/docs/_templates/base.html @@ -1,6 +1,5 @@ {% extends "!base.html" %} {% block announce %}

- Now Please Cite Me v0.3.10

diff --git a/docs/tutorial.md b/docs/tutorial.md index 2b4ff51b..bbcb0e3b 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -144,6 +144,8 @@ Click the blinking circle cross, and you will be blessed and get more informatio useLong=False, ) + print("Done") + .. code-annotations:: #. Same as `BLAT`, :func:`.fa_to_two_bit` can accept multilple inputs #. Output file path @@ -205,6 +207,7 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready ```{eval-rst} .. code-block:: python + :name: query_context_block :linenos: from pxblat import Client, Server @@ -233,7 +236,7 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready result4 = client.query(["ATCG", "ATCG"]) # (11)! result5 = client.query(["test_case1.fa"]) # (12)! result6 = client.query(["cgTA", "test_case1.fa"]) # (13)! - print(result3[0]) + print(result3[0]) # print result if __name__ == "__main__": @@ -243,7 +246,7 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready #. :attr:`.Client.host` is the hostname or IP address of the current running :class:`.Server`. #. :attr:`.Client.post` is the port number of the current running :class:`.Server`. #. :attr:`.Client.seq_dir` is the directory including `test_ref.fa` and `test_ref.2bit` - #. `two_bit` is the 2bit file [we already create](#3-convert-fasta-to-2bit) + #. `two_bit` is the 2bit file that :ref:`we already create ` #. :attr:`.Client.min_score` is the minimum score for the alignment. #. :attr:`.Client.min_identity` is the minimum identity for the alignment. #. block current thread to wait server to be ready @@ -263,9 +266,7 @@ Hence, in real life we need to make sure the {class}`pxblat.Server` is in `ready - {class}`list` of path of fasta files, e.g. `["data/fasta1.fa", "./test_case1.fa"]` - {class}`list` of `str` and path, e.g. `["ATCG", "data/fasta1.fa"]` -{meth}`.Client.query` return [`QueryResult`](#query-result). - -Let's Create a new Python script named `query_context.py`, and copy above to the script. +Let's Create a new Python script named `query_context.py`, and copy and paste [code above](#query_context_block) to the script. Then execute the Python script. ```bash @@ -280,247 +281,279 @@ Program: blat (v.37x1) 0 1 chr1 ``` +{meth}`.Client.query` return [`QueryResult`](#query-result), which is introduced later. + ### 4.2 Start {class}`pxblat.Server` in general mode ```{eval-rst} .. code-block:: python + :name: query_general_block :linenos: - from pxblat import Server, Client + from pxblat import Client, Server - client = Client( - host="localhost", - port=port, - seq_dir=two_bit, - min_score=20, - min_identity=90, - wait_ready=True, # (1)! - ) + def query_general(): + host = "localhost" + port = 65000 + seq_dir = "." + two_bit = "./test_ref.2bit" + + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, + min_identity=90, + ) + + server = Server(host, port, two_bit, can_stop=True, step_size=5) + server.start() # (1)! + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() # (2)! + result1 = client.query(["actg", "test_case1.fa"]) + # another_work() assume the func is your own function that takes time + result2 = client.query("test_case1.fa") + server.stop() # (3)! - server_option = Server.create_option().withCanStop(True).withStepSize(5).build() - server = Server("localhost", port, two_bit, server_option) - server.start() - work() # (2)! - # server.wait_ready() - # (3)! - result1 = client.query(["actg", "fasta.fa"]) - other_work() - result2 = client.query("fasta.fa") - server.stop() # (4)! + print(f"{result1=}") + print(f"{result2=}") + + + if __name__ == "__main__": + query_general() .. code-annotations:: - #. The parameter `wait_ready` is used to control if the client need to check and wait current server to be ready or query directly. - #. May a task consuming long time - #. No need to wait current running server to be ready, and the job will be done by :class:`.Client` - #. Stop the current running server + #. start server + #. block until the server is ready + #. stop the current running server ``` -Although {class}`.Server` and {class}`.Client` already consider most contexts, `PxBLAT` provides {class}`.ClientThread` that can launch a thread to +```{note} +the explanation of parameters including `two_bit` and `seq_dir` etc. is same as +[previous code](#query_context_block) +``` + +Let's Create a new Python script named `query_general.py`, and copy and paste [code above](#query_general_block) to the script. +Then execute the Python script. + +```bash +$ python query_general.py +result1=[None, QueryResult(id='case1', 1 hits)] +result2=[QueryResult(id='case1', 1 hits)] +``` + +```{note} +`None` means the sequence cannot be mapped to the reference. +``` + +Although {class}`.Server` and {class}`.Client` already consider most contexts, **PxBLAT** provides {class}`.ClientThread` that can launch a thread to query sequence. -However, {class}`.ClientThread` only query one sequence at one time. -Its APIs are still not stable so far. Free feel to check that if you have interests. -## Query Result +## 5. Query Result + +Right now we know how to query certain sequence to the reference, and let's dive into the query result and manipulate that together. -`PxBLAT` aims to introduce as few concepts as possible so that users do not need to take time to learn. -The query result is the same as `QueryResult` of [Bio][Bio]. -Hence, we can manipulate the query result as shown below. +Here we use contexts mode to align sequence, and modify a little bit based on [previous code](#query_context_block) + +````{example} query_context (hint: convenient to copy) +:collapsible: close + +```python +from pxblat import Client, Server + +def query_context(): + host = "localhost" + port = 65000 + seq_dir = "." + two_bit = "./test_ref.2bit" + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, + min_identity=90, + ) + with Server(host, port, two_bit, can_stop=True, step_size=5) as server: + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() + result1 = client.query("ATCG") + result2 = client.query("AtcG") + result3 = client.query("test_case1.fa") + result4 = client.query(["ATCG", "ATCG"]) + result5 = client.query(["test_case1.fa"]) + result6 = client.query(["cgTA", "test_case1.fa"]) + return [result1, result2, result3, result4, result5, result6] +``` +```` ```{eval-rst} -.. py:class:: QueryResult - - Class representing search results from a single query. - - QueryResult is the container object that stores all search hits from a - single search query. It is the top-level object returned by SearchIO's two - main functions, ``read`` and ``parse``. Depending on the search results and - search output format, a QueryResult object will contain zero or more Hit - objects (see Hit). - - You can take a quick look at a QueryResult's contents and attributes by - invoking ``print`` on it:: - - >>> from Bio import SearchIO - >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) - >>> print(qresult) - Program: blastn (2.2.27+) - Query: 33211 (61) - mir_1 - Target: refseq_rna - Hits: ---- ----- ---------------------------------------------------------- - # # HSP ID + description - ---- ----- ---------------------------------------------------------- - 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... - 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... - 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... - 3 2 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... - 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... - 5 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... - 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... - 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... - 8 1 gi|262205451|ref|NR_030222.1| Homo sapiens microRNA 51... - 9 2 gi|301171447|ref|NR_035871.1| Pan troglodytes microRNA... - 10 1 gi|301171276|ref|NR_035852.1| Pan troglodytes microRNA... - 11 1 gi|262205290|ref|NR_030188.1| Homo sapiens microRNA 51... - ... - - If you just want to know how many hits a QueryResult has, you can invoke - ``len`` on it. Alternatively, you can simply type its name in the interpreter:: - - >>> len(qresult) - 100 - >>> qresult - QueryResult(id='33211', 100 hits) - - QueryResult behaves like a hybrid of Python's built-in list and dictionary. - You can retrieve its items (Hit objects) using the integer index of the - item, just like regular Python lists:: - - >>> first_hit = qresult[0] - >>> first_hit - Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) - - You can slice QueryResult objects as well. Slicing will return a new - QueryResult object containing only the sliced hits:: - - >>> sliced_qresult = qresult[:3] # slice the first three hits - >>> len(qresult) - 100 - >>> len(sliced_qresult) - 3 - >>> print(sliced_qresult) - Program: blastn (2.2.27+) - Query: 33211 (61) - mir_1 - Target: refseq_rna - Hits: ---- ----- ---------------------------------------------------------- - # # HSP ID + description - ---- ----- ---------------------------------------------------------- - 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... - 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... - 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... - - Like Python dictionaries, you can also retrieve hits using the hit's ID. - This is useful for retrieving hits that you know should exist in a given - search:: - - >>> hit = qresult['gi|262205317|ref|NR_030195.1|'] - >>> hit - Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) - - You can also replace a Hit in QueryResult with another Hit using either the - integer index or hit key string. Note that the replacing object must be a - Hit that has the same ``query_id`` property as the QueryResult object. - - If you're not sure whether a QueryResult contains a particular hit, you can - use the hit ID to check for membership first:: - - >>> 'gi|262205317|ref|NR_030195.1|' in qresult - True - >>> 'gi|262380031|ref|NR_023426.1|' in qresult - False - - Or, if you just want to know the rank / position of a given hit, you can - use the hit ID as an argument for the ``index`` method. Note that the values - returned will be zero-based. So zero (0) means the hit is the first in the - QueryResult, three (3) means the hit is the fourth item, and so on. If the - hit does not exist in the QueryResult, a ``ValueError`` will be raised. - - >>> qresult.index('gi|262205317|ref|NR_030195.1|') - 0 - >>> qresult.index('gi|262205330|ref|NR_030198.1|') - 5 - >>> qresult.index('gi|262380031|ref|NR_023426.1|') - Traceback (most recent call last): - ... - ValueError: ... - - To ease working with a large number of hits, QueryResult has several - ``filter`` and ``map`` methods, analogous to Python's built-in functions with - the same names. There are ``filter`` and ``map`` methods available for - operations over both Hit objects or HSP objects. As an example, here we are - using the ``hit_map`` method to rename all hit IDs within a QueryResult:: - - >>> def renamer(hit): - ... hit.id = hit.id.split('|')[3] - ... return hit - >>> mapped_qresult = qresult.hit_map(renamer) - >>> print(mapped_qresult) - Program: blastn (2.2.27+) - Query: 33211 (61) - mir_1 - Target: refseq_rna - Hits: ---- ----- ---------------------------------------------------------- - # # HSP ID + description - ---- ----- ---------------------------------------------------------- - 0 1 NR_030195.1 Homo sapiens microRNA 520b (MIR520B), micr... - 1 1 NR_035856.1 Pan troglodytes microRNA mir-520b (MIR520B... - 2 1 NR_032573.1 Macaca mulatta microRNA mir-519a (MIR519A)... - ... - - The principle for other ``map`` and ``filter`` methods are similar: they accept - a function, applies it, and returns a new QueryResult object. - - There are also other methods useful for working with list-like objects: - ``append``, ``pop``, and ``sort``. More details and examples are available in - their respective documentations. - - Finally, just like Python lists and dictionaries, QueryResult objects are - iterable. Iteration over QueryResults will yield Hit objects:: - - >>> for hit in qresult[:4]: # iterate over the first four items - ... hit - ... - Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) - Hit(id='gi|301171311|ref|NR_035856.1|', query_id='33211', 1 hsps) - Hit(id='gi|270133242|ref|NR_032573.1|', query_id='33211', 1 hsps) - Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 2 hsps) - - If you need access to all the hits in a QueryResult object, you can get - them in a list using the ``hits`` property. Similarly, access to all hit IDs is - available through the ``hit_keys`` property. - - >>> qresult.hits - [Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps), ...] - >>> qresult.hit_keys - ['gi|262205317|ref|NR_030195.1|', 'gi|301171311|ref|NR_035856.1|', ...] +.. code-block:: pycon + :name: query_result_block + + >>> from pxblat import Client, Server + >>> def query_context(): + ... host = "localhost" + ... port = 65000 + ... seq_dir = "." + ... two_bit = "./test_ref.2bit" + ... client = Client( + ... host=host, + ... port=port, + ... seq_dir=seq_dir, + ... min_score=20, + ... min_identity=90, + ... ) + ... with Server(host, port, two_bit, can_stop=True, step_size=5) as server: + ... # work() assume work() is your own function that takes time to prepare something + ... server.wait_ready() + ... result1 = client.query("ATCG") + ... result2 = client.query("AtcG") + ... result3 = client.query("test_case1.fa") + ... result4 = client.query(["ATCG", "ATCG"]) + ... result5 = client.query(["test_case1.fa"]) + ... result6 = client.query(["cgTA", "test_case1.fa"]) + ... return [result1, result2, result3, result4, result5, result6] + >>> results = query_context() # get all alignment results + >>> results + [[None], [None], [QueryResult(id='case1', 1 hits)], [None, None], [QueryResult(id='case1', 1 hits)], [None, QueryResult(id='case1', 1 hits)]] + >>> results[2] # let's pick up the result of test_case1.fa + [QueryResult(id='case1', 1 hits)] + >>> result3 = results[2] + >>> result3 + [QueryResult(id='case1', 1 hits)] + >>> print(result3[0]) # let's show information of the result + Program: blat (v.37x1) + Query: case1 (151) + + Target: + Hits: ---- ----- ---------------------------------------------------------- + # # HSP ID + description + ---- ----- ---------------------------------------------------------- + 0 1 chr1 + >>> result = result3[0] # let's get the element in the result list + >>> result + QueryResult(id='case1', 1 hits) + >>> print(result) + Program: blat (v.37x1) + Query: case1 (151) + + Target: + Hits: ---- ----- ---------------------------------------------------------- + # # HSP ID + description + ---- ----- ---------------------------------------------------------- + 0 1 chr1 + >>> result.hsps # check all high-scoring pairs (HSPs) + [HSP(hit_id='chr1', query_id='case1', 1 fragments)] + >>> result[0] # check the top hsp + Hit(id='chr1', query_id='case1', 1 hsps) + >>> print(result[0]) # show more information about top hsp + Query: case1 + + Hit: chr1 (14999) + + HSPs: ---- -------- --------- ------ --------------- --------------------- + # E-value Bit score Span Query range Hit range + ---- -------- --------- ------ --------------- --------------------- + 0 ? ? ? [0:151] [12699:12850] + >>> top_hsp = result.hsps[0] + >>> top_hsp + HSP(hit_id='chr1', query_id='case1', 1 fragments) + >>> print(top_hsp) + Query: case1 + Hit: chr1 + Query range: [0:151] (1) + Hit range: [12699:12850] (1) + Quick stats: evalue ?; bitscore ? + Fragments: 1 (? columns) + >>> top_hsp.query_id # test_case1's id in top_hsp + 'case1' + >>> top_hsp.query_range # test_case1's query_range in top_hsp + (0, 151) + >>> top_hsp.query_span # test_case1's query_span in top_hsp + 151 + >>> top_hsp.query_start # test_case1's query_start in top_hsp + 0 + >>> top_hsp.query_strand # test_case1's query_strand in top_hsp + 1 + >>> top_hsp.hit_id # in top_hsp, test_case1 hit `chr1` of the reference + 'chr1' + >>> top_hsp.hit_range # in top_hsp, test_case1 hit (12699, 12850) of the reference + (12699, 12850) + >>> top_hsp.hit_start + 12699 + >>> top_hsp.hit_strand # in top_hsp, test_case1 hit strand of the reference (1 means positive strand) + 1 + >>> top_hsp. + top_hsp.aln top_hsp.hit_frame top_hsp.ident_pct top_hsp.query_frame_all + top_hsp.aln_all top_hsp.hit_frame_all top_hsp.is_fragmented top_hsp.query_gap_num + top_hsp.aln_annotation top_hsp.hit_gap_num top_hsp.match_num top_hsp.query_gapopen_num + top_hsp.aln_annotation_all top_hsp.hit_gapopen_num top_hsp.match_rep_num top_hsp.query_id + top_hsp.aln_span top_hsp.hit_id top_hsp.mismatch_num top_hsp.query_inter_ranges + top_hsp.fragment top_hsp.hit_inter_ranges top_hsp.molecule_type top_hsp.query_inter_spans + top_hsp.fragments top_hsp.hit_inter_spans top_hsp.n_num top_hsp.query_is_protein + top_hsp.gap_num top_hsp.hit_range top_hsp.output_index top_hsp.query_range + top_hsp.gapopen_num top_hsp.hit_range_all top_hsp.query top_hsp.query_range_all + top_hsp.hit top_hsp.hit_span top_hsp.query_all top_hsp.query_span + top_hsp.hit_all top_hsp.hit_span_all top_hsp.query_description top_hsp.query_span_all + top_hsp.hit_description top_hsp.hit_start top_hsp.query_end top_hsp.query_start + top_hsp.hit_end top_hsp.hit_start_all top_hsp.query_end_all top_hsp.query_start_all + top_hsp.hit_end_all top_hsp.hit_strand top_hsp.query_features top_hsp.query_strand + top_hsp.hit_features top_hsp.hit_strand_all top_hsp.query_features_all top_hsp.query_strand_all + top_hsp.hit_features_all top_hsp.ident_num top_hsp.query_frame top_hsp.score + +``` + +````{example} query_result code +:collapsible: close + +```{literalinclude} tutorial_data/query_result.py ``` -## APIs Compared to `BLAT` +```` + +We can precisely determine the regions of our sequence that align with specific parts of the reference. +We are able to know strand, start position, and end position for alignment part +both for our sequence and the reference. +The last part of [code example](#query_result_block) shows all methods of a high-scoring pairs (HSP). + +## 6. APIs Compared to `BLAT` So far, **PxBLAT** provides APIs, including {class}`.Client`, {class}`.Server`, {func}`.two_bit_to_fa` and {func}`.fa_to_two_bit`, as well as other useful functions ({doc}`reference`). **PxBLAT** is able to finish the most significant features of `BLAT`. Here is a table in which the features are compared. -| PxBLAT | BLAT | -| :--------------------- | :----------------------- | -| {class}`.Client` | [gfClient][gfClient] | -| {class}`.Server` | [gfServer][gfServer] | -| {func}`.two_bit_to_fa` | [twoBitToFa][twoBitToFa] | -| {func}`.fa_to_two_bit` | [faToTwoBit][faToTwoBit] | - -```{eval-rst} -.. code-block:: python - :linenos: +```{list-table} APIs Comparison + :header-rows: 1 + :align: center + + * - PxBLAT + - BLAT + * - {class}`.Client` + - [gfClient][gfClient] + * - {class}`.Server` + - [gfServer][gfServer] + * - {func}`.two_bit_to_fa` + - [twoBitToFa][twoBitToFa] + * - {func}`.fa_to_two_bit` + - [faToTwoBit][faToTwoBit] - from pxblat import Server - - server = Server("localhost", port, two_bit, server_option) # (1)! - -.. code-annotations:: - #. we change step size and tile size ``` -## Beyond APIs +## 7. Beyond APIs Even though `PxBLAT` is designed as library, it provides command-line tools using its APIs. That could provide more choices for user according to different situations. {doc}`reference` contain more details, and do not hesitate to check. +```{bug} +please feel free to [edit the tutorial](https://github.com/ylab-hi/pxblat/edit/main/docs/tutorial.md) or [open an issue](https://github.com/ylab-hi/pxblat/issues/new/choose), if you find some unclear or wrong statement. + +``` + [gfclient]: https://genome.ucsc.edu/goldenpath/help/blatSpec.html#gfClientUsage diff --git a/docs/tutorial_data/2bit.py b/docs/tutorial_data/2bit.py index 4b1b37da..0df0235a 100644 --- a/docs/tutorial_data/2bit.py +++ b/docs/tutorial_data/2bit.py @@ -8,3 +8,4 @@ ignoreDups=False, useLong=False, ) +print("Done") diff --git a/docs/tutorial_data/query_context.py b/docs/tutorial_data/query_context.py index c0d7216e..f1cecda7 100644 --- a/docs/tutorial_data/query_context.py +++ b/docs/tutorial_data/query_context.py @@ -1,5 +1,6 @@ from pxblat import Client, Server + def query_context(): host = "localhost" port = 65000 @@ -34,5 +35,6 @@ def query_context(): print(f"{result5=}") print(f"{result6=}") + if __name__ == "__main__": query_context() diff --git a/docs/tutorial_data/query_general.py b/docs/tutorial_data/query_general.py new file mode 100644 index 00000000..0a727797 --- /dev/null +++ b/docs/tutorial_data/query_general.py @@ -0,0 +1,32 @@ +from pxblat import Client, Server + + +def query_general(): + host = "localhost" + port = 65000 + seq_dir = "." + two_bit = "./test_ref.2bit" + + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, + min_identity=90, + ) + + server = Server(host, port, two_bit, can_stop=True, step_size=5) + server.start() + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() + result1 = client.query(["actg", "test_case1.fa"]) + # another_work() assume the func is your own function that takes time + result2 = client.query("test_case1.fa") + server.stop() + + print(f"{result1=}") + print(f"{result2=}") + + +if __name__ == "__main__": + query_general() diff --git a/docs/tutorial_data/query_result.py b/docs/tutorial_data/query_result.py new file mode 100644 index 00000000..d4b83f84 --- /dev/null +++ b/docs/tutorial_data/query_result.py @@ -0,0 +1,72 @@ +from pxblat import Client, Server + + +def query_context(): + host = "localhost" + port = 65000 + seq_dir = "." + two_bit = "./test_ref.2bit" + client = Client( + host=host, + port=port, + seq_dir=seq_dir, + min_score=20, + min_identity=90, + ) + with Server(host, port, two_bit, can_stop=True, step_size=5) as server: + # work() assume work() is your own function that takes time to prepare something + server.wait_ready() + result1 = client.query("ATCG") + result2 = client.query("AtcG") + result3 = client.query("test_case1.fa") + result4 = client.query(["ATCG", "ATCG"]) + result5 = client.query(["test_case1.fa"]) + result6 = client.query(["cgTA", "test_case1.fa"]) + return [result1, result2, result3, result4, result5, result6] + + +def query_result(): + results = query_context() # get all alignment results + results[2] # let's pick up the result of test_case1.fa + result3 = results[2] + print(result3) + print(result3[0]) # let's show information of the result + result = result3[0] # let's get the element in the result list + print(result) + print(result) + print(result.hsps) # check all high-scoring pairs (HSPs) + print(result[0]) # check the top hsp + print(result[0]) # show more information about top hsp + top_hsp = result.hsps[0] + print(top_hsp) + print(top_hsp) + print(top_hsp.query_id) # test_case1's id in top_hsp + print(top_hsp.query_range) # test_case1's query_range in top_hsp + print(top_hsp.query_span) # test_case1's query_span in top_hsp + print(top_hsp.query_start) # test_case1's query_start in top_hsp + print(top_hsp.query_strand) # test_case1's query_strand in top_hsp + print(top_hsp.hit_id) # in top_hsp, test_case1 hit `chr1` of the reference + print(top_hsp.hit_range) # in top_hsp, test_case1 hit (12699, 12850) of the reference + print(top_hsp.hit_start) + print(top_hsp.hit_strand) # in top_hsp, test_case1 hit strand of the reference (1 means positive strand) + # >>> top_hsp. + # top_hsp.aln top_hsp.hit_frame top_hsp.ident_pct top_hsp.query_frame_all + # top_hsp.aln_all top_hsp.hit_frame_all top_hsp.is_fragmented top_hsp.query_gap_num + # top_hsp.aln_annotation top_hsp.hit_gap_num top_hsp.match_num top_hsp.query_gapopen_num + # top_hsp.aln_annotation_all top_hsp.hit_gapopen_num top_hsp.match_rep_num top_hsp.query_id + # top_hsp.aln_span top_hsp.hit_id top_hsp.mismatch_num top_hsp.query_inter_ranges + # top_hsp.fragment top_hsp.hit_inter_ranges top_hsp.molecule_type top_hsp.query_inter_spans + # top_hsp.fragments top_hsp.hit_inter_spans top_hsp.n_num top_hsp.query_is_protein + # top_hsp.gap_num top_hsp.hit_range top_hsp.output_index top_hsp.query_range + # top_hsp.gapopen_num top_hsp.hit_range_all top_hsp.query top_hsp.query_range_all + # top_hsp.hit top_hsp.hit_span top_hsp.query_all top_hsp.query_span + # top_hsp.hit_all top_hsp.hit_span_all top_hsp.query_description top_hsp.query_span_all + # top_hsp.hit_description top_hsp.hit_start top_hsp.query_end top_hsp.query_start + # top_hsp.hit_end top_hsp.hit_start_all top_hsp.query_end_all top_hsp.query_start_all + # top_hsp.hit_end_all top_hsp.hit_strand top_hsp.query_features top_hsp.query_strand + # top_hsp.hit_features top_hsp.hit_strand_all top_hsp.query_features_all top_hsp.query_strand_all + # top_hsp.hit_features_all top_hsp.ident_num top_hsp.query_frame top_hsp.score + + +if __name__ == "__main__": + query_result() diff --git a/pyproject.toml b/pyproject.toml index ee3f38f5..3a310dd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,7 +169,6 @@ ignore = [ 'W191', ] exclude = [ - "docs/tutorial_data/*", "src/pxblat/extc/__init__.pyi", "src/pxblat/__init__.py", "tasks.py", @@ -232,6 +231,10 @@ allow-star-arg-any = true "src/pxblat/cli/cli.py" = ["DTZ005"] "src/pxblat/toolkit/__init__.py" = ["PLR0913"] "src/pxblat/parser.py" = ["A001", "A002", "ARG001"] +"docs/tutorial_data/query_context.py" = ["T201", "D103"] +"docs/tutorial_data/2bit.py" = ["T201", "D103"] +"docs/tutorial_data/query_general.py" = ["T201", "D103"] +"docs/tutorial_data/query_result.py" = ["T201", "D103"] [tool.ruff.pydocstyle] convention = 'google' From e04513af0f2766ba19a1fe0f125c375e6397a17e Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Wed, 25 Oct 2023 13:33:36 -0500 Subject: [PATCH 5/5] chroe: update dependencies --- poetry.lock | 121 +++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0600903b..3d162d35 100644 --- a/poetry.lock +++ b/poetry.lock @@ -906,73 +906,68 @@ test = ["backports.socketpair", "cffi (>=1.12.2)", "contextvars (==2.4)", "cover [[package]] name = "greenlet" -version = "3.0.0" +version = "3.0.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" files = [ - {file = "greenlet-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f"}, - {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a"}, - {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779"}, - {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9"}, - {file = "greenlet-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7"}, - {file = "greenlet-3.0.0-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f"}, - {file = "greenlet-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14"}, - {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b"}, - {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c"}, - {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362"}, - {file = "greenlet-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c"}, - {file = "greenlet-3.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383"}, - {file = "greenlet-3.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66"}, - {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb"}, - {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35"}, - {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17"}, - {file = "greenlet-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6b5ce7f40f0e2f8b88c28e6691ca6806814157ff05e794cdd161be928550f4c"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf94aa539e97a8411b5ea52fc6ccd8371be9550c4041011a091eb8b3ca1d810"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80dcd3c938cbcac986c5c92779db8e8ce51a89a849c135172c88ecbdc8c056b7"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e52a712c38e5fb4fd68e00dc3caf00b60cb65634d50e32281a9d6431b33b4af1"}, - {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5539f6da3418c3dc002739cb2bb8d169056aa66e0c83f6bacae0cd3ac26b423"}, - {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:343675e0da2f3c69d3fb1e894ba0a1acf58f481f3b9372ce1eb465ef93cf6fed"}, - {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:abe1ef3d780de56defd0c77c5ba95e152f4e4c4e12d7e11dd8447d338b85a625"}, - {file = "greenlet-3.0.0-cp37-cp37m-win32.whl", hash = "sha256:e693e759e172fa1c2c90d35dea4acbdd1d609b6936115d3739148d5e4cd11947"}, - {file = "greenlet-3.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bdd696947cd695924aecb3870660b7545a19851f93b9d327ef8236bfc49be705"}, - {file = "greenlet-3.0.0-cp37-universal2-macosx_11_0_x86_64.whl", hash = "sha256:cc3e2679ea13b4de79bdc44b25a0c4fcd5e94e21b8f290791744ac42d34a0353"}, - {file = "greenlet-3.0.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:63acdc34c9cde42a6534518e32ce55c30f932b473c62c235a466469a710bfbf9"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a1a6244ff96343e9994e37e5b4839f09a0207d35ef6134dce5c20d260d0302c"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b822fab253ac0f330ee807e7485769e3ac85d5eef827ca224feaaefa462dc0d0"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8060b32d8586e912a7b7dac2d15b28dbbd63a174ab32f5bc6d107a1c4143f40b"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:621fcb346141ae08cb95424ebfc5b014361621b8132c48e538e34c3c93ac7365"}, - {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bb36985f606a7c49916eff74ab99399cdfd09241c375d5a820bb855dfb4af9f"}, - {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10b5582744abd9858947d163843d323d0b67be9432db50f8bf83031032bc218d"}, - {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f351479a6914fd81a55c8e68963609f792d9b067fb8a60a042c585a621e0de4f"}, - {file = "greenlet-3.0.0-cp38-cp38-win32.whl", hash = "sha256:9de687479faec7db5b198cc365bc34addd256b0028956501f4d4d5e9ca2e240a"}, - {file = "greenlet-3.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:3fd2b18432e7298fcbec3d39e1a0aa91ae9ea1c93356ec089421fabc3651572b"}, - {file = "greenlet-3.0.0-cp38-universal2-macosx_11_0_x86_64.whl", hash = "sha256:3c0d36f5adc6e6100aedbc976d7428a9f7194ea79911aa4bf471f44ee13a9464"}, - {file = "greenlet-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99"}, - {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a"}, - {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692"}, - {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4"}, - {file = "greenlet-3.0.0-cp39-cp39-win32.whl", hash = "sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9"}, - {file = "greenlet-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce"}, - {file = "greenlet-3.0.0-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355"}, - {file = "greenlet-3.0.0.tar.gz", hash = "sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b"}, + {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, + {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, + {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, + {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, + {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, + {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a"}, + {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de"}, + {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166"}, + {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36"}, + {file = "greenlet-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1"}, + {file = "greenlet-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8"}, + {file = "greenlet-3.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd"}, + {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9"}, + {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e"}, + {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a"}, + {file = "greenlet-3.0.1-cp38-cp38-win32.whl", hash = "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd"}, + {file = "greenlet-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6"}, + {file = "greenlet-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1"}, + {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d"}, + {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8"}, + {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546"}, + {file = "greenlet-3.0.1-cp39-cp39-win32.whl", hash = "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57"}, + {file = "greenlet-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619"}, + {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, ] [package.extras]