├── .gitignore ├── requirements.txt ├── LICENSE ├── README.md └── ipynb_converter_app.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the virtual environment directory 2 | venv/ -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | streamlit 2 | ipynb-py-convert 3 | requests 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 rohanmistry231 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jupyter Notebook to Python Converter 2 | 3 | A web application built with Streamlit that allows users to easily convert Jupyter Notebook (.ipynb) files to Python (.py) script files. 4 | 5 | ## Features 6 | 7 | - **User-friendly Interface**: Clean and intuitive Streamlit UI 8 | - **Multiple Input Methods**: 9 | - Upload local .ipynb files directly 10 | - Convert from URLs 11 | - **Batch Processing**: Convert multiple files at once 12 | - **Download Options**: 13 | - Direct download for single files 14 | - ZIP archive for multiple files 15 | - **Error Handling**: Clear feedback on conversion success or failure 16 | 17 | ## Requirements 18 | 19 | - Python 3.7 or higher 20 | - Streamlit 21 | - ipynb-py-convert 22 | - requests 23 | 24 | ## Installation 25 | 26 | 1. Clone this repository: 27 | ``` 28 | git clone https://github.com/yourusername/ipynb-to-py-converter.git 29 | cd ipynb-to-py-converter 30 | ``` 31 | 32 | 2. Install the required packages: 33 | ``` 34 | pip install -r requirements.txt 35 | ``` 36 | 37 | ## Usage 38 | 39 | 1. Run the Streamlit app: 40 | ``` 41 | streamlit run ipynb_converter_app.py 42 | ``` 43 | 44 | 2. Open your web browser and navigate to: 45 | ``` 46 | http://localhost:8501 47 | ``` 48 | 49 | 3. Use either the "File Upload" or "URL Input" tab to convert your Jupyter Notebook files 50 | 51 | ## How It Works 52 | 53 | This application uses the `ipynb-py-convert` library to perform the conversion from .ipynb to .py format. The conversion preserves: 54 | 55 | - Code cells 56 | - Markdown cells (as comments) 57 | - Cell execution order 58 | 59 | ## Project Structure 60 | 61 | ``` 62 | ipynb-to-py-converter/ 63 | ├── ipynb_converter_app.py # Main Streamlit application 64 | ├── requirements.txt # Python dependencies 65 | └── README.md # Project documentation 66 | ``` 67 | 68 | ## Deployment 69 | 70 | This application can be deployed to Streamlit Sharing, Heroku, or any other platform that supports Streamlit applications. 71 | 72 | ## License 73 | 74 | This project is licensed under the MIT License - see the LICENSE file for details. 75 | 76 | ## Acknowledgements 77 | 78 | - [ipynb-py-convert](https://github.com/kiwi0fruit/ipynb-py-convert) for the conversion tool 79 | - [Streamlit](https://streamlit.io/) for the web application framework 80 | -------------------------------------------------------------------------------- /ipynb_converter_app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import os 3 | import tempfile 4 | import zipfile 5 | import subprocess 6 | import uuid 7 | import base64 8 | import requests 9 | from pathlib import Path 10 | from urllib.parse import urlparse 11 | 12 | st.set_page_config( 13 | page_title="Jupyter Notebook to Python Converter", 14 | page_icon="🐍", 15 | layout="wide", 16 | ) 17 | 18 | # Custom CSS 19 | st.markdown(""" 20 | 59 | """, unsafe_allow_html=True) 60 | 61 | def check_ipynb_py_convert(): 62 | """Check if ipynb-py-convert is installed, install if not.""" 63 | try: 64 | subprocess.run(["ipynb-py-convert", "--help"], capture_output=True, text=True) 65 | return True 66 | except FileNotFoundError: 67 | try: 68 | st.info("Installing ipynb-py-convert...") 69 | subprocess.run(["pip", "install", "ipynb-py-convert"], check=True) 70 | return True 71 | except subprocess.CalledProcessError: 72 | st.error("Failed to install ipynb-py-convert. Please make sure you have pip installed and try again.") 73 | return False 74 | 75 | def convert_ipynb_to_py(input_path, output_path): 76 | """Convert .ipynb file to .py file using ipynb-py-convert.""" 77 | try: 78 | result = subprocess.run( 79 | ["ipynb-py-convert", input_path, output_path], 80 | capture_output=True, 81 | text=True, 82 | check=True 83 | ) 84 | return True, result.stdout 85 | except subprocess.CalledProcessError as e: 86 | return False, f"Error converting file: {e.stderr}" 87 | 88 | def download_file_from_url(url, temp_dir): 89 | """Download a file from URL and save it to a temporary directory.""" 90 | try: 91 | response = requests.get(url, stream=True) 92 | response.raise_for_status() 93 | 94 | # Get filename from URL or generate one if not available 95 | parsed_url = urlparse(url) 96 | filename = os.path.basename(parsed_url.path) 97 | if not filename or '.' not in filename: 98 | filename = f"downloaded_notebook_{uuid.uuid4().hex}.ipynb" 99 | elif not filename.endswith('.ipynb'): 100 | filename = f"{filename}.ipynb" 101 | 102 | file_path = os.path.join(temp_dir, filename) 103 | 104 | with open(file_path, 'wb') as f: 105 | for chunk in response.iter_content(chunk_size=8192): 106 | f.write(chunk) 107 | 108 | return True, file_path, filename 109 | except Exception as e: 110 | return False, str(e), None 111 | 112 | def create_download_link(file_path, filename): 113 | """Create a download link for the converted file.""" 114 | with open(file_path, "rb") as file: 115 | contents = file.read() 116 | b64 = base64.b64encode(contents).decode() 117 | href = f'Download Converted File' 118 | return href 119 | 120 | def create_zip_download_link(zip_path): 121 | """Create a download link for the zip file containing multiple converted files.""" 122 | with open(zip_path, "rb") as file: 123 | contents = file.read() 124 | b64 = base64.b64encode(contents).decode() 125 | href = f'Download All Converted Files' 126 | return href 127 | 128 | def main(): 129 | st.markdown('