Skip to content

Instantly share code, notes, and snippets.

@rsiemens
Created May 1, 2024 16:39
Show Gist options
  • Save rsiemens/7b37af435cdefc845e58c3ab3e2d32db to your computer and use it in GitHub Desktop.
Save rsiemens/7b37af435cdefc845e58c3ab3e2d32db to your computer and use it in GitHub Desktop.
import requests
from queue import Queue
from collections import defaultdict
from pkg_resources import Requirement
META_URL = 'https://pypi.org/pypi/{req}/json'
class Digraph:
def __init__(self):
self.graph = defaultdict(set)
def add_edge(self, source, to):
self.graph[source].add(to)
def vertices(self):
return len(self.graph)
def edges(self):
total = 0
for k in self.graph:
total += len(self.graph[k])
return total
def adj(self, vert):
return self.graph[vert]
class BreadthFirstGraphBuilder:
def __init__(self, req):
self.req = req
self.visited = set()
self.digraph = Digraph()
def build(self):
self._bfs(self.req)
self.visited = set()
self._display(self.req)
def _display(self, req, depth=0):
self.visited.add(req)
print((" " * depth) + req)
for adj in self.digraph.adj(req):
if adj not in self.visited:
self._display(adj, depth=depth+1)
def _bfs(self, req):
q = Queue()
q.put(req)
self.visited.add(req)
while not q.empty():
n = q.get()
self._visit(n)
for adj in self.digraph.adj(n):
if adj not in self.visited:
self.visited.add(adj)
q.put(adj)
def _visit(self, req):
meta = self._get_meta(req)
deps = self._get_reqs(meta)
for dep in deps:
self.digraph.add_edge(req, dep)
def _get_meta(self, req):
url = META_URL.format(req=req)
res = requests.get(url)
res.raise_for_status()
return res.json()
def _get_reqs(self, meta):
ver_reqs = meta['info']['requires_dist']
fixed_reqs = []
if ver_reqs:
for r in ver_reqs:
p = Requirement.parse(r)
if p.marker and not p.marker.evaluate({'extra': None}):
continue
else:
fixed_reqs.append(p.name)
return fixed_reqs
if __name__ == '__main__':
import sys
req = sys.argv[1]
builder = BreadthFirstGraphBuilder(req)
builder.build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment