Skip to content

Commit 429c901

Browse files
feat: modernize packaging with pyproject.toml and uv (#247)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 4e674e7 commit 429c901

File tree

7 files changed

+1806
-125
lines changed

7 files changed

+1806
-125
lines changed

.github/CONTRIBUTING.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,50 @@ information on using pull requests.
2323

2424
## Setup local environment
2525

26-
Clone the project and run the following commands to setup your environment
26+
Clone the project and install [uv](https://github.com/astral-sh/uv) (our package manager):
2727

2828
```sh
29-
python3.11 -m venv venv
30-
source venv/bin/activate
31-
pip3 install --upgrade pip
32-
python3.11 -m pip install -e ".[dev]"
29+
# Install uv (if not already installed). You can also use 'pip install uv'.
30+
curl -LsSf https://astral.sh/uv/install.sh | sh
31+
32+
# Clone and setup the project
33+
git clone https://github.com/firebase/firebase-functions-python.git
34+
cd firebase-functions-python
35+
uv sync
3336
```
3437

35-
(this also applies to setting up samples environment for each sample)
38+
This will automatically:
39+
- Create a virtual environment
40+
- Install all runtime and development dependencies
41+
- Use the Python version specified in `.python-version` (3.10)
42+
43+
(For samples, you can use the same approach but run `uv sync` in each sample directory)
3644

3745
### Running tests
3846

3947
Without coverage:
4048
```bash
41-
python3.11 -m pytest
49+
uv run pytest
4250
```
4351

4452
With coverage:
4553
```bash
46-
python3.11 -m pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
54+
uv run pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
4755
```
4856

4957
### Formatting code
5058

5159
```bash
52-
python3.11 -m ruff format .
60+
uv run ruff format .
5361
```
5462

5563
### Running lints & type checking
5664

5765
```bash
5866
# Type checking
59-
python3.11 -m mypy .
67+
uv run mypy .
6068
# Linting
61-
python3.11 -m ruff check .
69+
uv run ruff check .
6270
```
6371

6472
### Generating Docs

.github/workflows/ci.yaml

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,18 @@ jobs:
1616

1717
steps:
1818
- uses: actions/checkout@v3
19-
- name: Set up Python ${{ matrix.python }}
20-
uses: actions/setup-python@v4
19+
- name: Install uv
20+
uses: astral-sh/setup-uv@v3
2121
with:
22-
python-version: ${{ matrix.python }}
22+
enable-cache: true
23+
- name: Set up Python ${{ matrix.python }}
24+
run: uv python install ${{ matrix.python }}
2325
- name: Install dependencies
2426
run: |
25-
python${{ matrix.python }} -m venv venv
26-
source venv/bin/activate
27-
pip3 install --upgrade pip
28-
python${{ matrix.python }} -m pip install -e ".[dev]"
27+
uv sync --python ${{ matrix.python }}
2928
- name: Test with pytest & coverage
3029
run: |
31-
source venv/bin/activate
32-
python${{ matrix.python }} -m pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
30+
uv run --python ${{ matrix.python }} pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
3331
# TODO requires activation for this repository on codecov website first.
3432
# - name: Upload coverage to Codecov
3533
# uses: codecov/codecov-action@v3
@@ -38,44 +36,39 @@ jobs:
3836
runs-on: ubuntu-latest
3937
steps:
4038
- uses: actions/checkout@v3
41-
- name: Set up Python
42-
uses: actions/setup-python@v4
39+
- name: Install uv
40+
uses: astral-sh/setup-uv@v3
4341
with:
44-
python-version: "3.10"
42+
enable-cache: true
43+
- name: Set up Python
44+
run: uv python install 3.10
4545
- name: Install dependencies
4646
run: |
47-
python3.10 -m venv venv
48-
source venv/bin/activate
49-
pip3 install --upgrade pip
50-
python3.10 -m pip install -e ".[dev]"
47+
uv sync
5148
- name: Lint with ruff
5249
run: |
53-
source venv/bin/activate
54-
python3.10 -m ruff check .
50+
uv run ruff check .
5551
- name: Lint with mypy
5652
run: |
57-
source venv/bin/activate
58-
python3.10 -m mypy .
53+
uv run mypy .
5954
6055
docs:
6156
runs-on: ubuntu-latest
6257
steps:
6358
- uses: actions/checkout@v3
64-
- name: Set up Python
65-
uses: actions/setup-python@v4
59+
- name: Install uv
60+
uses: astral-sh/setup-uv@v3
6661
with:
67-
python-version: "3.10"
62+
enable-cache: true
63+
- name: Set up Python
64+
run: uv python install 3.10
6865
- name: Install dependencies
6966
run: |
70-
python3.10 -m venv venv
71-
source venv/bin/activate
72-
pip3 install --upgrade pip
73-
python3.10 -m pip install -e ".[dev]"
67+
uv sync
7468
- name: Generate Reference Docs
7569
run: |
76-
source venv/bin/activate
7770
mkdir ./docs/build
78-
./docs/generate.sh --out=./docs/build/ --pypath=src/
71+
uv run ./docs/generate.sh --out=./docs/build/ --pypath=src/
7972
- uses: actions/upload-artifact@v4
8073
name: Upload Docs Preview
8174
with:
@@ -86,17 +79,15 @@ jobs:
8679
runs-on: ubuntu-latest
8780
steps:
8881
- uses: actions/checkout@v3
89-
- name: Set up Python
90-
uses: actions/setup-python@v4
82+
- name: Install uv
83+
uses: astral-sh/setup-uv@v3
9184
with:
92-
python-version: "3.10"
85+
enable-cache: true
86+
- name: Set up Python
87+
run: uv python install 3.10
9388
- name: Install dependencies
9489
run: |
95-
python3.10 -m venv venv
96-
source venv/bin/activate
97-
pip3 install --upgrade pip
98-
python3.10 -m pip install -e ".[dev]"
90+
uv sync
9991
- name: Check Formatting with ruff
10092
run: |
101-
source venv/bin/activate
102-
python3.10 -m ruff format --check .
93+
uv run ruff format --check .

.github/workflows/release.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,23 @@ jobs:
4141
with:
4242
python-version: '3.10'
4343

44+
- name: Install uv
45+
uses: astral-sh/setup-uv@v3
46+
with:
47+
enable-cache: true
48+
4449
- name: Install dependencies
4550
run: |
46-
pip install --upgrade pip
47-
python -m pip install -e ".[dev]"
51+
uv sync --dev
4852
4953
- name: Test with pytest & coverage
5054
run: |
51-
python -m pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
55+
uv run pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
5256
5357
# Build the Python Wheel and the source distribution.
5458
- name: Package release artifacts
5559
run: |
56-
python -m pip install setuptools wheel
57-
python setup.py bdist_wheel sdist
60+
uv run python -m build
5861
5962
# Attach the packaged artifacts to the workflow output. These can be manually
6063
# downloaded for later inspection if necessary.

.gitignore

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,3 @@ doc/dist
139139
.idea
140140
.vscode/*
141141
!.vscode/settings.json
142-
143-
# Local development files
144-
async.md
145-
modernization.md
146-
uv.lock

pyproject.toml

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,73 @@
1+
[build-system]
2+
requires = ["setuptools>=63.4.2", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "firebase_functions"
7+
description = "Firebase Functions Python SDK"
8+
readme = "README.md"
9+
license = {text = "Apache-2.0"}
10+
authors = [
11+
{name = "Firebase Team"}
12+
]
13+
keywords = ["firebase", "functions", "google", "cloud"]
14+
classifiers = [
15+
"Development Status :: 4 - Beta",
16+
"Intended Audience :: Developers",
17+
"Topic :: Software Development :: Build Tools",
18+
"Programming Language :: Python :: 3.10",
19+
"Programming Language :: Python :: 3.11",
20+
]
21+
requires-python = ">=3.10"
22+
dependencies = [
23+
"flask>=2.1.2",
24+
"functions-framework>=3.0.0",
25+
"firebase-admin>=6.0.0",
26+
"pyyaml>=6.0",
27+
"typing-extensions>=4.4.0",
28+
"cloudevents>=1.2.0,<2.0.0",
29+
"flask-cors>=3.0.10",
30+
"pyjwt[crypto]>=2.5.0",
31+
"google-events==0.5.0",
32+
"google-cloud-firestore>=2.11.0",
33+
]
34+
dynamic = ["version"]
35+
36+
[project.urls]
37+
"Homepage" = "https://github.com/firebase/firebase-functions-python"
38+
"Documentation" = "https://firebase.google.com/docs/functions"
39+
"Repository" = "https://github.com/firebase/firebase-functions-python"
40+
"Bug Tracker" = "https://github.com/firebase/firebase-functions-python/issues"
41+
42+
[dependency-groups]
43+
dev = [
44+
"pytest>=7.1.2,<9",
45+
"setuptools>=63.4.2",
46+
"pytest-cov>=3.0.0",
47+
"mypy>=1.0.0",
48+
"sphinx>=6.1.3",
49+
"sphinxcontrib-napoleon>=0.7",
50+
"toml>=0.10.2",
51+
"google-cloud-tasks>=2.13.1",
52+
"ruff>=0.1.0",
53+
"build>=1.0.0",
54+
]
55+
56+
[tool.setuptools]
57+
package-dir = {"" = "src"}
58+
packages = ["firebase_functions"]
59+
60+
[tool.setuptools.package-data]
61+
firebase_functions = ["py.typed"]
62+
63+
[tool.setuptools.dynamic]
64+
version = {attr = "firebase_functions.__version__"}
65+
166
[tool.pytest.ini_options]
267
pythonpath = [
368
".", "src/",
469
]
70+
571
[tool.coverage]
672
[tool.coverage.run]
773
omit = [
@@ -43,4 +109,4 @@ ignore = [
43109
quote-style = "double"
44110
indent-style = "space"
45111
skip-magic-trailing-comma = false
46-
line-ending = "auto"
112+
line-ending = "auto"

setup.py

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,69 +15,8 @@
1515
Setup for Firebase Functions Python.
1616
"""
1717

18-
from os import path
18+
from setuptools import setup
1919

20-
from setuptools import find_packages, setup
21-
22-
install_requires = [
23-
"flask>=2.1.2",
24-
"functions-framework>=3.0.0",
25-
"firebase-admin>=6.0.0",
26-
"pyyaml>=6.0",
27-
"typing-extensions>=4.4.0",
28-
"cloudevents>=1.2.0,<2.0.0",
29-
"flask-cors>=3.0.10",
30-
"pyjwt[crypto]>=2.5.0",
31-
"google-events==0.5.0",
32-
"google-cloud-firestore>=2.11.0",
33-
]
34-
35-
dev_requires = [
36-
"pytest>=7.1.2",
37-
"setuptools>=63.4.2",
38-
"pytest-cov>=3.0.0",
39-
"mypy>=1.0.0",
40-
"sphinx>=6.1.3",
41-
"sphinxcontrib-napoleon>=0.7",
42-
"toml>=0.10.2",
43-
"google-cloud-tasks>=2.13.1",
44-
"ruff>=0.1.0",
45-
]
46-
47-
# Read in the package metadata per recommendations from:
48-
# https://packaging.python.org/guides/single-sourcing-package-version/
49-
init_path = path.join(
50-
path.dirname(path.abspath(__file__)), "src", "firebase_functions", "__init__.py"
51-
)
52-
version = {}
53-
with open(init_path) as fp:
54-
exec(fp.read(), version) # pylint: disable=exec-used
55-
56-
long_description = (
57-
"The Firebase Functions Python SDK provides an SDK for defining Cloud Functions for Firebase."
58-
)
59-
60-
setup(
61-
name="firebase_functions",
62-
version=version["__version__"],
63-
description="Firebase Functions Python SDK",
64-
long_description=long_description,
65-
url="https://github.com/firebase/firebase-functions-python",
66-
author="Firebase Team",
67-
keywords=["firebase", "functions", "google", "cloud"],
68-
license="Apache License 2.0",
69-
install_requires=install_requires,
70-
extras_require={"dev": dev_requires},
71-
packages=find_packages(where="src"),
72-
package_dir={"": "src"},
73-
include_package_data=True,
74-
package_data={"firebase_functions": ["py.typed"]},
75-
python_requires=">=3.10",
76-
classifiers=[
77-
"Development Status :: 4 - Beta",
78-
"Intended Audience :: Developers",
79-
"Topic :: Software Development :: Build Tools",
80-
"Programming Language :: Python :: 3.10",
81-
"Programming Language :: Python :: 3.11",
82-
],
83-
)
20+
# All metadata is now defined in pyproject.toml.
21+
# This file is only for compatibility with legacy tools.
22+
setup()

0 commit comments

Comments
 (0)