<p>One approach is to get the gene's sequence (DNA/AA) and use the interproscan API  (e.g., <a href="https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5" rel="nofollow noreferrer">https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5</a>) with the httr2 library in R to POST gene sequence(s) and GET the resulting Panther annotation. Make sure to include <code>Panther</code> in the <code>appl</code> parameter for the post request.</p>
<p>Here's a function that does this for a single sequence.</p>
<pre><code>submit_fasta &lt;- function(
    fasta,
    path_outfolder,
    email,
    stype = &quot;n&quot;,
    appl = c(&quot;Panther&quot;),
    title = 'stackoverflow'
    ) {
  stopifnot(&quot;stype must be 'n' for nucleotide seqs or 'p' for protein seqs&quot; = stype %in% c('n', 'p'))
  url_post &lt;- &quot;https://www.ebi.ac.uk/Tools/services/rest/iprscan5/run&quot;
  chr_seq &lt;- as.character(fasta)
  req &lt;- httr2::request(url_post)
  req &lt;- req |&gt; httr2::req_body_form(
    &quot;email&quot; = email,
    &quot;title&quot; = title,
    &quot;goterms&quot; = &quot;false&quot;,
    &quot;pathways&quot; = &quot;false&quot;,
    &quot;stype&quot; = stype,
    &quot;appl&quot; = paste0(appl, collapse = &quot;,&quot;),
    &quot;sequence&quot; = chr_seq
  )
  req &lt;- req |&gt; httr2::req_headers(&quot;Accept&quot; = &quot;text/plain&quot;, &quot;Content-type&quot; = &quot;application/x-www-form-urlencoded&quot;)
  resp_post &lt;- req |&gt; httr2::req_perform()
  chr_retrieval_code &lt;- resp_post$body |&gt; rawToChar()
  url_get &lt;- &quot;https://www.ebi.ac.uk/Tools/services/rest/iprscan5/result&quot;
  req &lt;- httr2::request(url_get)
  req &lt;- req |&gt; httr2::req_url_path_append(chr_retrieval_code)
  req &lt;- req |&gt; httr2::req_url_path_append(&quot;tsv&quot;)
  req &lt;- req |&gt; httr2::req_retry(
    max_tries = 15L, backoff = ~ 30L,
    is_transient = function(resp) {httr2::resp_status(resp) == 400L}
  )
  req &lt;- req |&gt; httr2::req_headers(Accept = NULL)
  req |&gt; httr2::req_dry_run(quiet = FALSE)
  resp_get &lt;- req |&gt; httr2::req_perform()
  cat('status code:', resp_get$status_code, '\n')
  result &lt;- resp_get$body |&gt; rawToChar()
  result &lt;- read.table(text = result, sep = '\t')
  return(result)
}
</code></pre>
<p>Importantly, the fasta input parameter is expected to be XString object from the Biostrings package. However, the code could easily be adjusted. The sequence eventually needs to be coerced to a string for the POST request.</p>
<pre><code>#fasta &lt;- Biostrings::readDNAStringSet('seq.fa')
#resp &lt;- submit_fasta(fasta = fasta_single, path_outfolder = 'x', email = 'test@gmail.com', title = 'stackoverflow')
</code></pre>
<p><strong>edit</strong>: set the <code>is_transient</code> param to handle the actual transient error case where the data is not yet available (response code = 400). Also, it's important to note there's a &quot;status&quot; endpoint <a href="https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5#/Status" rel="nofollow noreferrer">https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5#/Status</a>) which is probably much more appropriate than pinging the data endpoint until either success or reaching max tries. However, I hope this answer suffices!</p>

CC BY-SA 4.0
2023-11-21T13:29:02.260Z
Wow, thank you for your comprehensive answer and welcome to the site.
M__
CC BY-SA 4.0
2023-11-23T00:38:23.973Z
@M__ Thanks for the welcome reply!
Jacob Krol
CC BY-SA 4.0
2023-11-21T07:22:20.887Z
2023-11-23T00:36:46.120Z
2023-11-23T00:36:46.120Z
Jacob Krol
<p>Does anyone know of a way to programmatically get panther protein class terms and IDs for a gene list, in a way that the classification structure is preserved (PARENT CLASS + CHILD CLASS)?</p>
<p>i.e. For a given gene, I would want to get the list of classes, in away that I can then use the top classification for downstream analyses.</p>
<p>GENEX, PC00244 zinc finger transcription factor &gt; PC00218 DNA-binding transcription factor &gt; PC00264 gene-specific transcriptional regulator</p>

<r><public-databases><functional-annotation>
PANTHER FUNCTIONAL CLASSIFICATION in R
# PANTHER FUNCTIONAL CLASSIFICATION in R

(Asked by: username_0 on 2023-11-17)

Does anyone know of a way to programmatically get panther protein class terms and IDs for a gene list, in a way that the classification structure is preserved (PARENT CLASS + CHILD CLASS)?

i.e. For a given gene, I would want to get the list of classes, in away that I can then use the top classification for downstream analyses.

GENEX, PC00244 zinc finger transcription factor > PC00218 DNA-binding transcription factor > PC00264 gene-specific transcriptional regulator

**Tags:** r, public-databases, functional-annotation

---

## 1 answers

### Answer by username_1 on 2023-11-21. Score: 1

One approach is to get the gene's sequence (DNA/AA) and use the interproscan API  (e.g., https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5) with the httr2 library in R to POST gene sequence(s) and GET the resulting Panther annotation. Make sure to include Panther in the appl parameter for the post request.
Here's a function that does this for a single sequence.
submit_fasta <- function(
    fasta,
    path_outfolder,
    email,
    stype = "n",
    appl = c("Panther"),
    title = 'stackoverflow'
    ) {
  stopifnot("stype must be 'n' for nucleotide seqs or 'p' for protein seqs" = stype %in% c('n', 'p'))
  url_post <- "https://www.ebi.ac.uk/Tools/services/rest/iprscan5/run"
  chr_seq <- as.character(fasta)
  req <- httr2::request(url_post)
  req <- req |> httr2::req_body_form(
    "email" = email,
    "title" = title,
    "goterms" = "false",
    "pathways" = "false",
    "stype" = stype,
    "appl" = paste0(appl, collapse = ","),
    "sequence" = chr_seq
  )
  req <- req |> httr2::req_headers("Accept" = "text/plain", "Content-type" = "application/x-www-form-urlencoded")
  resp_post <- req |> httr2::req_perform()
  chr_retrieval_code <- resp_post$body |> rawToChar()
  url_get <- "https://www.ebi.ac.uk/Tools/services/rest/iprscan5/result"
  req <- httr2::request(url_get)
  req <- req |> httr2::req_url_path_append(chr_retrieval_code)
  req <- req |> httr2::req_url_path_append("tsv")
  req <- req |> httr2::req_retry(
    max_tries = 15L, backoff = ~ 30L,
    is_transient = function(resp) {httr2::resp_status(resp) == 400L}
  )
  req <- req |> httr2::req_headers(Accept = NULL)
  req |> httr2::req_dry_run(quiet = FALSE)
  resp_get <- req |> httr2::req_perform()
  cat('status code:', resp_get$status_code, '\n')
  result <- resp_get$body |> rawToChar()
  result <- read.table(text = result, sep = '\t')
  return(result)
}

Importantly, the fasta input parameter is expected to be XString object from the Biostrings package. However, the code could easily be adjusted. The sequence eventually needs to be coerced to a string for the POST request.
#fasta <- Biostrings::readDNAStringSet('seq.fa')
#resp <- submit_fasta(fasta = fasta_single, path_outfolder = 'x', email = 'test@gmail.com', title = 'stackoverflow')

edit: set the is_transient param to handle the actual transient error case where the data is not yet available (response code = 400). Also, it's important to note there's a "status" endpoint https://www.ebi.ac.uk/Tools/common/tools/help/index.html?tool=iprscan5#/Status) which is probably much more appropriate than pinging the data endpoint until either success or reaching max tries. However, I hope this answer suffices!

> **Comments:**
> **username_2**: Wow, thank you for your comprehensive answer and welcome to the site.  
> **username_1**: @M__ Thanks for the welcome reply!  

---

