Skip to content

Commit 794237b

Browse files
committed
FastMCP working
1 parent e817d75 commit 794237b

File tree

18 files changed

+484
-542
lines changed

18 files changed

+484
-542
lines changed

.github/workflows/python-ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Python CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
lint-and-format:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
15+
- name: Set up Python 3.12
16+
uses: actions/setup-python@v4
17+
with:
18+
python-version: '3.12'
19+
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install ruff
24+
25+
- name: Lint with Ruff
26+
run: |
27+
ruff check .
28+
ruff format --check .
29+

.github/workflows/test.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Test Deploy CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
vendoring:
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest, macos-latest] # , windows-latest
16+
runs-on: ${{ matrix.os }}
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: '3.12'
26+
27+
- name: Install Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 22
31+
32+
- name: Install Wrangler
33+
run: npm install -g wrangler
34+
35+
- name: Run vendoring (Linux/macOS)
36+
if: runner.os != 'Windows'
37+
run: |
38+
python3.12 -m venv .venv
39+
source .venv/bin/activate
40+
.venv/bin/pip install pyodide-build
41+
.venv/bin/pyodide venv .venv-pyodide
42+
.venv-pyodide/bin/pip install -t src/vendor -r vendor.txt
43+
44+
# Windows is not supported by pyodide.
45+
# - name: Run vendoring (Windows)
46+
# if: runner.os == 'Windows'
47+
# run: |
48+
# python -m venv .venv
49+
# .\.venv\Scripts\Activate.ps1
50+
# .venv\Scripts\pip install pyodide-build
51+
# .venv\Scripts\pyodide venv .venv-pyodide
52+
# .venv-pyodide\Scripts\pip install -t src/vendor -r vendor.txt
53+
54+
- name: Test worker deployment
55+
run: wrangler deploy --dry-run
56+
57+
- name: Run tests (Linux/macOS)
58+
if: runner.os != 'Windows'
59+
run: |
60+
source .venv/bin/activate
61+
pip install -r requirements-test.txt
62+
pytest tests

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
.venv/
2+
.venv-pyodide/
3+
.pytest_cache/
24
node_modules/
5+
__pycache__/
36
src/vendor/
4-
.vscode/
7+
.vscode/
8+
.wrangler/

README.md

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
# Vendoring Packages: FastAPI + Jinja2 Example
1+
# Python Workers: FastMCP Example
22

3-
*Note: You must have Python Packages enabled on your account for built-in packages to work. Request Access to our Closed Beta using [This Form](https://forms.gle/FcjjhV3YtPyjRPaL8)*
3+
This is an example of a Python Worker that uses the FastMCP package.
44

5-
This is an example of a Python Worker that uses a built-in package (FastAPI) with a vendored package (Jinja2).
5+
[![Deploy to Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/ai/tree/main/demos/python-workers-mcp)
66

7-
## Adding Packages
7+
>[!NOTE]
8+
>Due to the [size](https://developers.cloudflare.com/workers/platform/limits/#worker-size) of the Worker, this example can only be deployed if you're using the Workers Paid plan. Free plan users will encounter deployment errors because this Worker exceeds the 3MB size limit.
89
9-
Built-in packages can be selected from [this list](https://developers.cloudflare.com/workers/languages/python/packages/#supported-packages) and added to your `requirements.txt` file. These can be used with no other explicit install step.
10+
## Adding Packages
1011

1112
Vendored packages are added to your source files and need to be installed in a special manner. The Python Workers team plans to make this process automatic in the future, but for now, manual steps need to be taken.
1213

1314
### Vendoring Packages
1415

15-
[//]: # (NOTE: when updating the instructions below, be sure to also update the vendoring.yml CI workflow)
16-
1716
First, install Python3.12 and pip for Python 3.12.
1817

1918
*Currently, other versions of Python will not work - use 3.12!*
@@ -30,36 +29,42 @@ Within our virtual environment, install the pyodide CLI:
3029
.venv/bin/pyodide venv .venv-pyodide
3130
```
3231

33-
Next, add packages to your vendor.txt file. Here we'll add jinja2
34-
```
35-
jinja2
36-
```
37-
38-
Lastly, add these packages to your source files at `src/vendor`. For any additional packages, re-run this command.
32+
Lastly, download the vendored packages. For any additional packages, re-run this command.
3933
```console
4034
.venv-pyodide/bin/pip install -t src/vendor -r vendor.txt
4135
```
4236

43-
### Using Vendored packages
37+
### Developing and Deploying
38+
39+
To develop your Worker, run `npx wrangler@latest dev`.
40+
41+
To deploy your Worker, run `npx wrangler@latest deploy`.
4442

45-
In your wrangler.toml, make the vendor directory available:
43+
### Testing
4644

47-
```toml
48-
[[rules]]
49-
globs = ["vendor/**"]
50-
type = "Data"
51-
fallthrough = true
45+
To test run:
46+
```console
47+
source .venv/bin/activate
48+
pip install -r requirements-test.txt
49+
pytest tests
5250
```
5351

54-
Now, you can import and use the packages:
52+
### Linting and Formatting
53+
54+
This project uses Ruff for linting and formatting:
5555

56-
```python
57-
import jinja2
58-
# ... etc ...
56+
```console
57+
pip install ruff
58+
ruff check . # Run linting
59+
ruff format . # Format code
5960
```
6061

61-
### Developing and Deploying
62+
### IDE Integration
6263

63-
To develop your Worker, run `npx wrangler@latest dev`.
64+
To have good autocompletions in your IDE simply select .venv-pyodide/bin/python as your IDE's interpreter.
6465

65-
To deploy your Worker, run `npx wrangler@latest deploy`.
66+
You should also install your dependencies for type hints.
67+
68+
```console
69+
.venv-pyodide/bin/pip install -r requirements-dev.txt
70+
```

build.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Check if Python 3.12 is installed
5+
if ! command -v python3.12 &> /dev/null; then
6+
echo "Error: Python 3.12 is required but not installed."
7+
exit 1
8+
fi
9+
10+
# Install pyodide CLI if needed
11+
if ! pip show pyodide-build &> /dev/null; then
12+
echo "Installing pyodide-build..."
13+
pip install pyodide-build
14+
else
15+
echo "pyodide-build already installed."
16+
fi
17+
18+
# Create pyodide virtual environment if it doesn't exist
19+
if [ ! -d ".venv-pyodide" ]; then
20+
echo "Creating pyodide virtual environment (.venv-pyodide)..."
21+
pyodide venv .venv-pyodide
22+
else
23+
echo "Using existing pyodide virtual environment (.venv-pyodide)..."
24+
fi
25+
26+
# Download vendored packages
27+
echo "Installing vendored packages from vendor.txt..."
28+
.venv-pyodide/bin/pip install -t src/vendor -r vendor.txt
29+
30+
echo "Build completed successfully!"

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "python-workers-mcp",
3+
"version": "1.0.0",
4+
"private": true,
5+
"description": "Python Workers MCP Demo",
6+
"scripts": {
7+
"build": "./build.sh",
8+
"dev": "wrangler dev",
9+
"deploy": "wrangler deploy"
10+
},
11+
"devDependencies": {
12+
"wrangler": "^4.14.0"
13+
}
14+
}

pyproject.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[tool.ruff]
2+
target-version = "py312"
3+
line-length = 100
4+
[tool.ruff.lint]
5+
select = [
6+
"E", # pycodestyle errors
7+
"F", # pyflakes
8+
"B", # flake8-bugbear
9+
"I", # isort
10+
"C4", # flake8-comprehensions
11+
"UP", # pyupgrade
12+
"N", # pep8-naming
13+
"RUF", # ruff-specific rules
14+
]
15+
ignore = []
16+
17+
[tool.ruff.lint.isort]
18+
known-first-party = ["src"]
19+
20+
[tool.ruff.format]
21+
quote-style = "double"
22+
indent-style = "space"
23+
line-ending = "auto"
24+
skip-magic-trailing-comma = false

requirements-dev.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pytest
2+
requests
3+
mcp
4+
pytest-asyncio
5+
ruff
6+
mcp
7+
structlog
8+
webtypy
9+
pyodide-py

requirements-test.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pytest
2+
requests
3+
mcp
4+
pytest-asyncio
5+
ruff

0 commit comments

Comments
 (0)