Skip to content

Instantly share code, notes, and snippets.

@chrnmaxim
Created September 13, 2024 12:55
Show Gist options
  • Select an option

  • Save chrnmaxim/4f0cc4dcf41b2b69cf68f0bc2b4abbff to your computer and use it in GitHub Desktop.

Select an option

Save chrnmaxim/4f0cc4dcf41b2b69cf68f0bc2b4abbff to your computer and use it in GitHub Desktop.
Convert a requirements.txt file to a Poetry project. This is enhanced version of tigerhawkvok/poetry-convert.py
#!python3
"""
Convert a requirements.txt file to a Poetry project.
Place in the directory with `requirements.txt` file and run.
"""
import os
import re
import subprocess
from os.path import abspath, dirname
requirements_file: str = f"{(dirname(abspath(__file__)))}/requirements.txt"
# Initialize Poetry if it doesn't yet have a pyproject.toml file
if not os.path.exists(f"{(dirname(abspath(__file__)))}/pyproject.toml"):
os.system("poetry init")
with open(requirements_file) as fh:
requirements = fh.read()
no_comments: str = re.sub("^#.*$", "", requirements, 0, re.IGNORECASE | re.MULTILINE)
clean_requirements: str = re.sub(
"\n+", "\n", no_comments, 0, re.IGNORECASE | re.MULTILINE
).strip()
pip_poetry_map = {">": "^", "=": ""}
dependencies = []
for line in clean_requirements.splitlines():
# For lines such as `package==1.0.0`:
if re.match(r".*==.*", line):
package, match, version = re.sub(
pattern=r"^(.*?)\s*([~>=<])=\s*v?([0-9\.\*]+)",
repl=r"\1,\2,\3",
string=line,
count=0,
flags=re.IGNORECASE | re.MULTILINE,
).split(",")
try:
poetryMatch = pip_poetry_map[match]
except KeyError:
poetryMatch = match
poetryLine = f"{package}"
dependencies.append(poetryLine)
# For lines such as `package @ git+https://github.com/`
elif re.match(r".*@\s*git\+https?://", line):
url = re.sub(r".*git\+\s*", "", line).split()
poetryLine = f"git+{url[0]}"
dependencies.append(poetryLine)
# For lines such as `package @ https://github.com/`
elif re.match(r".*@\s*https?://", line):
package, url = re.sub(r"\s*@\s*", "git@ ", line).split()
poetryLine = f"git@{url}"
dependencies.append(poetryLine)
# For other lines, e.g. packages without version
else:
dependencies.append(line)
with open("poetry_dependencies.txt", "w") as file:
for dependency in dependencies:
file.write(dependency + "\n")
print("Found Poetry-compatible dependencies:")
with open("poetry_dependencies.txt", "r") as file:
dependencies = file.read().splitlines()
subprocess.call(["poetry", "add"] + dependencies)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment