Skip to content

Instantly share code, notes, and snippets.

@fomightez
Last active January 12, 2022 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fomightez/a456c200cb86a0c0aa603e33d7230b81 to your computer and use it in GitHub Desktop.
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.
# 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