nucliadb-agentic-api 1.0.0.post156__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. nucliadb_agentic_api-1.0.0.post156/PKG-INFO +150 -0
  2. nucliadb_agentic_api-1.0.0.post156/README.md +135 -0
  3. nucliadb_agentic_api-1.0.0.post156/VERSION +1 -0
  4. nucliadb_agentic_api-1.0.0.post156/alembic/README +1 -0
  5. nucliadb_agentic_api-1.0.0.post156/alembic/env.py +99 -0
  6. nucliadb_agentic_api-1.0.0.post156/alembic/script.py.mako +28 -0
  7. nucliadb_agentic_api-1.0.0.post156/alembic/versions/7f3b2f92a8c1_add_agentic_config_table.py +56 -0
  8. nucliadb_agentic_api-1.0.0.post156/alembic/versions/b3c4d5e6f7a8_add_sources_table.py +72 -0
  9. nucliadb_agentic_api-1.0.0.post156/alembic.ini +149 -0
  10. nucliadb_agentic_api-1.0.0.post156/pyproject.toml +135 -0
  11. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/VERSION +1 -0
  12. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/__init__.py +20 -0
  13. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/agentic/__init__.py +0 -0
  14. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/agentic/ask_handler.py +66 -0
  15. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/agentic/ask_result.py +389 -0
  16. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/agentic/ask_transform_to_interaction.py +10 -0
  17. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/app.py +147 -0
  18. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/commands.py +66 -0
  19. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/db/__init__.py +0 -0
  20. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/db/agentic_configs.py +296 -0
  21. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/db/settings.py +11 -0
  22. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/db/sources.py +202 -0
  23. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/db/transform.py +208 -0
  24. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/exceptions.py +10 -0
  25. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/logging.py +18 -0
  26. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/models.py +321 -0
  27. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/py.typed +0 -0
  28. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/server/__init__.py +1 -0
  29. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/server/server.py +113 -0
  30. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/server/session.py +276 -0
  31. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/server/settings.py +22 -0
  32. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/settings.py +39 -0
  33. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/utils.py +284 -0
  34. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/__init__.py +19 -0
  35. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/agentic_configs.py +117 -0
  36. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/ask.py +303 -0
  37. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/ask_websocket.py +141 -0
  38. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/mcp_content.py +310 -0
  39. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/mcp_nucliadb.py +785 -0
  40. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/oauth.py +60 -0
  41. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/router.py +3 -0
  42. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/sources.py +158 -0
  43. nucliadb_agentic_api-1.0.0.post156/src/nucliadb_agentic_api/v1/utils.py +12 -0
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: nucliadb_agentic_api
3
+ Version: 1.0.0.post156
4
+ Summary: NucliaDB Agentic API for Hyperforge
5
+ Author: AI Data Team
6
+ Author-email: AI Data Team <learning@nuclia.com>
7
+ License-Expression: Apache-2.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.10
11
+ Project-URL: Progress, https://progress.com
12
+ Project-URL: Github, https://github.com/nuclia/forge
13
+ Project-URL: API Reference, https://docs.rag.progress.cloud
14
+ Description-Content-Type: text/markdown
15
+
16
+ # NucliaDB Agentic API
17
+
18
+ The NucliaDB Agentic API package exposes NucliaDB-oriented agentic capabilities
19
+ for Hyperforge, including ASK/search flows and MCP integrations.
20
+
21
+ ## Install
22
+
23
+ From the workspace root:
24
+
25
+ ```bash
26
+ uv sync
27
+ ```
28
+
29
+ ## Run
30
+
31
+ Start the service:
32
+
33
+ ```bash
34
+ uv run nucliadb-agentic-api
35
+ ```
36
+
37
+ Useful endpoints:
38
+
39
+ - `/health/ready`
40
+ - `/health/alive`
41
+ - `/metrics`
42
+
43
+ ## Configuration
44
+
45
+ Runtime configuration is provided through environment variables consumed by
46
+ Pydantic settings. Common settings include:
47
+
48
+ - `HTTP_HOST` and `HTTP_PORT`
49
+ - `MEMORY_READER_NUCLIADB`, `MEMORY_WRITER_NUCLIADB`, and
50
+ `MEMORY_SEARCH_NUCLIADB`
51
+ - `MEMORY_APIKEY_NUCLIADB`
52
+ - `VALKEY_URL`
53
+ - `IDP_REGIONAL_GRPC`
54
+ - `LOAD_MODULES`
55
+
56
+ ## Development
57
+
58
+ Run the package tests from the workspace root:
59
+
60
+ ```bash
61
+ make test
62
+ ```
63
+
64
+
65
+ # Objective
66
+ Enhance the RAG experience by offering RAO features directly in a KB.
67
+
68
+ # How?
69
+ The same way we store search configs in the KB, we could store agentic configs, and when calling the `/ask` endpoint we can refer to a given agentic config.
70
+
71
+ # Scope
72
+
73
+ The corresponding RAO workflow will be:
74
+ - a Rephrase (optionally)
75
+ - a SmartAgent
76
+ - a Summarize
77
+
78
+ Possible sources for the SmartAgent:
79
+ - The current KB (possibly several times with different filters)
80
+ - Sync service (using connections defined in the current KB)
81
+ - Google
82
+ - Perplexity
83
+ - MCP
84
+
85
+ Out of scope
86
+ - Other KBs
87
+ - SQL
88
+ - Snowflake (?)
89
+ - Sitefinity (?)
90
+
91
+ # Config spec
92
+
93
+ ```json
94
+ {
95
+ "rephrase": { // optional
96
+ "ask_to": <filter_expression>, //optional
97
+ "prompt": <string>, // optional
98
+ "model": <model>, // optional
99
+ },
100
+ "smart_agent": {
101
+ "mode": <reactive | plan_execute>,
102
+ "extra_prompt": <string>, // optional
103
+ "models": { // optional
104
+ "context_validation": <model>, // optional
105
+ "planner": <model>, // optional
106
+ "executor": <model>, // optional
107
+ },
108
+ "sources": [<source list>]
109
+ },
110
+ "summarize": { // optional
111
+ "user_prompt": <string>, // optional
112
+ "system_prompt": <string>, // optional
113
+ "conversational": <boolean>,
114
+ "model": <model>, // optional
115
+ // and citations must be forced to chunk-level
116
+ }
117
+ }
118
+ ```
119
+
120
+ And sources can be:
121
+
122
+ ```json
123
+ {
124
+ "type": "nucliadb",
125
+ "description": <string>,
126
+ "filter_expression": <filter_expression>, //optional
127
+ }
128
+
129
+ {
130
+ "type": "sync",
131
+ "description": <string>,
132
+ "connection": <connection_id>
133
+ }
134
+
135
+ {
136
+ "type": "google",
137
+ "description": <string>
138
+ }
139
+
140
+ {
141
+ "type": "perplexity",
142
+ "description": <string>
143
+ }
144
+
145
+ {
146
+ "type": "mcp",
147
+ "description": <string>,
148
+ <...the MCP driver params>
149
+ }
150
+ ````
@@ -0,0 +1,135 @@
1
+ # NucliaDB Agentic API
2
+
3
+ The NucliaDB Agentic API package exposes NucliaDB-oriented agentic capabilities
4
+ for Hyperforge, including ASK/search flows and MCP integrations.
5
+
6
+ ## Install
7
+
8
+ From the workspace root:
9
+
10
+ ```bash
11
+ uv sync
12
+ ```
13
+
14
+ ## Run
15
+
16
+ Start the service:
17
+
18
+ ```bash
19
+ uv run nucliadb-agentic-api
20
+ ```
21
+
22
+ Useful endpoints:
23
+
24
+ - `/health/ready`
25
+ - `/health/alive`
26
+ - `/metrics`
27
+
28
+ ## Configuration
29
+
30
+ Runtime configuration is provided through environment variables consumed by
31
+ Pydantic settings. Common settings include:
32
+
33
+ - `HTTP_HOST` and `HTTP_PORT`
34
+ - `MEMORY_READER_NUCLIADB`, `MEMORY_WRITER_NUCLIADB`, and
35
+ `MEMORY_SEARCH_NUCLIADB`
36
+ - `MEMORY_APIKEY_NUCLIADB`
37
+ - `VALKEY_URL`
38
+ - `IDP_REGIONAL_GRPC`
39
+ - `LOAD_MODULES`
40
+
41
+ ## Development
42
+
43
+ Run the package tests from the workspace root:
44
+
45
+ ```bash
46
+ make test
47
+ ```
48
+
49
+
50
+ # Objective
51
+ Enhance the RAG experience by offering RAO features directly in a KB.
52
+
53
+ # How?
54
+ The same way we store search configs in the KB, we could store agentic configs, and when calling the `/ask` endpoint we can refer to a given agentic config.
55
+
56
+ # Scope
57
+
58
+ The corresponding RAO workflow will be:
59
+ - a Rephrase (optionally)
60
+ - a SmartAgent
61
+ - a Summarize
62
+
63
+ Possible sources for the SmartAgent:
64
+ - The current KB (possibly several times with different filters)
65
+ - Sync service (using connections defined in the current KB)
66
+ - Google
67
+ - Perplexity
68
+ - MCP
69
+
70
+ Out of scope
71
+ - Other KBs
72
+ - SQL
73
+ - Snowflake (?)
74
+ - Sitefinity (?)
75
+
76
+ # Config spec
77
+
78
+ ```json
79
+ {
80
+ "rephrase": { // optional
81
+ "ask_to": <filter_expression>, //optional
82
+ "prompt": <string>, // optional
83
+ "model": <model>, // optional
84
+ },
85
+ "smart_agent": {
86
+ "mode": <reactive | plan_execute>,
87
+ "extra_prompt": <string>, // optional
88
+ "models": { // optional
89
+ "context_validation": <model>, // optional
90
+ "planner": <model>, // optional
91
+ "executor": <model>, // optional
92
+ },
93
+ "sources": [<source list>]
94
+ },
95
+ "summarize": { // optional
96
+ "user_prompt": <string>, // optional
97
+ "system_prompt": <string>, // optional
98
+ "conversational": <boolean>,
99
+ "model": <model>, // optional
100
+ // and citations must be forced to chunk-level
101
+ }
102
+ }
103
+ ```
104
+
105
+ And sources can be:
106
+
107
+ ```json
108
+ {
109
+ "type": "nucliadb",
110
+ "description": <string>,
111
+ "filter_expression": <filter_expression>, //optional
112
+ }
113
+
114
+ {
115
+ "type": "sync",
116
+ "description": <string>,
117
+ "connection": <connection_id>
118
+ }
119
+
120
+ {
121
+ "type": "google",
122
+ "description": <string>
123
+ }
124
+
125
+ {
126
+ "type": "perplexity",
127
+ "description": <string>
128
+ }
129
+
130
+ {
131
+ "type": "mcp",
132
+ "description": <string>,
133
+ <...the MCP driver params>
134
+ }
135
+ ````
@@ -0,0 +1 @@
1
+ 1.0.0.post156
@@ -0,0 +1 @@
1
+ Generic single-database configuration.
@@ -0,0 +1,99 @@
1
+ import os
2
+ from logging.config import fileConfig
3
+
4
+ from hyperforge.database import metadata
5
+ from sqlalchemy import engine_from_config, pool
6
+
7
+ from alembic import context
8
+ from nucliadb_agentic_api.db import (
9
+ agentic_configs, # noqa: F401
10
+ sources, # noqa: F401
11
+ )
12
+ from nucliadb_agentic_api.db.settings import DataManagerSettings
13
+
14
+ # this is the Alembic Config object, which provides
15
+ # access to the values within the .ini file in use.
16
+ config = context.config
17
+
18
+ # Interpret the config file for Python logging.
19
+ # This line sets up loggers basically.
20
+ if config.config_file_name is not None:
21
+ fileConfig(config.config_file_name)
22
+
23
+ # add your model's MetaData object here
24
+ # for 'autogenerate' support
25
+ # from myapp import mymodel
26
+ # target_metadata = mymodel.Base.metadata
27
+
28
+ current_dir = os.path.dirname(os.path.abspath(__file__))
29
+ migrations_dir = os.path.dirname(current_dir)
30
+
31
+ config.set_main_option("script_location", migrations_dir)
32
+
33
+ # Configure Alembic to use our DATABASE_URL and our table definitions...
34
+ if os.environ.get("POSTGRESQL_DSN") or os.environ.get("postgresql_dsn"):
35
+ url = DataManagerSettings().postgresql_dsn.split("?")[0] # type: ignore
36
+ config.set_main_option("sqlalchemy.url", url)
37
+
38
+
39
+ target_metadata = metadata
40
+
41
+ # other values from the config, defined by the needs of env.py,
42
+ # can be acquired:
43
+ # my_important_option = config.get_main_option("my_important_option")
44
+ # ... etc.
45
+
46
+
47
+ def run_migrations_offline() -> None:
48
+ """Run migrations in 'offline' mode.
49
+
50
+ This configures the context with just a URL
51
+ and not an Engine, though an Engine is acceptable
52
+ here as well. By skipping the Engine creation
53
+ we don't even need a DBAPI to be available.
54
+
55
+ Calls to context.execute() here emit the given string to the
56
+ script output.
57
+
58
+ """
59
+ url = config.get_main_option("sqlalchemy.url")
60
+ context.configure(
61
+ url=url,
62
+ target_metadata=target_metadata,
63
+ version_table="nucliadb_agentic_api_alembic_version",
64
+ literal_binds=True,
65
+ dialect_opts={"paramstyle": "named"},
66
+ )
67
+
68
+ with context.begin_transaction():
69
+ context.run_migrations()
70
+
71
+
72
+ def run_migrations_online() -> None:
73
+ """Run migrations in 'online' mode.
74
+
75
+ In this scenario we need to create an Engine
76
+ and associate a connection with the context.
77
+
78
+ """
79
+ connectable = engine_from_config(
80
+ config.get_section(config.config_ini_section, {}),
81
+ prefix="sqlalchemy.",
82
+ poolclass=pool.NullPool,
83
+ )
84
+
85
+ with connectable.connect() as connection:
86
+ context.configure(
87
+ connection=connection,
88
+ target_metadata=target_metadata,
89
+ version_table="nucliadb_agentic_api_alembic_version",
90
+ )
91
+
92
+ with context.begin_transaction():
93
+ context.run_migrations()
94
+
95
+
96
+ if context.is_offline_mode():
97
+ run_migrations_offline()
98
+ else:
99
+ run_migrations_online()
@@ -0,0 +1,28 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ ${imports if imports else ""}
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ ${upgrades if upgrades else "pass"}
24
+
25
+
26
+ def downgrade() -> None:
27
+ """Downgrade schema."""
28
+ ${downgrades if downgrades else "pass"}
@@ -0,0 +1,56 @@
1
+ """Add agentic config table
2
+
3
+ Revision ID: 7f3b2f92a8c1
4
+ Revises: None
5
+ Create Date: 2026-05-30 00:00:00.000000
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from sqlalchemy.dialects import postgresql
13
+
14
+ from alembic import op
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "7f3b2f92a8c1"
18
+ down_revision: Union[str, None] = None
19
+ branch_labels: Union[str, Sequence[str], None] = None
20
+ depends_on: Union[str, Sequence[str], None] = None
21
+
22
+
23
+ def upgrade() -> None:
24
+ op.create_table(
25
+ "agentic_config_table",
26
+ sa.Column("account", sa.String(), nullable=False),
27
+ sa.Column("kbid", sa.String(), nullable=False),
28
+ sa.Column("agentic_id", sa.String(), nullable=False),
29
+ sa.Column("created", sa.DateTime(), server_default=sa.func.now()),
30
+ sa.Column("modified", sa.DateTime(), nullable=True),
31
+ sa.Column("title", sa.String(), nullable=True),
32
+ sa.Column("config", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
33
+ sa.PrimaryKeyConstraint("account", "kbid", "agentic_id"),
34
+ )
35
+ op.create_index(
36
+ op.f("ix_agentic_config_table_account"),
37
+ "agentic_config_table",
38
+ ["account"],
39
+ unique=False,
40
+ )
41
+ op.create_index(
42
+ op.f("ix_agentic_config_table_kbid"),
43
+ "agentic_config_table",
44
+ ["kbid"],
45
+ unique=False,
46
+ )
47
+
48
+
49
+ def downgrade() -> None:
50
+ op.drop_index(
51
+ op.f("ix_agentic_config_table_kbid"), table_name="agentic_config_table"
52
+ )
53
+ op.drop_index(
54
+ op.f("ix_agentic_config_table_account"), table_name="agentic_config_table"
55
+ )
56
+ op.drop_table("agentic_config_table")
@@ -0,0 +1,72 @@
1
+ """Add sources table
2
+
3
+ Revision ID: b3c4d5e6f7a8
4
+ Revises: 7f3b2f92a8c1
5
+ Create Date: 2026-06-08 00:00:00.000000
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from sqlalchemy.dialects import postgresql
13
+
14
+ from alembic import op
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "b3c4d5e6f7a8"
18
+ down_revision: Union[str, None] = "7f3b2f92a8c1"
19
+ branch_labels: Union[str, Sequence[str], None] = None
20
+ depends_on: Union[str, Sequence[str], None] = None
21
+
22
+
23
+ def upgrade() -> None:
24
+ op.create_table(
25
+ "sources_table",
26
+ sa.Column("account", sa.String(), nullable=False),
27
+ sa.Column("kbid", sa.String(), nullable=False),
28
+ sa.Column("source_id", sa.String(), nullable=False),
29
+ sa.Column("agentic_config_id", sa.String(), nullable=True),
30
+ sa.Column("created", sa.DateTime(), server_default=sa.func.now()),
31
+ sa.Column("modified", sa.DateTime(), nullable=True),
32
+ sa.Column("description", sa.String(), nullable=True),
33
+ sa.Column("type", sa.String(), nullable=False),
34
+ sa.Column("config", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
35
+ sa.ForeignKeyConstraint(
36
+ ["account", "kbid", "agentic_config_id"],
37
+ [
38
+ "agentic_config_table.account",
39
+ "agentic_config_table.kbid",
40
+ "agentic_config_table.agentic_id",
41
+ ],
42
+ ondelete="CASCADE",
43
+ ),
44
+ sa.PrimaryKeyConstraint("account", "kbid", "source_id"),
45
+ )
46
+ op.create_index(
47
+ op.f("ix_sources_table_account"),
48
+ "sources_table",
49
+ ["account"],
50
+ unique=False,
51
+ )
52
+ op.create_index(
53
+ op.f("ix_sources_table_kbid"),
54
+ "sources_table",
55
+ ["kbid"],
56
+ unique=False,
57
+ )
58
+ op.create_index(
59
+ op.f("ix_sources_table_agentic_config_id"),
60
+ "sources_table",
61
+ ["agentic_config_id"],
62
+ unique=False,
63
+ )
64
+
65
+
66
+ def downgrade() -> None:
67
+ op.drop_index(
68
+ op.f("ix_sources_table_agentic_config_id"), table_name="sources_table"
69
+ )
70
+ op.drop_index(op.f("ix_sources_table_kbid"), table_name="sources_table")
71
+ op.drop_index(op.f("ix_sources_table_account"), table_name="sources_table")
72
+ op.drop_table("sources_table")
@@ -0,0 +1,149 @@
1
+ # A generic, single database configuration.
2
+
3
+ [alembic]
4
+ # path to migration scripts.
5
+ # this is typically a path given in POSIX (e.g. forward slashes)
6
+ # format, relative to the token %(here)s which refers to the location of this
7
+ # ini file
8
+ script_location = %(here)s/alembic
9
+
10
+ # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
11
+ # Uncomment the line below if you want the files to be prepended with date and time
12
+ # see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
13
+ # for all available tokens
14
+ # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
15
+ # Or organize into date-based subdirectories (requires recursive_version_locations = true)
16
+ # file_template = %%(year)d/%%(month).2d/%%(day).2d_%%(hour).2d%%(minute).2d_%%(second).2d_%%(rev)s_%%(slug)s
17
+
18
+ # sys.path path, will be prepended to sys.path if present.
19
+ # defaults to the current working directory. for multiple paths, the path separator
20
+ # is defined by "path_separator" below.
21
+ prepend_sys_path = .
22
+
23
+
24
+ # timezone to use when rendering the date within the migration file
25
+ # as well as the filename.
26
+ # If specified, requires the tzdata library which can be installed by adding
27
+ # `alembic[tz]` to the pip requirements.
28
+ # string value is passed to ZoneInfo()
29
+ # leave blank for localtime
30
+ # timezone =
31
+
32
+ # max length of characters to apply to the "slug" field
33
+ # truncate_slug_length = 40
34
+
35
+ # set to 'true' to run the environment during
36
+ # the 'revision' command, regardless of autogenerate
37
+ # revision_environment = false
38
+
39
+ # set to 'true' to allow .pyc and .pyo files without
40
+ # a source .py file to be detected as revisions in the
41
+ # versions/ directory
42
+ # sourceless = false
43
+
44
+ # version location specification; This defaults
45
+ # to <script_location>/versions. When using multiple version
46
+ # directories, initial revisions must be specified with --version-path.
47
+ # The path separator used here should be the separator specified by "path_separator"
48
+ # below.
49
+ # version_locations = %(here)s/bar:%(here)s/bat:%(here)s/alembic/versions
50
+
51
+ # path_separator; This indicates what character is used to split lists of file
52
+ # paths, including version_locations and prepend_sys_path within configparser
53
+ # files such as alembic.ini.
54
+ # The default rendered in new alembic.ini files is "os", which uses os.pathsep
55
+ # to provide os-dependent path splitting.
56
+ #
57
+ # Note that in order to support legacy alembic.ini files, this default does NOT
58
+ # take place if path_separator is not present in alembic.ini. If this
59
+ # option is omitted entirely, fallback logic is as follows:
60
+ #
61
+ # 1. Parsing of the version_locations option falls back to using the legacy
62
+ # "version_path_separator" key, which if absent then falls back to the legacy
63
+ # behavior of splitting on spaces and/or commas.
64
+ # 2. Parsing of the prepend_sys_path option falls back to the legacy
65
+ # behavior of splitting on spaces, commas, or colons.
66
+ #
67
+ # Valid values for path_separator are:
68
+ #
69
+ # path_separator = :
70
+ # path_separator = ;
71
+ # path_separator = space
72
+ # path_separator = newline
73
+ #
74
+ # Use os.pathsep. Default configuration used for new projects.
75
+ path_separator = os
76
+
77
+ # set to 'true' to search source files recursively
78
+ # in each "version_locations" directory
79
+ # new in Alembic version 1.10
80
+ # recursive_version_locations = false
81
+
82
+ # the output encoding used when revision files
83
+ # are written from script.py.mako
84
+ # output_encoding = utf-8
85
+
86
+ # database URL. This is consumed by the user-maintained env.py script only.
87
+ # other means of configuring database URLs may be customized within the env.py
88
+ # file.
89
+ sqlalchemy.url = postgresql://user:pass@localhost/dbname
90
+
91
+
92
+ [post_write_hooks]
93
+ # post_write_hooks defines scripts or Python functions that are run
94
+ # on newly generated revision scripts. See the documentation for further
95
+ # detail and examples
96
+
97
+ # format using "black" - use the console_scripts runner, against the "black" entrypoint
98
+ # hooks = black
99
+ # black.type = console_scripts
100
+ # black.entrypoint = black
101
+ # black.options = -l 79 REVISION_SCRIPT_FILENAME
102
+
103
+ # lint with attempts to fix using "ruff" - use the module runner, against the "ruff" module
104
+ # hooks = ruff
105
+ # ruff.type = module
106
+ # ruff.module = ruff
107
+ # ruff.options = check --fix REVISION_SCRIPT_FILENAME
108
+
109
+ # Alternatively, use the exec runner to execute a binary found on your PATH
110
+ # hooks = ruff
111
+ # ruff.type = exec
112
+ # ruff.executable = ruff
113
+ # ruff.options = check --fix REVISION_SCRIPT_FILENAME
114
+
115
+ # Logging configuration. This is also consumed by the user-maintained
116
+ # env.py script only.
117
+ [loggers]
118
+ keys = root,sqlalchemy,alembic
119
+
120
+ [handlers]
121
+ keys = console
122
+
123
+ [formatters]
124
+ keys = generic
125
+
126
+ [logger_root]
127
+ level = WARNING
128
+ handlers = console
129
+ qualname =
130
+
131
+ [logger_sqlalchemy]
132
+ level = WARNING
133
+ handlers =
134
+ qualname = sqlalchemy.engine
135
+
136
+ [logger_alembic]
137
+ level = INFO
138
+ handlers =
139
+ qualname = alembic
140
+
141
+ [handler_console]
142
+ class = StreamHandler
143
+ args = (sys.stderr,)
144
+ level = NOTSET
145
+ formatter = generic
146
+
147
+ [formatter_generic]
148
+ format = %(levelname)-5.5s [%(name)s] %(message)s
149
+ datefmt = %H:%M:%S