Skip to content

Commit 61bd030

Browse files
Merge branch 'master' into update-mcp-client-sdk-v2
2 parents 6cda4c5 + c3bf2f0 commit 61bd030

59 files changed

Lines changed: 881 additions & 46 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎celery-async-tasks/README.md‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,28 @@
33
Example project for integrating Celery and Redis into a Django application.
44
This repository holds the code for the Real Python [Asynchronous Tasks With Django and Celery](https://realpython.com/asynchronous-tasks-with-django-and-celery/) tutorial.
55

6-
## Setup (macOS)
6+
## Setup
77

8-
To try the project, set up a virtual environment and install the listed dependencies:
8+
The project targets Linux and macOS. Celery doesn't support Windows.
9+
10+
To try the project, set up a virtual environment with Python 3.12 or newer and install the listed dependencies:
911

1012
```sh
1113
$ python -m venv venv
1214
$ source venv/bin/activate
1315
(venv) $ python -m pip install -r requirements.txt
1416
```
1517

16-
You'll also need to install Redis on your system:
18+
You'll also need to install Redis on your system.
19+
20+
On Linux (Debian or Ubuntu):
21+
22+
```sh
23+
$ sudo apt update
24+
$ sudo apt install redis
25+
```
26+
27+
On macOS with [Homebrew](https://brew.sh/):
1728

1829
```sh
1930
$ brew install redis
@@ -46,4 +57,4 @@ $ redis-server
4657
(venv) $ python -m celery -A django_celery worker -l info
4758
```
4859

49-
When all three processes are running, you can go to `localhost:8000/` and submit a feedback response. Celery will simulate a work-intensive process and send an email at the end of it. You'll see the email message show up in the log stream on the terminal window where the Celery worker is running.
60+
When all three processes are running, you can go to `http://localhost:8000/` and submit a feedback response. Celery will simulate a work-intensive process and send an email at the end of it. You'll see the email message show up in the log stream on the terminal window where the Celery worker is running.
Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
amqp==5.3.1
2-
asgiref==3.8.1
3-
billiard==4.2.1
4-
celery==5.4.0
5-
click==8.1.7
1+
amqp==5.4.0
2+
asgiref==3.12.1
3+
billiard==4.3.0
4+
celery==5.6.3
5+
click==8.5.0
66
click-didyoumean==0.3.1
7-
click-plugins==1.1.1
8-
click-repl==0.3.0
9-
Django==5.1.3
10-
kombu==5.4.2
11-
prompt_toolkit==3.0.48
7+
click-plugins==1.1.1.2
8+
click-repl==0.4.0
9+
Django==6.1.1
10+
kombu==5.6.2
11+
packaging==26.3
12+
prompt_toolkit==3.0.53
1213
python-dateutil==2.9.0.post0
13-
redis==5.2.0
14-
six==1.16.0
15-
sqlparse==0.5.2
16-
tzdata==2024.2
14+
redis==8.1.0
15+
six==1.17.0
16+
sqlparse==0.6.0
17+
typing_extensions==4.16.0
18+
tzdata==2026.4
19+
tzlocal==5.4.4
1720
vine==5.1.0
18-
wcwidth==0.2.13
21+
wcwidth==0.9.1
Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
amqp==5.3.1
2-
asgiref==3.8.1
3-
billiard==4.2.1
4-
celery==5.4.0
5-
click==8.1.7
1+
amqp==5.4.0
2+
asgiref==3.12.1
3+
billiard==4.3.0
4+
celery==5.6.3
5+
click==8.5.0
66
click-didyoumean==0.3.1
7-
click-plugins==1.1.1
8-
click-repl==0.3.0
9-
Django==5.1.3
10-
kombu==5.4.2
11-
prompt_toolkit==3.0.48
7+
click-plugins==1.1.1.2
8+
click-repl==0.4.0
9+
Django==6.1.1
10+
kombu==5.6.2
11+
packaging==26.3
12+
prompt_toolkit==3.0.53
1213
python-dateutil==2.9.0.post0
13-
redis==5.2.0
14-
six==1.16.0
15-
sqlparse==0.5.2
16-
tzdata==2024.2
14+
redis==8.1.0
15+
six==1.17.0
16+
sqlparse==0.6.0
17+
typing_extensions==4.16.0
18+
tzdata==2026.4
19+
tzlocal==5.4.4
1720
vine==5.1.0
18-
wcwidth==0.2.13
21+
wcwidth==0.9.1

‎hello-jev/README.md‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Hello Jev: Getting Started With Jev in Python
2+
3+
This folder provides the code examples for *Get Started With Jev in Python*,
4+
a video on the [Real Python YouTube channel](https://www.youtube.com/@realpython).
5+
6+
Both scripts run the same train-station info desk. The desk asks a visitor
7+
whether they lost something and then points them at the lost-and-found counter
8+
or asks what else it can help with. The difference is how the answer is read:
9+
10+
- **`plain_python.py`** handles the input by hand. It only accepts an uppercase
11+
`Y` or `N`, so anything else sends the visitor back around the loop.
12+
- **`jev_noul.py`** replaces that branching with a single `Noul` question. Jev
13+
scores how affirmative the answer is on a scale from `0` to `1`, so the script
14+
compares thresholds instead of strings and understands replies like
15+
`yeah, I've lost something`.
16+
17+
## Setup
18+
19+
Install [uv](https://docs.astral.sh/uv/), then create the virtual environment.
20+
Because `pyproject.toml` pins `requires-python = ">=3.14"`, uv downloads
21+
CPython 3.14 for you if you don't have it yet:
22+
23+
```sh
24+
$ uv sync
25+
```
26+
27+
`jev_noul.py` reaches Jev through [OpenRouter](https://openrouter.ai/), which
28+
lets you try the model without opening an account with TypeSafe AI. Grab an
29+
OpenRouter API key, then create a `.env` file next to the scripts and add it:
30+
31+
```dotenv
32+
OPENROUTER_API_KEY=<YOUR-OPENROUTER-KEY>
33+
```
34+
35+
Keep `.env` out of version control. An API key belongs in your environment, not
36+
in your repository.
37+
38+
## Running the Examples
39+
40+
Start with the plain script to see where hand-written input handling gives up:
41+
42+
```sh
43+
$ uv run plain_python.py
44+
Did you lose something? (Y/N)
45+
```
46+
47+
Only an uppercase `Y` or `N` gets you past the prompt. Try `yes` or `y` and the
48+
script asks again.
49+
50+
Now run the Jev version. The `--env-file` flag tells uv to load your API key
51+
from `.env` before it starts the script:
52+
53+
```sh
54+
$ uv run --env-file .env jev_noul.py
55+
Did you lose something?
56+
```
57+
58+
Answer in your own words. `jev_noul.py` treats a Noul above `0.8` as a yes and
59+
below `0.2` as a no, and asks again for anything in between.
60+
61+
## Where to Go Next
62+
63+
`Noul` is one of three Jev primitives. `Score` rates something on a scale, and
64+
`Choice` picks from a list of options. The
65+
[TypeSafe SDK on PyPI](https://pypi.org/project/typesafe-sdk/) documents all
66+
three, and the TypeSafe AI blog explains the idea behind them in
67+
[Introducing System One Models and Jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev).

‎hello-jev/jev_noul.py‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import os
2+
3+
from typesafe_sdk import Noul, TypeSafeClient
4+
5+
client = TypeSafeClient(
6+
api_key=os.environ["OPENROUTER_API_KEY"],
7+
base_url="https://openrouter.ai/api",
8+
)
9+
10+
11+
def respond(lost_something):
12+
if lost_something:
13+
print("You can find the lost and found counter on the right.")
14+
else:
15+
print("What can I help you with?")
16+
17+
18+
def ask():
19+
while True:
20+
answer = input("Did you lose something? ")
21+
r = client.system_one(
22+
state=f"{answer}",
23+
questions={
24+
"lost_something": Noul(
25+
instructions="Is the answer from the user affirmative?"
26+
),
27+
},
28+
)
29+
lost_something = r.answers["lost_something"].noul
30+
if lost_something > 0.8:
31+
return True
32+
if lost_something < 0.2:
33+
return False
34+
print("Sorry, I didn't get that.")
35+
36+
37+
def main():
38+
lost_something = ask()
39+
respond(lost_something)
40+
41+
42+
if __name__ == "__main__":
43+
main()

‎hello-jev/plain_python.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
def respond(lost_something):
2+
if lost_something:
3+
print("You can find the lost and found counter on the right.")
4+
else:
5+
print("What can I help you with?")
6+
7+
8+
def ask():
9+
while True:
10+
answer = input("Did you lose something? (Y/N) ")
11+
if answer == "Y":
12+
return True
13+
if answer == "N":
14+
return False
15+
print("Please answer with Y or N.")
16+
17+
18+
def main():
19+
lost_something = ask()
20+
respond(lost_something)
21+
22+
23+
if __name__ == "__main__":
24+
main()

‎hello-jev/pyproject.toml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
name = "hello-jev"
3+
version = "0.1.0"
4+
description = "Hello Jev: a train station info desk that routes visitors with a Choice, a Score, and a Noul."
5+
requires-python = ">=3.14"
6+
dependencies = [
7+
"typesafe-sdk>=0.7.0",
8+
]

0 commit comments

Comments
 (0)