Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e0687e9
bump major version number
bmos Feb 12, 2026
27b2290
only use requirements in setup.py or requirements-dev.txt
bmos Feb 12, 2026
5efdab7
make friendly dependencies behavior the default
bmos Feb 12, 2026
db815d9
update dev dependencies
bmos Feb 12, 2026
0274edd
update dev dependencies
bmos Feb 12, 2026
8bdf4e1
add python 3.14 support
bmos Feb 12, 2026
f3a0b5d
ruff formatting
bmos Feb 12, 2026
1ff64e1
remove FutureWarning
bmos Feb 12, 2026
591e0fe
add min versions in setup.py to ensure tests pass
bmos Feb 12, 2026
82ec685
Revert "remove FutureWarning"
bmos Feb 12, 2026
fefdbaa
add ImportWarning
bmos Feb 12, 2026
79c73d6
add warning in requirements.txt
bmos Feb 12, 2026
8bdc9a4
remove selenium setup from dockerfile
bmos Feb 12, 2026
5588224
adjusting google min dep versions to get 3.14 install working
bmos Feb 12, 2026
a91f1e3
Merge branch 'main' into only_friendly_deps
bmos Feb 12, 2026
0a231b9
adjusting google min dep versions to get 3.14 install working
bmos Feb 12, 2026
71033d4
remove pytz
bmos Feb 13, 2026
f45cf4d
add pandas extra
bmos Feb 13, 2026
f6be14c
don't allow GHSA-pq67-6m6q-mj2v
bmos Feb 13, 2026
40a6a27
add paramiko to targetsmart extra
bmos Feb 13, 2026
686a07a
Bump dbt-core to 1.6.15+
bmos Feb 13, 2026
ad4b325
fix circleci workflow
bmos Feb 13, 2026
3318439
allow dependency review through firewall
bmos Feb 13, 2026
9d926e0
Merge branch 'main' into only_friendly_deps
bmos Feb 13, 2026
3763c05
fix dockerfile
bmos Feb 13, 2026
5a21d3c
fix circleci cache keys
bmos Feb 13, 2026
5def9f0
Merge branch 'main' into only_friendly_deps
bmos Feb 13, 2026
b77c03f
add store_artifacts to circleci
bmos Feb 13, 2026
17037f0
fix artifact upload path
bmos Feb 13, 2026
107ecfc
remove vendor exclusion from bandit in python checks
bmos Feb 15, 2026
bade670
Merge branch 'main' into only_friendly_deps
bmos Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#

version: 2

workflows:
Expand All @@ -16,82 +11,95 @@ workflows:
only: main

jobs:

# Documentation CI
docs-build:
docker:
- image: cimg/python:3.13

steps:
- checkout
# Download and cache dependencies

- restore_cache:
keys:
- v2-dependencies-python3.13-{{ checksum "requirements-dev.txt" }}
- v2-dependencies-python3.13-{{ checksum "setup.py" }}-{{ checksum "requirements-dev.txt" }}
# fallback to using the latest cache if no exact match is found
- v2-dependencies-python3.13-

- run:
name: Install dependencies
# Note that we the circleci node image installs stuff with a user "circleci", rather
# than root. So we need to tell npm where to install stuff.
command: |
pip install uv
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt

uv pip install -r requirements-dev.txt
uv pip install -e .[all]

- save_cache:
paths:
- ./venv
key: v2-dependencies-python3.13-{{ checksum "requirements-dev.txt" }}
key: v2-dependencies-python3.13-{{ checksum "setup.py" }}-{{ checksum "requirements-dev.txt" }}

- run:
name: Build docs
command: |
source .venv/bin/activate

cd docs/
make deploy_docs
cd ..

- store_artifacts:
path: docs/html

docs-build-deploy:
docker:
- image: cimg/python:3.13-node

steps:
- checkout
# Download and cache dependencies

- restore_cache:
keys:
- v2-dependencies-python3.13-{{ checksum "requirements-dev.txt" }}-
- v2-dependencies-python3.13-{{ checksum "setup.py" }}-{{ checksum "requirements-dev.txt" }}
# fallback to using the latest cache if no exact match is found
- v2-dependencies-python3.13-

- run:
name: Install dependencies
# Note that we the circleci node image installs stuff with a user "circleci", rather
# than root. So we need to tell npm where to install stuff.
command: |
npm set prefix=/home/circleci/npm
npm install -g --silent gh-pages@2.0.1

pip install uv
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt

uv pip install -r requirements-dev.txt
uv pip install -e .[all]

- save_cache:
paths:
- ./venv
key: v2-dependencies-python3.13-{{ checksum "requirements-dev.txt" }}
key: v2-dependencies-python3.13-{{ checksum "setup.py" }}-{{ checksum "requirements-dev.txt" }}

- add_ssh_keys:
# This SSH key is "CircleCI Docs" in https://github.com/move-coop/parsons/settings/keys
# We need write access to the Parsons repo, so we can push the "gh-pages" branch.
fingerprints:
- '9a:ec:4d:2b:c3:45:b2:f5:55:ca:0b:2b:36:e2:7f:df'

- run:
name: Build and deploy docs
# When running gh-pages, we specify to include dotfiles, so we pick up the .nojerkyll file.
# (This file tell Github Pages that we want to include all files in docs/, including those
# that start with an underscore like _static/).
command: |
source .venv/bin/activate

cd docs/
make deploy_docs

cd ..
git config user.email "ci-build@movementcooperative.org"
git config user.name "ci-build"
Expand Down
42 changes: 25 additions & 17 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
.dockerignore
Dockerfile
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
coverage.xml
*,cover
*.log
# Git
.git
*.gitignore

# Python artifacts
__pycache__/
.pytest_cache/
.ruff_cache/
.venv/
venv/
build/
dist/
*.egg-info/
.coverage

# Docker/CI
Dockerfile
.dockerignore
.circleci/
.github/
.pre-commit-config.yaml

# OS/IDEs
.DS_Store
.vscode/
.idea/
3 changes: 1 addition & 2 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ jobs:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.deps.dev:443
api.github.com:443
api.securityscorecards.dev:443
github.com:443

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261
with:
allow-ghsas: GHSA-pq67-6m6q-mj2v # urllib3
27 changes: 7 additions & 20 deletions .github/workflows/python-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
resolution:
- highest
- lowest-direct
- limited-dependencies

permissions:
contents: write
Expand All @@ -52,33 +51,21 @@ jobs:

- uses: install-pinned/uv@fa468aced1ea5737b7cbaba356dd97587bc27f7f

- if: matrix.resolution != 'limited-dependencies'
continue-on-error: ${{ contains(matrix.python-version, '3.14') }}
run: |
- run: |
uv pip install --system --resolution ${{ matrix.resolution }} -e .[all]
uv pip install --system --resolution ${{ matrix.resolution }} -r requirements-dev.txt

- if: matrix.resolution == 'limited-dependencies'
continue-on-error: ${{ contains(matrix.python-version, '3.14') }}
env:
PARSONS_LIMITED_DEPENDENCIES: 'TRUE'
run: |
uv pip install --system -r requirements-dev.txt
uv pip install --system -e .[all]

- id: cache-pytest
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306
with:
path: .pytest_cache
key: pytest-${{ matrix.python-version }}-${{ matrix.os }}-${{ matrix.resolution }}-${{ hashFiles('pyproject.toml') }}

- run: pytest
continue-on-error: ${{ contains(matrix.python-version, '3.14') }}
env:
COVERAGE_FILE: ".coverage.${{ matrix.os }}.${{ matrix.python-version }}.${{ matrix.resolution }}"

- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
if: ${{ !contains(matrix.python-version, '3.14') }}
with:
name: coverage-${{ matrix.os }}-${{ matrix.python-version }}-${{ matrix.resolution }}
path: .coverage.${{ matrix.os }}.${{ matrix.python-version }}.${{ matrix.resolution }}
Expand Down Expand Up @@ -199,7 +186,7 @@ jobs:

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.13'
python-version: '3.14'
cache: pip

- uses: install-pinned/uv@fa468aced1ea5737b7cbaba356dd97587bc27f7f
Expand Down Expand Up @@ -236,7 +223,7 @@ jobs:

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.13'
python-version: '3.14'
cache: pip

- uses: install-pinned/uv@fa468aced1ea5737b7cbaba356dd97587bc27f7f
Expand Down Expand Up @@ -284,7 +271,7 @@ jobs:

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.13'
python-version: '3.14'
cache: pip

- uses: install-pinned/uv@fa468aced1ea5737b7cbaba356dd97587bc27f7f
Expand All @@ -293,7 +280,7 @@ jobs:

- id: run-bandit-sarif
run: |
bandit --confidence-level 'medium' --severity-level 'medium' --recursive 'parsons' --exclude '**/vendor/*' --format 'sarif' --output 'results.sarif'
bandit --confidence-level 'medium' --severity-level 'medium' --recursive 'parsons' --format 'sarif' --output 'results.sarif'

- uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2
if: ( success() || failure() ) && contains('["success", "failure"]', steps.run-bandit-sarif.outcome)
Expand All @@ -303,7 +290,7 @@ jobs:
- id: run-bandit
if: failure() && contains('["failure"]', steps.run-bandit-sarif.outcome)
run: |
bandit --confidence-level 'medium' --severity-level 'medium' --recursive 'parsons' --exclude '**/vendor/*'
bandit --confidence-level 'medium' --severity-level 'medium' --recursive 'parsons'

coverage:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -370,7 +357,7 @@ jobs:

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.13'
python-version: '3.14'
cache: pip

- uses: install-pinned/uv@fa468aced1ea5737b7cbaba356dd97587bc27f7f
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Set up Python 3.13
- name: Set up Python 3.14
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: "3.13"
python-version: "3.14"
cache: pip

- name: Install uv
Expand Down Expand Up @@ -59,6 +59,7 @@ jobs:
- '3.11'
- '3.12'
- '3.13'
- '3.14'
os:
- ubuntu-latest
- windows-latest
Expand All @@ -81,7 +82,8 @@ jobs:
mkdir -p temp_extract
tar -xzf "$file" -C temp_extract
# Find and move requirements files to root
find temp_extract -name 'requirements.txt' -exec cp {} . \; 2>/dev/null || true
find temp_extract -name 'pyproject.toml' -exec cp {} . \; 2>/dev/null || true
find temp_extract -name 'setup.py' -exec cp {} . \; 2>/dev/null || true
# Clean up
rm -rf temp_extract

Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.0
rev: v0.15.0
hooks:
- id: ruff
- id: ruff-check
args: ['--fix']
- id: ruff-format
- repo: https://github.com/PyCQA/bandit
rev: 1.8.6
rev: 1.9.3
hooks:
- id: bandit
args: ['--confidence-level', 'medium', '--severity-level', 'medium', '--exclude', '**/vendor/*']
Expand Down
38 changes: 6 additions & 32 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
FROM --platform=linux/amd64 python:3.11

####################
## Selenium setup ##
####################

# TODO Remove when we have a TMC-specific Docker image

# Much of this was pulled from examples at https://github.com/joyzoursky/docker-python-chromedriver

# install google chrome
RUN wget -qO- https://dl.google.com/linux/linux_signing_key.pub \
| gpg --dearmor -o /etc/apt/keyrings/google.gpg; \
chmod 0644 /etc/apt/keyrings/google.gpg; \
echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/google.gpg] https://dl.google.com/linux/chrome/deb/ stable main' \
> /etc/apt/sources.list.d/google-chrome.list
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

# install chromedriver
RUN apt-get install -yqq unzip
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

# set display port to avoid crash
ENV DISPLAY=:99

###################
## Parsons setup ##
###################

RUN mkdir /src

COPY requirements.txt /src/
RUN pip install uv
RUN uv pip install --system -r /src/requirements.txt

COPY . /src/
WORKDIR /src

RUN python setup.py develop
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

RUN uv pip install --system -e .[all]

# The /app directory can house the scripts that will actually execute on this Docker image.
# Eg. If using this image in a Civis container script, Civis will install your script repo
# (from Github) to /app.
RUN mkdir /app
WORKDIR /app

# Useful for importing modules that are associated with your python scripts:
ENV PYTHONPATH=.:/app
ENV PYTHONPATH=.:/app
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
include requirements.txt
include README.md
include LICENSE.md
recursive-include parsons *.py
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This project is maintained by [The Movement Cooperative](https://movementcoopera
after [Lucy Parsons](https://en.wikipedia.org/wiki/Lucy_Parsons). The Movement Cooperative is a member-led organization
focused on providing data, tools, and strategic support for the progressive community.

Parsons is only supported for Python 3.10-13.
Parsons is only supported for Python 3.10 - 3.14.

## Table of Contents

Expand Down
Loading
Loading