Skip to content

Instantly share code, notes, and snippets.

@DavidLutton
Last active May 26, 2020 11:51
Show Gist options
  • Save DavidLutton/ca1aed5292faba67cfdf2a6fc879fab2 to your computer and use it in GitHub Desktop.
Save DavidLutton/ca1aed5292faba67cfdf2a6fc879fab2 to your computer and use it in GitHub Desktop.
Create venv and config for Python / VS Code
import fileinput
import os
import venv
from pathlib import Path
# venvtarget = Path('.').resolve().name.replace(' ', '_')
# header = Path(venvtarget / 'Scripts/python.exe').as_posix()
# print(header)
venvtarget = Path(f'.venv')
print(venvtarget)
if not venvtarget.is_dir():
builder = venv.EnvBuilder(
system_site_packages=False,
clear=False,
symlinks=False,
upgrade=True,
with_pip=True
)
print(f'Creating new venv in: {venvtarget}')
builder.create(venvtarget)
print(f'New venv created in: {venvtarget}')
else:
print(f'venv exists in: {venvtarget}')
Path('venv_install.py').write_text("""#! template/Scripts/python.exe
import subprocess
import sys
import shlex
import time
from pprint import pprint
from pathlib import Path
from datetime import datetime
now = datetime.now().isoformat()[0:10] # Date
sequence = [
f'-m pip install --upgrade pip setuptools wheel',
f'-m pip install --upgrade -r requirements.txt',
# f'-m pip freeze',
]
try:
print(sys.executable)
for line in sequence:
print()
print(line)
process = subprocess.Popen([sys.executable] + shlex.split(line), stdout=subprocess.PIPE)
while True:
output = process.stdout.readline()
if output == b'' and process.poll() is not None:
break
if output:
print(output.strip().decode())
rc = process.poll()
# https://stackoverflow.com/a/50255019
run = subprocess.run([sys.executable] + shlex.split('-m pip freeze'), capture_output=True)
# pprint(run)
# print(run.stdout)
Path(f'./requirements_freeze_{now}.txt').write_bytes(run.stdout)
except subprocess.CalledProcessError as e:
print(e, run)
input('Done, Press enter to close.')
""")
Path('venv_main_template.py').write_text('#! template/Scripts/python.exe\n')
for line in fileinput.input([Path('venv_main_template.py'), Path('venv_install.py')], inplace=True):
print(line.replace('template', venvtarget.name), end='')
requirements = Path('requirements.txt')
if not requirements.exists():
requirements.write_text('pylint\npycodestyle\npydocstyle\nipykernel')
else:
requirements.touch()
Path('.vscode').mkdir(exist_ok=True)
vscodesettings = Path('.vscode/settings.json')
if not vscodesettings.exists():
vscodesettings.write_text("""{
"python.linting.pylintEnabled": true,
"python.linting.pycodestyleEnabled": true,
"python.linting.pydocstyleEnabled": true,
"python.linting.enabled": true
}""")
setupcfg = Path('setup.cfg')
if not setupcfg.exists():
setupcfg.write_text("""
[pycodestyle]
max-line-length = 160
[pydocstyle]
add-ignore = D100
""")
input('Done, Press enter to close.')
@DavidLutton
Copy link
Author

DavidLutton commented May 24, 2020

Hello

In the directory you want the code to live in:
Download and run this Gist

This creates a bunch of files
Then run venv_install which installs the Python modules listed in requirements.txt
You can use venv_install again later to install additional modules when you want
If you want to pin dependencies copy requirements_freeze_~date.txt over requirements.txt

Install the VS Code Python extension
Open directory in VS Code

Then create a notebook
Notebooks are particularly useful for exploratory development, as cells of code can be run by pressing ctrl-enter

Python launcher parses shebang-lines to decide what environment to run the program in, this avoids having to use .bat or powershell files to launch Python programs
Use venv_main_template as the #! header for programs

@DavidLutton
Copy link
Author

DavidLutton commented May 24, 2020

To run a module for example pytest and pytest-html
Copy venv_main_template to run_pytest and add to end of the #!
-m pytest --html=report.html --self-contained-html .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment