Skip to content

chore: update python sample code #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2025
Merged
Changes from all commits
Commits
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
116 changes: 86 additions & 30 deletions docs/tutorials/todo-manager/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -808,54 +808,110 @@ First, let's create a simple todo service to provide basic CRUD operations for m
<Tabs groupId="sdk">
<TabItem value="python" label="Python">
```python
# todo-service.py
# service.py

"""
A simple Todo service for demonstration purposes.
Uses an in-memory list to store todos.
"""

from dataclasses import dataclass
from datetime import datetime
from typing import Optional
from typing import List, Optional, Dict, Any
import random
import string

@dataclass
class Todo:
id: str
content: str
owner_id: str
created_at: str
"""Represents a todo item."""

def __init__(self, id: str, content: str, owner_id: str, created_at: str):
self.id = id
self.content = content
self.owner_id = owner_id
self.created_at = created_at

def to_dict(self) -> Dict[str, Any]:
"""Convert todo to dictionary for JSON serialization."""
return {
"id": self.id,
"content": self.content,
"ownerId": self.owner_id,
"createdAt": self.created_at
}

class TodoService:
"""A simple Todo service for demonstration purposes.
Use an in-memory array to store todos
"""
def **init**(self):
self.todos: list[Todo] = []
"""A simple Todo service for demonstration purposes."""

def __init__(self):
self._todos: List[Todo] = []

def get_all_todos(self, owner_id: Optional[str] = None) -> list[Todo]:
def get_all_todos(self, owner_id: Optional[str] = None) -> List[Dict[str, Any]]:
"""
Get all todos, optionally filtered by owner_id.

Args:
owner_id: If provided, only return todos owned by this user

Returns:
List of todo dictionaries
"""
if owner_id:
return [todo for todo in self.todos if todo.owner_id == owner_id]
return self.todos
filtered_todos = [todo for todo in self._todos if todo.owner_id == owner_id]
return [todo.to_dict() for todo in filtered_todos]
return [todo.to_dict() for todo in self._todos]

def get_todo_by_id(self, todo_id: str) -> Optional[Todo]:
"""
Get a todo by its ID.

Args:
todo_id: The ID of the todo to retrieve

Returns:
Todo object if found, None otherwise
"""
for todo in self._todos:
if todo.id == todo_id:
return todo
return None

def get_todo_by_id(self, id: str) -> Optional[Todo]:
return next((todo for todo in self.todos if todo.id == id), None)
def create_todo(self, content: str, owner_id: str) -> Dict[str, Any]:
"""
Create a new todo.

def create_todo(self, content: str, owner_id: str) -> Todo:
Args:
content: The content of the todo
owner_id: The ID of the user who owns this todo

Returns:
Dictionary representation of the created todo
"""
todo = Todo(
id=self._gen_id(),
id=self._generate_id(),
content=content,
owner_id=owner_id,
created_at=datetime.now().isoformat()
)
self.todos.append(todo)
return todo

def delete_todo(self, id: str) -> Optional[Todo]:
for i, todo in enumerate(self.todos):
if todo.id == id:
return self.todos.pop(i)
self._todos.append(todo)
return todo.to_dict()

def delete_todo(self, todo_id: str) -> Optional[Dict[str, Any]]:
"""
Delete a todo by its ID.

Args:
todo_id: The ID of the todo to delete

Returns:
Dictionary representation of the deleted todo if found, None otherwise
"""
for i, todo in enumerate(self._todos):
if todo.id == todo_id:
deleted_todo = self._todos.pop(i)
return deleted_todo.to_dict()
return None

def _gen_id(self) -> str:
"""Generate a random 8-character string for todo ID."""
def _generate_id(self) -> str:
"""Generate a random ID for a todo."""
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))

````
Expand Down Expand Up @@ -1068,7 +1124,7 @@ This demonstrates how role-based access control (RBAC) works in practice, where
<TabItem value="python" label="Python">

:::info
Check out the [MCP Auth Python SDK repository](https://github.com/mcp-auth/python/blob/master/samples/server/todo-manager.py) for the complete code of the MCP server (OIDC version).
Check out the [MCP Auth Python SDK repository](https://github.com/mcp-auth/python/blob/master/samples/server/todo-manager/server.py) for the complete code of the MCP server (OIDC version).
:::

</TabItem>
Expand Down