Skip to content

Commit 4b0c23c

Browse files
committed
wip
1 parent 653fcde commit 4b0c23c

File tree

4 files changed

+229
-0
lines changed

4 files changed

+229
-0
lines changed

scripts/__init__.py

Whitespace-only changes.

scripts/populate_tox/__init__.py

Whitespace-only changes.
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import configparser
2+
import functools
3+
from datetime import datetime, timedelta
4+
from pathlib import Path
5+
6+
import requests
7+
8+
# XXX FIX THIS
9+
# from ..scripts.split_tox_gh_actions.split_tox_gh_actions import GROUPS
10+
11+
12+
GROUPS = {
13+
"Common": [
14+
"common",
15+
],
16+
"AI": [
17+
"anthropic",
18+
"cohere",
19+
"langchain",
20+
"openai",
21+
"huggingface_hub",
22+
],
23+
"AWS": [
24+
# this is separate from Cloud Computing because only this one test suite
25+
# needs to run with access to GitHub secrets
26+
"aws_lambda",
27+
],
28+
"Cloud": [
29+
"boto3",
30+
"chalice",
31+
"cloud_resource_context",
32+
"gcp",
33+
],
34+
"Tasks": [
35+
"arq",
36+
"beam",
37+
"celery",
38+
"dramatiq",
39+
"huey",
40+
"ray",
41+
"rq",
42+
"spark",
43+
],
44+
"DBs": [
45+
"asyncpg",
46+
"clickhouse_driver",
47+
"pymongo",
48+
"redis",
49+
"redis_py_cluster_legacy",
50+
"sqlalchemy",
51+
],
52+
"GraphQL": [
53+
"ariadne",
54+
"gql",
55+
"graphene",
56+
"strawberry",
57+
],
58+
"Network": [
59+
"gevent",
60+
"grpc",
61+
"httpx",
62+
"requests",
63+
],
64+
"Web 1": [
65+
"django",
66+
"flask",
67+
"starlette",
68+
"fastapi",
69+
],
70+
"Web 2": [
71+
"aiohttp",
72+
"asgi",
73+
"bottle",
74+
"falcon",
75+
"litestar",
76+
"pyramid",
77+
"quart",
78+
"sanic",
79+
"starlite",
80+
"tornado",
81+
],
82+
"Misc": [
83+
"launchdarkly",
84+
"loguru",
85+
"openfeature",
86+
"opentelemetry",
87+
"potel",
88+
"pure_eval",
89+
"trytond",
90+
"typer",
91+
],
92+
}
93+
94+
# Only consider package versions going back this far
95+
CUTOFF = datetime.now() - timedelta(days=365 * 3)
96+
LOWEST_SUPPORTED_PY_VERSION = "3.6"
97+
98+
TOX_FILE = Path(__file__).resolve().parent.parent.parent / "tox.ini"
99+
100+
PYPI_PROJECT_URL = "https://pypi.python.org/pypi/{project}/json"
101+
PYPI_VERSION_URL = "https://pypi.python.org/pypi/{project}/{version}/json"
102+
103+
EXCLUDE = {
104+
"common",
105+
}
106+
107+
packages = {}
108+
109+
110+
@functools.total_ordering
111+
class Version:
112+
def __init__(self, version, metadata):
113+
self.raw = version
114+
self.metadata = metadata
115+
116+
self.major = None
117+
self.minor = None
118+
self.patch = None
119+
self.parsed = None
120+
121+
try:
122+
parsed = version.split(".")
123+
if parsed[2].isnumeric():
124+
self.major, self.minor, self.patch = (int(p) for p in parsed)
125+
except Exception:
126+
# This will fail for e.g. prereleases, but we don't care about those
127+
# for now
128+
pass
129+
130+
self.parsed = (self.major, self.minor, self.patch or 0)
131+
132+
@property
133+
def valid(self):
134+
return self.major is not None and self.minor is not None
135+
136+
def __str__(self):
137+
return self.raw
138+
139+
def __repr__(self):
140+
return self.raw
141+
142+
def __eq__(self, other):
143+
return self.parsed == other.parsed
144+
145+
def __lt__(self, other):
146+
return self.parsed < other.parsed
147+
148+
149+
def parse_tox():
150+
config = configparser.ConfigParser()
151+
config.read(TOX_FILE)
152+
lines = [
153+
line
154+
for line in config["tox"]["envlist"].split("\n")
155+
if line.strip() and not line.strip().startswith("#")
156+
]
157+
158+
for line in lines:
159+
# normalize lines
160+
line = line.strip().lower()
161+
162+
try:
163+
# parse tox environment definition
164+
try:
165+
(raw_python_versions, framework, framework_versions) = line.split("-")
166+
except ValueError:
167+
(raw_python_versions, framework) = line.split("-")
168+
framework_versions = []
169+
170+
framework_versions
171+
packages[framework] = {}
172+
173+
# collect python versions to test the framework in
174+
raw_python_versions = set(
175+
raw_python_versions.replace("{", "").replace("}", "").split(",")
176+
)
177+
178+
except ValueError:
179+
print(f"ERROR reading line {line}")
180+
181+
182+
def fetch_metadata(package):
183+
url = PYPI_PROJECT_URL.format(project=package)
184+
pypi_data = requests.get(url)
185+
186+
if pypi_data.status_code != 200:
187+
print(f"{package} not found")
188+
189+
import pprint
190+
191+
pprint.pprint(package)
192+
pprint.pprint(pypi_data.json())
193+
return pypi_data.json()
194+
195+
196+
def parse_metadata(data):
197+
package = data["info"]["name"]
198+
199+
majors = {}
200+
201+
for release, metadata in data["releases"].items():
202+
meta = metadata[0]
203+
if datetime.fromisoformat(meta["upload_time"]) < CUTOFF:
204+
continue
205+
206+
version = Version(release, meta)
207+
if not version.valid:
208+
print(f"Failed to parse version {release} of package {package}")
209+
continue
210+
211+
if version.major not in majors:
212+
# 0 -> [min 0.x version, max 0.x version]
213+
majors[version.major] = [version, version]
214+
continue
215+
216+
if version < majors[version.major][0]:
217+
majors[version.major][0] = version
218+
if version > majors[version.major][1]:
219+
majors[version.major][1] = version
220+
221+
print(release, "not too old", meta["upload_time"])
222+
223+
return majors
224+
225+
226+
print(parse_tox())
227+
print(packages)
228+
print(parse_metadata(fetch_metadata("celery")))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests

0 commit comments

Comments
 (0)