Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-21T13:29:02.260Z
Answers.Text: Wow, thank you for your comprehensive answer and welcome to the site.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-23T00:38:23.973Z
Answers.Text: @M__ Thanks for the welcome reply!
Answers.UserDisplayName: Jacob Krol
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-21T07:22:20.887Z
Answers.LastActivityDate: 2023-11-23T00:36:46.120Z
Answers.LastEditDate: 2023-11-23T00:36:46.120Z
Answers.UserDisplayName: Jacob Krol
Body: <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>
  
Tags: <r><public-databases><functional-annotation>
Title: PANTHER FUNCTIONAL CLASSIFICATION in R
ThreadText: # 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**: @username_2 Thanks for the welcome reply!  
  
  ---
  
  