Last active
January 12, 2022 00:19
-
-
Save fomightez/a456c200cb86a0c0aa603e33d7230b81 to your computer and use it in GitHub Desktop.
Snakemake pipeline for demonstrating use of Python's `input` command to collect text while running a rule.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Save this file as `demo_user_input_snakefile` where you want to run this | |
# pipeline. | |
# Snakemake pipeline for demonstrating use of Python's `input` command to | |
# collect text while running a rule. The tricky thing as highlighted at | |
# https://www.biostars.org/p/9505154/#9505163 is that `input` is a reserved word | |
# in Snakemake rules and so you have to bind the Python `input` do a different | |
# name. | |
# | |
# | |
# This file can be run by calling | |
# `snakemake -j1 -s demo_user_input_snakefile` on the command line. | |
# Via MyBinder, run this Snakefile with the following in terminal: | |
# snakemake --cores 1 -s demo_user_input_snakefile | |
# HAS TO BE IN TERMINAL SO YOU CAN ACCESS PROMPT TO SUPPLY TEXT for | |
# `user_input` step. | |
# Use `%pip install snakemake` in a Jupyter notebook if snakemake is needed | |
# installed in a session served via MyBInder.org. | |
# Only 1 core, because I think when I was using 8 it would commonly cause a race | |
# where more than one notebook was getting auxillary scripts and overwriting as | |
# as the other notebooks was trying to use. More reliable with 1. But if it, did | |
# fail when using more cores, try re-running again because it should just | |
# complete the missing files. | |
# For cleaning, there won't be any conflicts, so use the following in terminal | |
# on MyBbinder-served sessions: | |
# snakemake -s demo_user_input_snakefile --cores 8 clean | |
# To just initiate a rule/step, run something like: | |
# `snakemake -j 8 <name_of_rules> -s <snakefile_name>`, where the number 8 is | |
# replaced by the result of the command `getconf _NPROCESSORS_ONLN`. | |
import os | |
import sys | |
# FILES THAT WILL BE GENERATED-------------------------------------------------- | |
# initiating_files #initiating files to generate in ordrt to to use to trigger | |
# main rule | |
# text_files_w_content # file corresponding to trigger file with content | |
# provided by user via prompt | |
##----------------HELPER FUNCTIONS---------------------------------------------- | |
def write_string_to_file(s, fn): | |
''' | |
Takes a string, `s`, and a name for a file & writes the string to the file. | |
''' | |
with open(fn, 'w') as output_file: | |
output_file.write(s) | |
##-----------END OF HELPER FUNCTIONS-------------------------------------------- | |
# PREPARATION------------------------------------------------------------------- | |
# MAKE LIST OF FILES THAT SCRIPT WILL MAKE-------------------------------------- | |
# since there isn't really much of anything going on in this pipeline, aside | |
# from demonstrating how to get user input in a rule and use the string, these | |
# are really just 'placeholder' files | |
number_demo_files_to_make = 4 | |
initiating_files = [f"init_file_{i}.txt" for i in range( | |
number_demo_files_to_make)] | |
text_files_w_content = [f"result_{i}.txt" for i in range( | |
number_demo_files_to_make)] | |
# MAKE THE initiating_files THAT WILL TRIGGER MAIN RULE FOR EACH FILE----------- | |
for indx,init_file in enumerate(initiating_files): | |
if not os.path.isfile(init_file): | |
write_string_to_file(f"MOCK_CONTENT_for_TRIGGER_FILE{indx}",init_file) | |
# END OF PREPARATION------------------------------------------------------------ | |
# SNAKEMAKE RULES--------------------------------------------------------------- | |
rule all: | |
input: | |
text_files_w_content | |
# ---------------Individual Rules--------------------------------------------- | |
# Delete any generated files so can trigger full run easily after cleaning | |
''' | |
The `touch` commands added make sure files matching each and every pattern of | |
output so that the `rm` commands don't throw an error. | |
''' | |
rule clean: | |
shell: | |
''' | |
touch init_file_18199xlkleFAKE.txt | |
touch result_18199xlkleFAKE.txt | |
rm init_file_*.txt | |
rm result_*.txt | |
''' | |
# Make the result file with the content the user types in when prompted | |
''' | |
Main rule of this demonstration pipeline. | |
User is prompted to type in some text to be content for produced file. | |
Demonstrates getting user input via Python `input` inside a rule, based on | |
https://www.biostars.org/p/9505154/#9505163 . | |
''' | |
user_input = input | |
rule make_result_file_with_user_provided_content: | |
input: | |
"init_file_{num}.txt" | |
output: | |
"result_{num}.txt" | |
run: | |
file_to_make = str(list({output})[0]) | |
#Get text content from user | |
txt_content = user_input(f"Type a few letters or words to use as file content for {file_to_make} and then hit return: ") | |
#Generate output file | |
write_string_to_file(txt_content,file_to_make) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment