├── tests └── __init__.py ├── requirements.txt ├── deepgram_cli ├── version.py ├── __init__.py ├── utils.py ├── app.py ├── cli.py ├── constants.py └── deepgram_cli.py ├── requirements-dev.txt ├── .github ├── ISSUE_TEMPLATE.md └── workflows │ └── continuous-integration-publish.yml ├── .pre-commit-config.yaml ├── LICENSE ├── setup.py ├── README.md ├── Makefile └── .gitignore /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | deepgram-sdk 2 | requests 3 | -------------------------------------------------------------------------------- /deepgram_cli/version.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.0.2" 2 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pre-commit 2 | python-dotenv 3 | wheel 4 | -------------------------------------------------------------------------------- /deepgram_cli/__init__.py: -------------------------------------------------------------------------------- 1 | """Top-level package for Snapchat Downloader.""" 2 | 3 | __author__ = """Aakash Gajjar""" 4 | __email__ = "skyqutip@gmail.com" 5 | 6 | from deepgram_cli.deepgram_cli import DeepgramCLI 7 | 8 | __all__ = ["DeepgramCLI"] 9 | -------------------------------------------------------------------------------- /deepgram_cli/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def get_ext(filepth): 5 | _, ext = os.path.splitext(filepth) 6 | return ext 7 | 8 | 9 | def save_file(data, filepath): 10 | with open(filepath, "w") as f: 11 | f.write(data) 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * Deepgram CLI version: 2 | * Python version: 3 | * Operating System: 4 | 5 | ### Description 6 | 7 | Describe what you were trying to get done. 8 | Tell us what happened, what went wrong, and what you expected to happen. 9 | 10 | ### What I Did 11 | 12 | ``` 13 | Paste the command(s) you ran and the output. 14 | If there was a crash, please include the traceback here. 15 | ``` 16 | -------------------------------------------------------------------------------- /deepgram_cli/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from ast import dump 4 | 5 | from deepgram import Deepgram 6 | 7 | from deepgram_cli.cli import parse_arguments 8 | from deepgram_cli.deepgram_cli import DeepgramCLI 9 | 10 | 11 | def main(): 12 | """Download transcripts from Deepgram.""" 13 | args = parse_arguments() 14 | 15 | dg_client = Deepgram(os.getenv("DEEPGRAM_API_KEY")) 16 | 17 | batch_file = [] 18 | if args.batch_file and os.path.isfile(args.batch_file): 19 | with open(args.batch_file, "r") as f: 20 | batch_file = f.read().split("\n") 21 | 22 | app = DeepgramCLI( 23 | urls=args.urls, 24 | files=args.files, 25 | dump_json=args.dump_json, 26 | batch_list=batch_file, 27 | dg=dg_client, 28 | ) 29 | app.run() 30 | 31 | 32 | if __name__ == "__main__": 33 | print(23) 34 | sys.exit(main()) 35 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v2.4.0 6 | hooks: 7 | - id: check-added-large-files 8 | - id: check-yaml 9 | - id: detect-private-key 10 | - id: end-of-file-fixer 11 | - id: requirements-txt-fixer 12 | - id: trailing-whitespace 13 | - repo: https://github.com/asottile/reorder_python_imports 14 | rev: v2.3.0 15 | hooks: 16 | - id: reorder-python-imports 17 | - repo: https://github.com/psf/black 18 | rev: 19.10b0 19 | hooks: 20 | - id: black 21 | - repo: https://github.com/asottile/blacken-docs 22 | rev: v1.7.0 23 | hooks: 24 | - id: blacken-docs 25 | additional_dependencies: [black==19.10b0] 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022, Aakash Gajjar 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 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration-publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python-version: [3.8] 15 | environment: production 16 | 17 | steps: 18 | - uses: actions/cache@v2 19 | with: 20 | path: ~/.cache/pip 21 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 22 | restore-keys: | 23 | ${{ runner.os }}-pip- 24 | - uses: actions/checkout@v2 25 | - name: Set up Python ${{ matrix.python-version }} 26 | uses: actions/setup-python@v2 27 | with: 28 | python-version: ${{ matrix.python-version }} 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install setuptools 33 | pip install wheel 34 | pip install twine 35 | - name: Build and publish 36 | env: 37 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 38 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 39 | run: | 40 | python setup.py sdist bdist_wheel 41 | twine upload dist/* 42 | -------------------------------------------------------------------------------- /deepgram_cli/cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | 4 | 5 | def parse_arguments(): 6 | """Console script for deepgram_cli.""" 7 | parser = argparse.ArgumentParser(prog="deepgram-cli") 8 | 9 | any_one_group = parser.add_mutually_exclusive_group() 10 | 11 | any_one_group.add_argument( 12 | "-f", 13 | "--file", 14 | action="store", 15 | nargs="*", 16 | help="At least one or more audio file path to transcribe.", 17 | dest="files", 18 | default=[], 19 | ) 20 | 21 | any_one_group.add_argument( 22 | "-u", 23 | "--url", 24 | action="store", 25 | nargs="*", 26 | help="At least one or more urls to transcribe.", 27 | dest="urls", 28 | default=[], 29 | ) 30 | 31 | any_one_group.add_argument( 32 | "-i", 33 | "--batch-file", 34 | action="store", 35 | help="Read files/orls from batch file (one per line).", 36 | metavar="BATCH_FILENAME", 37 | dest="batch_file", 38 | default=None, 39 | ) 40 | 41 | parser.add_argument( 42 | "-d", 43 | "--dump-json", 44 | action="store_true", 45 | help="Save metadata to a JSON file.", 46 | dest="dump_json", 47 | ) 48 | 49 | parser.add_argument( 50 | "-q", 51 | "--quiet", 52 | action="store_true", 53 | help="Do not print anything except errors to the console.", 54 | ) 55 | 56 | if len(sys.argv) == 1: 57 | parser.print_help() 58 | sys.exit(1) 59 | 60 | return parser.parse_args() 61 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """The setup script.""" 3 | from setuptools import find_packages 4 | from setuptools import setup 5 | 6 | 7 | version = {} 8 | with open("deepgram_cli/version.py") as fp: 9 | exec(fp.read(), version) 10 | 11 | with open("README.md") as readme_file: 12 | readme = readme_file.read() 13 | 14 | requirements = list() 15 | 16 | with open("requirements.txt", "r") as file: 17 | requirements = [r for r in file.readlines() if len(r) > 0] 18 | 19 | test_requirements = ["pytest"].extend(requirements) 20 | 21 | setup( 22 | name="deepgram-cli", 23 | version=version["__version__"], 24 | description="deepgram cli for bulk transcribing files.", 25 | long_description=readme, 26 | long_description_content_type="text/markdown", 27 | url="https://github.com/skyme5/deepgram-cli", 28 | author="Aakash Gajjar", 29 | author_email="skyqutip@gmail.com", 30 | entry_points={"console_scripts": ["deepgram-cli=deepgram_cli.app:main",],}, 31 | include_package_data=True, 32 | install_requires=requirements, 33 | test_suite="tests", 34 | tests_require=test_requirements, 35 | python_requires=">=3.5", 36 | keywords="deepgram-cli", 37 | license="MIT license", 38 | packages=find_packages(include=["deepgram_cli", "deepgram_cli.*"]), 39 | zip_safe=False, 40 | classifiers=[ 41 | "Development Status :: 5 - Production/Stable", 42 | "Environment :: Console", 43 | "Intended Audience :: Developers", 44 | "Intended Audience :: End Users/Desktop", 45 | "License :: OSI Approved :: MIT License", 46 | "Natural Language :: English", 47 | "Programming Language :: Python :: 3", 48 | ], 49 | ) 50 | -------------------------------------------------------------------------------- /deepgram_cli/constants.py: -------------------------------------------------------------------------------- 1 | AUDIO_MAPPINGS = { 2 | ".aa": "audio/audible", 3 | ".aac": "audio/aac", 4 | ".aax": "audio/vnd.audible.aax", 5 | ".ac3": "audio/ac3", 6 | ".adt": "audio/vnd.dlna.adts", 7 | ".adts": "audio/aac", 8 | ".aif": "audio/aiff", 9 | ".aifc": "audio/aiff", 10 | ".aiff": "audio/aiff", 11 | ".au": "audio/basic", 12 | ".axa": "audio/annodex", 13 | ".caf": "audio/x-caf", 14 | ".cdda": "audio/aiff", 15 | ".flac": "audio/flac", 16 | ".gsm": "audio/x-gsm", 17 | ".m3u": "audio/x-mpegurl", 18 | ".m3u8": "audio/x-mpegurl", 19 | ".m4a": "audio/m4a", 20 | ".m4b": "audio/m4b", 21 | ".m4p": "audio/m4p", 22 | ".m4r": "audio/x-m4r", 23 | ".mid": "audio/mid", 24 | ".midi": "audio/mid", 25 | ".mka": "audio/x-matroska", 26 | ".mp3": "audio/mpeg", 27 | ".oga": "audio/ogg", 28 | ".ogg": "audio/ogg", 29 | ".opus": "audio/ogg", 30 | ".pls": "audio/scpls", 31 | ".ra": "audio/x-pn-realaudio", 32 | ".ram": "audio/x-pn-realaudio", 33 | ".rmi": "audio/mid", 34 | ".rpm": "audio/x-pn-realaudio-plugin", 35 | ".sd2": "audio/x-sd2", 36 | ".smd": "audio/x-smd", 37 | ".smx": "audio/x-smd", 38 | ".smz": "audio/x-smd", 39 | ".snd": "audio/basic", 40 | ".spx": "audio/ogg", 41 | ".wav": "audio/wav", 42 | ".wave": "audio/wav", 43 | ".wax": "audio/x-ms-wax", 44 | ".wma": "audio/x-ms-wma", 45 | "audio/aac": ".aac", 46 | "audio/aiff": ".aiff", 47 | "audio/basic": ".snd", 48 | "audio/mid": ".midi", 49 | "audio/mp4": ".m4a", 50 | "audio/wav": ".wav", 51 | "audio/x-m4a": ".m4a", 52 | "audio/x-mpegurl": ".m3u", 53 | "audio/x-pn-realaudio": ".ra", 54 | "audio/x-smd": ".smd", 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
49 | 50 | 51 | 52 | ## Installation 53 | 54 | ``` 55 | pip install git+https://github.com/skyme5/deepgram-cli.git 56 | ``` 57 | 58 | Also set your `DEEPGRAM_API_KEY` for it to work. 59 | 60 | ## Usage 61 | 62 | ```bash 63 | usage: deepgram-cli [-h] [-f [FILES ...] | -u [URLS ...] | -i BATCH_FILENAME] [-d] [-q] 64 | 65 | options: 66 | -h, --help show this help message and exit 67 | -f [FILES ...], --file [FILES ...] 68 | At least one or more audio file path to transcribe. 69 | -u [URLS ...], --url [URLS ...] 70 | At least one or more urls to transcribe. 71 | -i BATCH_FILENAME, --batch-file BATCH_FILENAME 72 | Read files/orls from batch file (one per line). 73 | -d, --dump-json Save metadata to a JSON file. 74 | -q, --quiet Do not print anything except errors to the console. 75 | ``` 76 | 77 | # License 78 | 79 | MIT 80 | -------------------------------------------------------------------------------- /deepgram_cli/deepgram_cli.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import json 3 | import os 4 | import platform 5 | import re 6 | 7 | from deepgram import Deepgram 8 | 9 | from deepgram_cli.constants import AUDIO_MAPPINGS 10 | from deepgram_cli.utils import get_ext 11 | from deepgram_cli.utils import save_file 12 | 13 | 14 | if platform.system() == "Windows": 15 | asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) 16 | 17 | 18 | class DeepgramCLI: 19 | """_summary_ 20 | 21 | Returns: 22 | _type_: _description_ 23 | """ 24 | 25 | def __init__( 26 | self, urls: list, files: list, dump_json: bool, batch_list: list, dg: Deepgram 27 | ) -> None: 28 | self.dg = dg 29 | self.urls = urls 30 | self.files = files 31 | self.dump_json = dump_json 32 | self.batch_list = batch_list 33 | self.loop = asyncio.get_event_loop() 34 | 35 | async def remote(self, url): 36 | file_path = url.split("?")[0].split("/")[-1] 37 | source = {"url": url} 38 | options = {"punctuate": True, "language": "en-US"} 39 | 40 | response = await self.dg.transcription.prerecorded(source, options) 41 | max_confidence_result = response.get("results").get("channels")[0][0] 42 | save_file(max_confidence_result["transcript"], f"{file_path}.txt") 43 | if self.dump_json: 44 | save_file(json.dumps(response), f"{file_path}.txt") 45 | 46 | async def local(self, file_path): 47 | with open(file_path, "rb") as audio: 48 | source = {"buffer": audio, "mimetype": AUDIO_MAPPINGS[get_ext(file_path)]} 49 | options = {"punctuate": True, "language": "en-US"} 50 | 51 | response = await self.dg.transcription.prerecorded(source, options) 52 | max_confidence_result = response.get("results").get("channels")[0][ 53 | "alternatives" 54 | ][0] 55 | save_file(max_confidence_result["transcript"], f"{file_path}.txt") 56 | 57 | if self.dump_json: 58 | save_file(json.dumps(response), f"{file_path}.txt") 59 | 60 | async def process(self): 61 | for file_path in self.files: 62 | await self.local(file_path) 63 | 64 | for url in self.urls: 65 | await self.remote(url) 66 | 67 | for f in self.batch_list: 68 | if re.match(r"^http", f): 69 | await self.remote(f) 70 | else: 71 | await self.local(f) 72 | 73 | def run(self): 74 | return self.loop.run_until_complete(self.process()) 75 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean clean-test clean-pyc clean-build docs help 2 | .DEFAULT_GOAL := help 3 | 4 | define BROWSER_PYSCRIPT 5 | import os, webbrowser, sys 6 | 7 | from urllib.request import pathname2url 8 | 9 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 10 | endef 11 | export BROWSER_PYSCRIPT 12 | 13 | define PRINT_HELP_PYSCRIPT 14 | import re, sys 15 | 16 | for line in sys.stdin: 17 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 18 | if match: 19 | target, help = match.groups() 20 | print("%-20s %s" % (target, help)) 21 | endef 22 | export PRINT_HELP_PYSCRIPT 23 | 24 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 25 | 26 | help: 27 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 28 | 29 | clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts 30 | 31 | clean-build: ## remove build artifacts 32 | rm -fr build/ 33 | rm -fr dist/ 34 | rm -fr .eggs/ 35 | find . -name '*.egg-info' -exec rm -fr {} + 36 | find . -name '*.egg' -exec rm -rf {} + 37 | 38 | clean-pyc: ## remove Python file artifacts 39 | find . -name '*.pyc' -exec rm -f {} + 40 | find . -name '*.pyo' -exec rm -f {} + 41 | find . -name '*~' -exec rm -f {} + 42 | find . -name '__pycache__' -exec rm -fr {} + 43 | 44 | clean-test: ## remove test and coverage artifacts 45 | rm -fr .tox/ 46 | rm -f .coverage 47 | rm -fr htmlcov/ 48 | rm -fr .pytest_cache 49 | rm -fr .test-data 50 | 51 | lint: ## check style with flake8 52 | black snapchat_dl tests 53 | 54 | test: clean-test ## run tests quickly with the default Python 55 | pytest tests --cache-clear 56 | 57 | test-all: clean-test ## run tests on every Python version with tox 58 | pytest tests --cache-clear 59 | 60 | coverage: clean-test ## check code coverage quickly with the default Python 61 | coverage run -m pytest -v tests 62 | coverage report -m --skip-covered 63 | coverage html 64 | $(BROWSER) htmlcov/index.html 65 | 66 | docs-usage: 67 | python.exe snapchat_dl/cli.py --help > USAGE.rst 68 | 69 | docs: docs-usage## generate Sphinx HTML documentation, including API docs 70 | rm -f docs/snapchat_dl.rst 71 | rm -f docs/modules.rst 72 | sphinx-apidoc -o docs/ snapchat_dl 73 | $(MAKE) -C docs clean 74 | $(MAKE) -C docs html 75 | $(BROWSER) docs/_build/html/index.html 76 | 77 | servedocs: docs ## compile the docs watching for changes 78 | watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . 79 | 80 | dist: clean ## builds source and wheel package 81 | python setup.py sdist 82 | python setup.py bdist_wheel 83 | ls -l dist 84 | 85 | install: clean ## install the package to the active Python's site-packages 86 | python setup.py install 87 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/python 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 4 | 5 | ### Python ### 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | local_settings.py 66 | db.sqlite3 67 | db.sqlite3-journal 68 | 69 | # Flask stuff: 70 | instance/ 71 | .webassets-cache 72 | 73 | # Scrapy stuff: 74 | .scrapy 75 | 76 | # Sphinx documentation 77 | docs/_build/ 78 | 79 | # PyBuilder 80 | .pybuilder/ 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | # For a library or package, you might want to ignore these files since the code is 92 | # intended to run in multiple environments; otherwise, check them in: 93 | # .python-version 94 | 95 | # pipenv 96 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 97 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 98 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 99 | # install all needed dependencies. 100 | #Pipfile.lock 101 | 102 | # poetry 103 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 104 | # This is especially recommended for binary packages to ensure reproducibility, and is more 105 | # commonly ignored for libraries. 106 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 107 | #poetry.lock 108 | 109 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 110 | __pypackages__/ 111 | 112 | # Celery stuff 113 | celerybeat-schedule 114 | celerybeat.pid 115 | 116 | # SageMath parsed files 117 | *.sage.py 118 | 119 | # Environments 120 | .env 121 | .venv 122 | env/ 123 | venv/ 124 | ENV/ 125 | env.bak/ 126 | venv.bak/ 127 | 128 | # Spyder project settings 129 | .spyderproject 130 | .spyproject 131 | 132 | # Rope project settings 133 | .ropeproject 134 | 135 | # mkdocs documentation 136 | /site 137 | 138 | # mypy 139 | .mypy_cache/ 140 | .dmypy.json 141 | dmypy.json 142 | 143 | # Pyre type checker 144 | .pyre/ 145 | 146 | # pytype static type analyzer 147 | .pytype/ 148 | 149 | # Cython debug symbols 150 | cython_debug/ 151 | 152 | # PyCharm 153 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 154 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 155 | # and can be added to the global gitignore or merged into this file. For a more nuclear 156 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 157 | #.idea/ 158 | 159 | # End of https://www.toptal.com/developers/gitignore/api/python 160 | --------------------------------------------------------------------------------