Skip to content

Commit bf7961d

Browse files
committed
feat: rename a2a-db-cli to db-cli in installation instructions and update related CLI arguments
1 parent 874e72b commit bf7961d

9 files changed

Lines changed: 108 additions & 115 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ postgresql = ["sqlalchemy[asyncio,postgresql-asyncpg]>=2.0.0"]
3939
mysql = ["sqlalchemy[asyncio,aiomysql]>=2.0.0"]
4040
signing = ["PyJWT>=2.0.0"]
4141
sqlite = ["sqlalchemy[asyncio,aiosqlite]>=2.0.0"]
42-
a2a-db-cli = ["alembic>=1.14.0"]
42+
db-cli = ["alembic>=1.14.0"]
4343

4444
sql = ["a2a-sdk[postgresql,mysql,sqlite]"]
4545

@@ -50,7 +50,7 @@ all = [
5050
"a2a-sdk[grpc]",
5151
"a2a-sdk[telemetry]",
5252
"a2a-sdk[signing]",
53-
"a2a-sdk[a2a-db-cli]",
53+
"a2a-sdk[db-cli]",
5454
]
5555

5656
[project.urls]

src/a2a/a2a_db_cli.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
except ImportError as e:
1313
raise ImportError(
14-
"CLI requires Alembic. Install with: 'pip install a2a-sdk[a2a-db-cli]'."
14+
"CLI requires Alembic. Install with: 'pip install a2a-sdk[db-cli]'."
1515
) from e
1616

1717

@@ -28,14 +28,12 @@ def _add_shared_args(
2828
parser.add_argument(
2929
'--tasks-table',
3030
dest=f'{prefix}tasks_table',
31-
help='Custom tasks table to update.',
32-
action='append',
31+
help='Custom tasks table to update. If not set, the default is "tasks".',
3332
)
3433
parser.add_argument(
35-
'--push-notification-table',
36-
dest=f'{prefix}push_notification_table',
37-
help='Custom push notification configs table to update.',
38-
action='append',
34+
'--push-notification-configs-table',
35+
dest=f'{prefix}push_notification_configs_table',
36+
help='Custom push notification configs table to update. If not set, the default is "push_notification_configs".',
3937
)
4038
parser.add_argument(
4139
'-v',
@@ -122,29 +120,27 @@ def run_migrations() -> None:
122120
# Consolidate owner, db_url, tables, verbose and sql values
123121
owner = args.owner or getattr(args, 'sub_owner', None)
124122
db_url = args.database_url or getattr(args, 'sub_database_url', None)
125-
task_tables = args.tasks_table or getattr(args, 'sub_tasks_table', None)
126-
push_notification_tables = args.push_notification_table or getattr(
127-
args, 'sub_push_notification_table', None
123+
task_table = args.tasks_table or getattr(args, 'sub_tasks_table', None)
124+
push_notification_configs_table = (
125+
args.push_notification_configs_table
126+
or getattr(args, 'sub_push_notification_configs_table', None)
128127
)
128+
129129
verbose = args.verbose or getattr(args, 'sub_verbose', False)
130130
sql = args.sql or getattr(args, 'sub_sql', False)
131131

132132
# Pass custom arguments to the migration context
133133
if owner:
134-
if args.cmd == 'downgrade':
135-
parser.error(
136-
"The --add_columns_owner_last_updated-default-owner option is not supported for the 'downgrade' command."
137-
)
138134
cfg.set_main_option(
139135
'add_columns_owner_last_updated_default_owner', owner
140136
)
141137
if db_url:
142138
os.environ['DATABASE_URL'] = db_url
143-
if task_tables:
144-
cfg.set_main_option('tasks_tables', ','.join(task_tables))
145-
if push_notification_tables:
139+
if task_table:
140+
cfg.set_main_option('tasks_table', task_table)
141+
if push_notification_configs_table:
146142
cfg.set_main_option(
147-
'push_notification_tables', ','.join(push_notification_tables)
143+
'push_notification_configs_table', push_notification_configs_table
148144
)
149145
if verbose:
150146
cfg.set_main_option('verbose', 'true')

src/a2a/migrations/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ This directory handles the database schema updates for the A2A SDK. It uses a bu
44

55
## Installation
66

7-
To use the `a2a-db` migration tool, install the `a2a-sdk` with the `a2a-db-cli` extra.
7+
To use the `a2a-db` migration tool, install the `a2a-sdk` with the `db-cli` extra.
88

99
| Extra | `uv` Command | `pip` Command |
1010
| :--- | :--- | :--- |
11-
| **CLI Only** | `uv add "a2a-sdk[a2a-db-cli]"` | `pip install "a2a-sdk[a2a-db-cli]"` |
11+
| **CLI Only** | `uv add "a2a-sdk[db-cli]"` | `pip install "a2a-sdk[db-cli]"` |
1212
| **All Extras** | `uv add "a2a-sdk[all]"` | `pip install "a2a-sdk[all]"` |
1313

1414

@@ -55,11 +55,11 @@ You can use the `--database-url` flag to specify the database URL for a single c
5555
```bash
5656
uv run a2a-db --database-url "sqlite+aiosqlite:///my_database.db"
5757
```
58-
#### --tasks-table / --push-notification-table
59-
The tables `tasks` and `push_notification_configs` are always updated by default. If your application uses additional tables that require the same migration, you can specify them using these flags.
58+
#### --tasks-table / --push-notification-configs-table
59+
Custom tasks and push notification configs tables to update. If not set, the default are `tasks` and `push_notification_configs`.
6060

6161
```bash
62-
uv run a2a-db --tasks-table "my_tasks" --push-notification-table "my_configs"
62+
uv run a2a-db --tasks-table "my_tasks" --push-notification-configs-table "my_configs"
6363
```
6464
#### -v / --verbose
6565
Enables verbose output by setting `sqlalchemy.engine` logging to `INFO`.

src/a2a/migrations/env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from alembic import context
1414
except ImportError as e:
1515
raise ImportError(
16-
"Migrations require Alembic. Install with: 'pip install a2a-sdk[a2a-db-cli]'."
16+
"Migrations require Alembic. Install with: 'pip install a2a-sdk[db-cli]'."
1717
) from e
1818

1919

src/a2a/migrations/script.py.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ try:
1313
from alembic import op
1414
except ImportError as e:
1515
raise ImportError(
16-
"A2A migrations require the 'a2a-db-cli' extra. Install with: 'pip install a2a-sdk[a2a-db-cli]'."
16+
"A2A migrations require the 'db-cli' extra. Install with: 'pip install a2a-sdk[db-cli]'."
1717
) from e
1818

1919
${imports if imports else ""}

src/a2a/migrations/versions/6419d2d130f6_add_columns_owner_last_updated.py

Lines changed: 76 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from alembic import context, op
1616
except ImportError as e:
1717
raise ImportError(
18-
"'Add columns owner and last_updated to database tables' migration requires Alembic. Install with: 'pip install a2a-sdk[a2a-db-cli]'."
18+
"'Add columns owner and last_updated to database tables' migration requires Alembic. Install with: 'pip install a2a-sdk[db-cli]'."
1919
) from e
2020

2121

@@ -32,6 +32,38 @@ def _get_inspector() -> sa.engine.reflection.Inspector:
3232
return inspector
3333

3434

35+
def _add_column(table: str, value: str, column_name: str) -> None:
36+
if not _column_exists(table, column_name):
37+
op.add_column(
38+
table,
39+
sa.Column(
40+
column_name,
41+
sa.String(128),
42+
nullable=False,
43+
server_default=value,
44+
),
45+
)
46+
47+
48+
def _add_index(table: str, index_name: str, columns: list[str]) -> None:
49+
if not _index_exists(table, index_name):
50+
op.create_index(
51+
index_name,
52+
table,
53+
columns,
54+
)
55+
56+
57+
def _drop_column(table: str, column_name: str) -> None:
58+
if _column_exists(table, column_name, True):
59+
op.drop_column(table, column_name)
60+
61+
62+
def _drop_index(table: str, index_name: str) -> None:
63+
if _index_exists(table, index_name, True):
64+
op.drop_index(index_name, table_name=table)
65+
66+
3567
def _table_exists(table_name: str) -> bool:
3668
if context.is_offline_mode():
3769
return True
@@ -69,89 +101,54 @@ def upgrade() -> None:
69101
'add_columns_owner_last_updated_default_owner',
70102
'legacy_v03_no_user_info',
71103
)
72-
tasks_tables = ['tasks']
73-
push_notification_tables = ['push_notification_configs']
74-
75-
if tasks_tables_str := context.config.get_main_option('tasks_tables', None):
76-
tasks_tables.extend([t.strip() for t in tasks_tables_str.split(',')])
77-
if push_notification_tables_str := context.config.get_main_option(
78-
'push_notification_tables', None
79-
):
80-
push_notification_tables.extend(
81-
[t.strip() for t in push_notification_tables_str.split(',')]
104+
tasks_table = context.config.get_main_option('tasks_table', 'tasks')
105+
push_notification_configs_table = context.config.get_main_option(
106+
'push_notification_configs_table', 'push_notification_configs'
107+
)
108+
109+
if _table_exists(tasks_table):
110+
_add_column(tasks_table, owner, 'owner')
111+
_add_column(tasks_table, '0', 'last_updated')
112+
_add_index(
113+
tasks_table,
114+
f'idx_{tasks_table}_owner_last_updated',
115+
['owner', 'last_updated'],
116+
)
117+
else:
118+
logging.warning(
119+
f"Table '{tasks_table}' does not exist. Skipping upgrade for this table."
82120
)
83121

84-
for table in tasks_tables + push_notification_tables:
85-
if _table_exists(table):
86-
if not _column_exists(table, 'owner'):
87-
op.add_column(
88-
table,
89-
sa.Column(
90-
'owner',
91-
sa.String(128),
92-
nullable=False,
93-
server_default=owner,
94-
),
95-
)
96-
else:
97-
if table in tasks_tables:
98-
tasks_tables.remove(table)
99-
logging.warning(
100-
f"Table '{table}' does not exist. Skipping upgrade for this table."
101-
)
102-
103-
for table in tasks_tables:
104-
if _table_exists(table):
105-
if not _column_exists(table, 'last_updated'):
106-
op.add_column(
107-
table,
108-
sa.Column('last_updated', sa.String(22), nullable=True),
109-
)
110-
if not _index_exists(table, f'idx_{table}_owner_last_updated'):
111-
op.create_index(
112-
f'idx_{table}_owner_last_updated',
113-
table,
114-
['owner', 'last_updated'],
115-
)
116-
else:
117-
logging.warning(
118-
f"Table '{table}' does not exist. Skipping upgrade for this table."
119-
)
122+
if _table_exists(push_notification_configs_table):
123+
_add_column(push_notification_configs_table, owner, 'owner')
124+
else:
125+
logging.warning(
126+
f"Table '{push_notification_configs_table}' does not exist. Skipping upgrade for this table."
127+
)
120128

121129

122130
def downgrade() -> None:
123131
"""Downgrade schema."""
124-
tasks_tables = ['tasks']
125-
push_notification_tables = ['push_notification_configs']
126-
127-
if tasks_tables_str := context.config.get_main_option('tasks_tables', None):
128-
tasks_tables.extend([t.strip() for t in tasks_tables_str.split(',')])
129-
if push_notification_tables_str := context.config.get_main_option(
130-
'push_notification_tables', None
131-
):
132-
push_notification_tables.extend(
133-
[t.strip() for t in push_notification_tables_str.split(',')]
132+
tasks_table = context.config.get_main_option('tasks_table', 'tasks')
133+
push_notification_configs_table = context.config.get_main_option(
134+
'push_notification_configs_table', 'push_notification_configs'
135+
)
136+
137+
if _table_exists(tasks_table):
138+
_drop_index(
139+
tasks_table,
140+
f'idx_{tasks_table}_owner_last_updated',
141+
)
142+
_drop_column(tasks_table, 'owner')
143+
_drop_column(tasks_table, 'last_updated')
144+
else:
145+
logging.warning(
146+
f"Table '{tasks_table}' does not exist. Skipping downgrade for this table."
134147
)
135148

136-
for table in tasks_tables:
137-
if _table_exists(table):
138-
if _index_exists(table, f'idx_{table}_owner_last_updated', True):
139-
op.drop_index(
140-
f'idx_{table}_owner_last_updated', table_name=table
141-
)
142-
if _column_exists(table, 'last_updated', True):
143-
op.drop_column(table, 'last_updated')
144-
else:
145-
tasks_tables.remove(table)
146-
logging.warning(
147-
f"Table '{table}' does not exist. Skipping downgrade for this table."
148-
)
149-
150-
for table in tasks_tables + push_notification_tables:
151-
if _table_exists(table):
152-
if _column_exists(table, 'owner', True):
153-
op.drop_column(table, 'owner')
154-
else:
155-
logging.warning(
156-
f"Table '{table}' does not exist. Skipping downgrade for this table."
157-
)
149+
if _table_exists(push_notification_configs_table):
150+
_drop_column(push_notification_configs_table, 'owner')
151+
else:
152+
logging.warning(
153+
f"Table '{push_notification_configs_table}' does not exist. Skipping downgrade for this table."
154+
)

tests/migrations/test_a2a_db_cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_cli_upgrade_offline(mock_alembic_command, mock_alembic_config):
2626
tasks_table = 'my_tasks'
2727
push_table = 'my_push'
2828

29-
# Simulate: a2a-db upgrade head --sql --add_columns_owner_last_updated-default-ownertest-owner --tasks-table my_tasks --push-notification-table my_push -v
29+
# Simulate: a2a-db upgrade head --sql --add_columns_owner_last_updated-default-ownertest-owner --tasks-table my_tasks --push-notification-configs-table my_push -v
3030
test_args = [
3131
'a2a-db',
3232
'upgrade',
@@ -36,7 +36,7 @@ def test_cli_upgrade_offline(mock_alembic_command, mock_alembic_config):
3636
custom_owner,
3737
'--tasks-table',
3838
tasks_table,
39-
'--push-notification-table',
39+
'--push-notification-configs-table',
4040
push_table,
4141
'-v',
4242
]
@@ -55,10 +55,10 @@ def test_cli_upgrade_offline(mock_alembic_command, mock_alembic_config):
5555
'add_columns_owner_last_updated_default_owner', custom_owner
5656
)
5757
mock_alembic_config.return_value.set_main_option.assert_any_call(
58-
'tasks_tables', tasks_table
58+
'tasks_table', tasks_table
5959
)
6060
mock_alembic_config.return_value.set_main_option.assert_any_call(
61-
'push_notification_tables', push_table
61+
'push_notification_configs_table', push_table
6262
)
6363
mock_alembic_config.return_value.set_main_option.assert_any_call(
6464
'verbose', 'true'
@@ -88,7 +88,7 @@ def test_cli_downgrade_offline(mock_alembic_command, mock_alembic_config):
8888

8989
# Verify tables option
9090
mock_alembic_config.return_value.set_main_option.assert_any_call(
91-
'tasks_tables', tasks_table
91+
'tasks_table', tasks_table
9292
)
9393

9494

tests/migrations/versions/test_migration_6419d2d130f6.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def test_migration_6419d2d130f6_custom_tables(
177177
db_url,
178178
'--tasks-table',
179179
custom_tasks,
180-
'--push-notification-table',
180+
'--push-notification-configs-table',
181181
custom_push,
182182
'upgrade',
183183
'6419d2d130f6',

uv.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)