Skip to content

Commit be65a8b

Browse files
committed
Standardize Python 3.11 with uv
1 parent e4eaac4 commit be65a8b

9 files changed

Lines changed: 1043 additions & 24 deletions

File tree

.devcontainer/devcontainer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
]
1818
}
1919
},
20-
"updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y <packages.txt; [ -f requirements.txt ] && pip3 install --user -r requirements.txt; pip3 install --user streamlit; echo '✅ Packages installed and Requirements met'",
20+
"updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo xargs apt install -y <packages.txt; python3 -m pip install --user uv; [ -f pyproject.toml ] && ~/.local/bin/uv sync --python 3.11; [ -f pyproject.toml ] && ~/.local/bin/uv run playwright install chromium; echo '✅ uv environment synced'",
2121
"postAttachCommand": {
22-
"server": "streamlit run app.py --server.enableCORS false --server.enableXsrfProtection false"
22+
"server": "~/.local/bin/uv run streamlit run app.py --server.enableCORS false --server.enableXsrfProtection false"
2323
},
2424
"portsAttributes": {
2525
"8501": {

.github/workflows/ci.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v5
16+
1417
- name: Check out repository
1518
uses: actions/checkout@v4
1619

1720
- name: Set up Python
1821
uses: actions/setup-python@v5
1922
with:
20-
python-version: "3.11"
23+
python-version-file: ".python-version"
2124

22-
- name: Install dependencies
25+
- name: Sync dependencies
2326
run: |
24-
python -m pip install --upgrade pip
25-
pip install -r requirements.txt
27+
uv sync --frozen
2628
2729
- name: Run unit tests
2830
run: |
29-
python -m unittest tests.test_analysis_store tests.test_report_builder tests.test_exporters tests.test_repo_checks tests.test_github_auth tests.test_github_client tests.test_openai_service
31+
uv run python -m unittest tests.test_analysis_store tests.test_report_builder tests.test_exporters tests.test_repo_checks tests.test_github_auth tests.test_github_client tests.test_openai_service

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

DEVLOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ This log tracks the major implementation milestones for the current modular Stre
44

55
---
66

7+
## March 13, 2026 - Python 3.11 and uv Environment Standardization
8+
9+
Standardized local development and CI around a reproducible Python toolchain:
10+
11+
- added `pyproject.toml` so direct dependencies are declared in one place
12+
- targeted Python `3.11` explicitly with a tracked `.python-version`
13+
- switched CI to `uv sync --frozen` and `uv run`
14+
- updated the devcontainer bootstrap flow to sync dependencies with uv
15+
- prepared the repository for a pinned `requirements.txt` exported from the uv lockfile
16+
717
## March 7, 2026 - Modular Audit Pipeline
818

919
Implemented the current application architecture:

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,20 +183,21 @@ Module responsibilities:
183183

184184
## Setup
185185

186-
### 1. Create and activate a virtual environment
186+
### 1. Install uv and Python 3.11
187187

188188
```powershell
189-
python -m venv venv
190-
venv\Scripts\activate
189+
uv python install 3.11
191190
```
192191

193-
### 2. Install dependencies
192+
### 2. Sync the project environment
194193

195194
```powershell
196-
pip install -r requirements.txt
197-
venv\Scripts\python.exe -m playwright install chromium
195+
uv sync --python 3.11
196+
uv run playwright install chromium
198197
```
199198

199+
This project now targets Python `3.11` explicitly via [`.python-version`](.python-version) and [pyproject.toml](pyproject.toml). The checked-in `requirements.txt` is an exported, pinned snapshot of the uv lockfile for reproducible installs.
200+
200201
### 3. Add credentials
201202

202203
Create these files in the project root as needed:
@@ -233,7 +234,7 @@ OAuth scope default:
233234
## Running the App
234235

235236
```powershell
236-
streamlit run app.py
237+
uv run streamlit run app.py
237238
```
238239

239240
Then:

pyproject.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[project]
2+
name = "github-portfolio-reviewer-agent"
3+
version = "0.1.0"
4+
description = "Streamlit app for auditing GitHub repositories and portfolios."
5+
readme = "README.md"
6+
requires-python = ">=3.11,<3.12"
7+
dependencies = [
8+
"markdown-it-py",
9+
"openai",
10+
"playwright",
11+
"reportlab",
12+
"requests",
13+
"streamlit",
14+
]
15+
16+
[tool.uv]
17+
package = false

requirements.txt

Lines changed: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,154 @@
1-
openai
2-
requests
3-
streamlit
4-
reportlab==3.6.12
5-
markdown-it-py
6-
playwright
7-
1+
# This file was autogenerated by uv via the following command:
2+
# uv export --format requirements-txt --no-hashes -o requirements.txt
3+
altair==6.0.0
4+
# via streamlit
5+
annotated-types==0.7.0
6+
# via pydantic
7+
anyio==4.12.1
8+
# via
9+
# httpx
10+
# openai
11+
attrs==25.4.0
12+
# via
13+
# jsonschema
14+
# referencing
15+
blinker==1.9.0
16+
# via streamlit
17+
cachetools==7.0.5
18+
# via streamlit
19+
certifi==2026.2.25
20+
# via
21+
# httpcore
22+
# httpx
23+
# requests
24+
charset-normalizer==3.4.5
25+
# via
26+
# reportlab
27+
# requests
28+
click==8.3.1
29+
# via streamlit
30+
colorama==0.4.6 ; sys_platform == 'win32'
31+
# via
32+
# click
33+
# tqdm
34+
distro==1.9.0
35+
# via openai
36+
gitdb==4.0.12
37+
# via gitpython
38+
gitpython==3.1.46
39+
# via streamlit
40+
greenlet==3.3.2
41+
# via playwright
42+
h11==0.16.0
43+
# via httpcore
44+
httpcore==1.0.9
45+
# via httpx
46+
httpx==0.28.1
47+
# via openai
48+
idna==3.11
49+
# via
50+
# anyio
51+
# httpx
52+
# requests
53+
jinja2==3.1.6
54+
# via
55+
# altair
56+
# pydeck
57+
jiter==0.13.0
58+
# via openai
59+
jsonschema==4.26.0
60+
# via altair
61+
jsonschema-specifications==2025.9.1
62+
# via jsonschema
63+
markdown-it-py==4.0.0
64+
# via github-portfolio-reviewer-agent
65+
markupsafe==3.0.3
66+
# via jinja2
67+
mdurl==0.1.2
68+
# via markdown-it-py
69+
narwhals==2.18.0
70+
# via altair
71+
numpy==2.4.3
72+
# via
73+
# pandas
74+
# pydeck
75+
# streamlit
76+
openai==2.26.0
77+
# via github-portfolio-reviewer-agent
78+
packaging==26.0
79+
# via
80+
# altair
81+
# streamlit
82+
pandas==2.3.3
83+
# via streamlit
84+
pillow==12.1.1
85+
# via
86+
# reportlab
87+
# streamlit
88+
playwright==1.58.0
89+
# via github-portfolio-reviewer-agent
90+
protobuf==6.33.5
91+
# via streamlit
92+
pyarrow==23.0.1
93+
# via streamlit
94+
pydantic==2.12.5
95+
# via openai
96+
pydantic-core==2.41.5
97+
# via pydantic
98+
pydeck==0.9.1
99+
# via streamlit
100+
pyee==13.0.1
101+
# via playwright
102+
python-dateutil==2.9.0.post0
103+
# via pandas
104+
pytz==2026.1.post1
105+
# via pandas
106+
referencing==0.37.0
107+
# via
108+
# jsonschema
109+
# jsonschema-specifications
110+
reportlab==4.4.10
111+
# via github-portfolio-reviewer-agent
112+
requests==2.32.5
113+
# via
114+
# github-portfolio-reviewer-agent
115+
# streamlit
116+
rpds-py==0.30.0
117+
# via
118+
# jsonschema
119+
# referencing
120+
six==1.17.0
121+
# via python-dateutil
122+
smmap==5.0.3
123+
# via gitdb
124+
sniffio==1.3.1
125+
# via openai
126+
streamlit==1.55.0
127+
# via github-portfolio-reviewer-agent
128+
tenacity==9.1.4
129+
# via streamlit
130+
toml==0.10.2
131+
# via streamlit
132+
tornado==6.5.5
133+
# via streamlit
134+
tqdm==4.67.3
135+
# via openai
136+
typing-extensions==4.15.0
137+
# via
138+
# altair
139+
# anyio
140+
# openai
141+
# pydantic
142+
# pydantic-core
143+
# pyee
144+
# referencing
145+
# streamlit
146+
# typing-inspection
147+
typing-inspection==0.4.2
148+
# via pydantic
149+
tzdata==2025.3
150+
# via pandas
151+
urllib3==2.6.3
152+
# via requests
153+
watchdog==6.0.0 ; sys_platform != 'darwin'
154+
# via streamlit

src/analysis_store.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import sqlite3
3+
from contextlib import closing
34
from dataclasses import asdict
45
from datetime import datetime, timezone
56
from hashlib import sha256
@@ -23,7 +24,7 @@ def _connect(db_path=None):
2324

2425

2526
def initialize_analysis_store(db_path=None):
26-
with _connect(db_path) as connection:
27+
with closing(_connect(db_path)) as connection:
2728
connection.execute(
2829
"""
2930
CREATE TABLE IF NOT EXISTS analysis_cache (
@@ -156,7 +157,7 @@ def _report_from_payload(payload):
156157
def load_cached_report(analysis_key, freshness_signature, db_path=None):
157158
initialize_analysis_store(db_path=db_path)
158159

159-
with _connect(db_path) as connection:
160+
with closing(_connect(db_path)) as connection:
160161
row = connection.execute(
161162
"""
162163
SELECT report_json, updated_at
@@ -184,7 +185,7 @@ def save_cached_report(analysis_key, github_username, freshness_signature, repor
184185
serialized_report = json.dumps(asdict(report), ensure_ascii=True)
185186
timestamp = datetime.now(timezone.utc).isoformat()
186187

187-
with _connect(db_path) as connection:
188+
with closing(_connect(db_path)) as connection:
188189
connection.execute(
189190
"""
190191
INSERT INTO analysis_cache (

0 commit comments

Comments
 (0)