tamilPY 0.1.0__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 (95) hide show
  1. tamilpy-0.1.0/PKG-INFO +62 -0
  2. tamilpy-0.1.0/README.md +42 -0
  3. tamilpy-0.1.0/pyproject.toml +36 -0
  4. tamilpy-0.1.0/setup.cfg +4 -0
  5. tamilpy-0.1.0/tamilPY.egg-info/PKG-INFO +62 -0
  6. tamilpy-0.1.0/tamilPY.egg-info/SOURCES.txt +93 -0
  7. tamilpy-0.1.0/tamilPY.egg-info/dependency_links.txt +1 -0
  8. tamilpy-0.1.0/tamilPY.egg-info/entry_points.txt +2 -0
  9. tamilpy-0.1.0/tamilPY.egg-info/requires.txt +11 -0
  10. tamilpy-0.1.0/tamilPY.egg-info/top_level.txt +1 -0
  11. tamilpy-0.1.0/tpy/__init__.py +3 -0
  12. tamilpy-0.1.0/tpy/cli.py +14 -0
  13. tamilpy-0.1.0/tpy/commands/__init__.py +0 -0
  14. tamilpy-0.1.0/tpy/commands/build.py +53 -0
  15. tamilpy-0.1.0/tpy/commands/crud.py +26 -0
  16. tamilpy-0.1.0/tpy/commands/db.py +43 -0
  17. tamilpy-0.1.0/tpy/commands/doctor.py +45 -0
  18. tamilpy-0.1.0/tpy/commands/migrate.py +84 -0
  19. tamilpy-0.1.0/tpy/commands/new.py +120 -0
  20. tamilpy-0.1.0/tpy/commands/seed.py +44 -0
  21. tamilpy-0.1.0/tpy/commands/serve.py +42 -0
  22. tamilpy-0.1.0/tpy/commands/version.py +12 -0
  23. tamilpy-0.1.0/tpy/config/__init__.py +5 -0
  24. tamilpy-0.1.0/tpy/config/loader.py +102 -0
  25. tamilpy-0.1.0/tpy/config/settings.py +5 -0
  26. tamilpy-0.1.0/tpy/database/__init__.py +7 -0
  27. tamilpy-0.1.0/tpy/database/column.py +42 -0
  28. tamilpy-0.1.0/tpy/database/migration.py +88 -0
  29. tamilpy-0.1.0/tpy/database/seeder.py +83 -0
  30. tamilpy-0.1.0/tpy/generator/__init__.py +0 -0
  31. tamilpy-0.1.0/tpy/generator/controller_generator.py +53 -0
  32. tamilpy-0.1.0/tpy/generator/crud_generator.py +86 -0
  33. tamilpy-0.1.0/tpy/generator/migration_generator.py +96 -0
  34. tamilpy-0.1.0/tpy/generator/model_generator.py +116 -0
  35. tamilpy-0.1.0/tpy/generator/repository_generator.py +88 -0
  36. tamilpy-0.1.0/tpy/generator/route_generator.py +128 -0
  37. tamilpy-0.1.0/tpy/generator/schema_generator.py +221 -0
  38. tamilpy-0.1.0/tpy/generator/service_generator.py +53 -0
  39. tamilpy-0.1.0/tpy/parser/__init__.py +0 -0
  40. tamilpy-0.1.0/tpy/parser/ast.py +25 -0
  41. tamilpy-0.1.0/tpy/parser/lexer.py +210 -0
  42. tamilpy-0.1.0/tpy/parser/parser.py +168 -0
  43. tamilpy-0.1.0/tpy/parser/tokens.py +105 -0
  44. tamilpy-0.1.0/tpy/providers/__init__.py +6 -0
  45. tamilpy-0.1.0/tpy/providers/base.py +302 -0
  46. tamilpy-0.1.0/tpy/providers/factory.py +58 -0
  47. tamilpy-0.1.0/tpy/providers/mongodb/__init__.py +3 -0
  48. tamilpy-0.1.0/tpy/providers/mongodb/connection.py +0 -0
  49. tamilpy-0.1.0/tpy/providers/mongodb/indexes.py +0 -0
  50. tamilpy-0.1.0/tpy/providers/mongodb/provider.py +50 -0
  51. tamilpy-0.1.0/tpy/providers/mongodb/repository.py +0 -0
  52. tamilpy-0.1.0/tpy/providers/mysql/__init__.py +3 -0
  53. tamilpy-0.1.0/tpy/providers/mysql/connection.py +0 -0
  54. tamilpy-0.1.0/tpy/providers/mysql/migration.py +0 -0
  55. tamilpy-0.1.0/tpy/providers/mysql/provider.py +97 -0
  56. tamilpy-0.1.0/tpy/providers/mysql/repository.py +0 -0
  57. tamilpy-0.1.0/tpy/providers/postgres/__init__.py +3 -0
  58. tamilpy-0.1.0/tpy/providers/postgres/connection.py +0 -0
  59. tamilpy-0.1.0/tpy/providers/postgres/migration.py +0 -0
  60. tamilpy-0.1.0/tpy/providers/postgres/provider.py +98 -0
  61. tamilpy-0.1.0/tpy/providers/postgres/repository.py +0 -0
  62. tamilpy-0.1.0/tpy/providers/sqlite/__init__.py +3 -0
  63. tamilpy-0.1.0/tpy/providers/sqlite/connection.py +0 -0
  64. tamilpy-0.1.0/tpy/providers/sqlite/migration.py +0 -0
  65. tamilpy-0.1.0/tpy/providers/sqlite/provider.py +96 -0
  66. tamilpy-0.1.0/tpy/providers/sqlite/repository.py +0 -0
  67. tamilpy-0.1.0/tpy/runtime/__init__.py +26 -0
  68. tamilpy-0.1.0/tpy/runtime/base_model.py +13 -0
  69. tamilpy-0.1.0/tpy/runtime/builder.py +54 -0
  70. tamilpy-0.1.0/tpy/runtime/logger.py +84 -0
  71. tamilpy-0.1.0/tpy/runtime/request.py +35 -0
  72. tamilpy-0.1.0/tpy/runtime/response.py +46 -0
  73. tamilpy-0.1.0/tpy/runtime/routing.py +72 -0
  74. tamilpy-0.1.0/tpy/runtime/template_engine.py +25 -0
  75. tamilpy-0.1.0/tpy/runtime/validation.py +64 -0
  76. tamilpy-0.1.0/tpy/templates/generators/controller.py.j2 +59 -0
  77. tamilpy-0.1.0/tpy/templates/generators/migration.py.j2 +25 -0
  78. tamilpy-0.1.0/tpy/templates/generators/model.py.j2 +19 -0
  79. tamilpy-0.1.0/tpy/templates/generators/repository.py.j2 +73 -0
  80. tamilpy-0.1.0/tpy/templates/generators/route.py.j2 +49 -0
  81. tamilpy-0.1.0/tpy/templates/generators/schema.py.j2 +47 -0
  82. tamilpy-0.1.0/tpy/templates/generators/service.py.j2 +40 -0
  83. tamilpy-0.1.0/tpy/templates/project/README.md +5 -0
  84. tamilpy-0.1.0/tpy/templates/project/app_logger.py +9 -0
  85. tamilpy-0.1.0/tpy/templates/project/app_providers_database.py +9 -0
  86. tamilpy-0.1.0/tpy/templates/project/database_seed_demo.py +31 -0
  87. tamilpy-0.1.0/tpy/templates/project/main.py +18 -0
  88. tamilpy-0.1.0/tpy/templates/project/requirements.txt +8 -0
  89. tamilpy-0.1.0/tpy/templates/project/schema.tpy +11 -0
  90. tamilpy-0.1.0/tpy/templates/project/tpy.toml +6 -0
  91. tamilpy-0.1.0/tpy/utils/__init__.py +0 -0
  92. tamilpy-0.1.0/tpy/utils/console.py +20 -0
  93. tamilpy-0.1.0/tpy/utils/db_wizard.py +254 -0
  94. tamilpy-0.1.0/tpy/utils/file_manager.py +27 -0
  95. tamilpy-0.1.0/tpy/utils/files.py +6 -0
tamilpy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.4
2
+ Name: tamilPY
3
+ Version: 0.1.0
4
+ Summary: TamilPY Framework — schema-driven Python web framework
5
+ Author: TPY Contributors
6
+ License: MIT
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: typer
10
+ Requires-Dist: jinja2
11
+ Requires-Dist: rich
12
+ Requires-Dist: fastapi
13
+ Requires-Dist: uvicorn
14
+ Requires-Dist: sqlalchemy
15
+ Requires-Dist: pydantic
16
+ Requires-Dist: motor
17
+ Requires-Dist: pymongo
18
+ Requires-Dist: psycopg2-binary
19
+ Requires-Dist: pymysql
20
+
21
+ tpy/templates/project/.gitignore# tamilPY (TPY Framework)
22
+
23
+ Schema-driven Python web framework by **Selvaganapathi Arumugam**.
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install tamilPY
29
+ ```
30
+
31
+ ## Client flow
32
+
33
+ 1. `tpy new myapp` — create the app
34
+ 2. Edit `schema.tpy` — define models
35
+ 3. `tpy build` — choose DB (SQLite / PostgreSQL / MySQL / MongoDB), enter connection details, generate code
36
+ 4. `tpy migrate` — apply migrations
37
+ 5. `tpy seed` — seed sample data
38
+ 6. `tpy serve` — run the API
39
+
40
+ ## Commands
41
+
42
+ | Command | Description |
43
+ |---------|-------------|
44
+ | `tpy new <name>` | Create a new project |
45
+ | `tpy build` | Interactive DB setup + generate app layers |
46
+ | `tpy build --skip-db` | Generate using existing `.env` |
47
+ | `tpy db configure` | Re-run DB wizard anytime |
48
+ | `tpy migrate` | Apply pending migrations |
49
+ | `tpy migrate rollback` | Roll back latest migration |
50
+ | `tpy seed` | Run `database/seeds` |
51
+ | `tpy serve` | Start FastAPI server |
52
+ | `tpy doctor` | Validate project structure |
53
+ | `tpy version` | Show framework version |
54
+
55
+ ## Docs
56
+
57
+ Open [TamilPY](https://selvaganapathiarumugam.github.io/tamilPY/) for the full client guide.
58
+
59
+ ## Author
60
+
61
+ **Selvaganapathi Arumugam**
62
+ Software Developer
@@ -0,0 +1,42 @@
1
+ tpy/templates/project/.gitignore# tamilPY (TPY Framework)
2
+
3
+ Schema-driven Python web framework by **Selvaganapathi Arumugam**.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install tamilPY
9
+ ```
10
+
11
+ ## Client flow
12
+
13
+ 1. `tpy new myapp` — create the app
14
+ 2. Edit `schema.tpy` — define models
15
+ 3. `tpy build` — choose DB (SQLite / PostgreSQL / MySQL / MongoDB), enter connection details, generate code
16
+ 4. `tpy migrate` — apply migrations
17
+ 5. `tpy seed` — seed sample data
18
+ 6. `tpy serve` — run the API
19
+
20
+ ## Commands
21
+
22
+ | Command | Description |
23
+ |---------|-------------|
24
+ | `tpy new <name>` | Create a new project |
25
+ | `tpy build` | Interactive DB setup + generate app layers |
26
+ | `tpy build --skip-db` | Generate using existing `.env` |
27
+ | `tpy db configure` | Re-run DB wizard anytime |
28
+ | `tpy migrate` | Apply pending migrations |
29
+ | `tpy migrate rollback` | Roll back latest migration |
30
+ | `tpy seed` | Run `database/seeds` |
31
+ | `tpy serve` | Start FastAPI server |
32
+ | `tpy doctor` | Validate project structure |
33
+ | `tpy version` | Show framework version |
34
+
35
+ ## Docs
36
+
37
+ Open [TamilPY](https://selvaganapathiarumugam.github.io/tamilPY/) for the full client guide.
38
+
39
+ ## Author
40
+
41
+ **Selvaganapathi Arumugam**
42
+ Software Developer
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tamilPY"
7
+ version = "0.1.0"
8
+ description = "TamilPY Framework — schema-driven Python web framework"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "TPY Contributors" }
14
+ ]
15
+ dependencies = [
16
+ "typer",
17
+ "jinja2",
18
+ "rich",
19
+ "fastapi",
20
+ "uvicorn",
21
+ "sqlalchemy",
22
+ "pydantic",
23
+ "motor",
24
+ "pymongo",
25
+ "psycopg2-binary",
26
+ "pymysql",
27
+ ]
28
+
29
+ [project.scripts]
30
+ tpy = "tpy.cli:app"
31
+
32
+ [tool.setuptools.packages.find]
33
+ include = ["tpy*"]
34
+
35
+ [tool.setuptools.package-data]
36
+ tpy = ["templates/**/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.4
2
+ Name: tamilPY
3
+ Version: 0.1.0
4
+ Summary: TamilPY Framework — schema-driven Python web framework
5
+ Author: TPY Contributors
6
+ License: MIT
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: typer
10
+ Requires-Dist: jinja2
11
+ Requires-Dist: rich
12
+ Requires-Dist: fastapi
13
+ Requires-Dist: uvicorn
14
+ Requires-Dist: sqlalchemy
15
+ Requires-Dist: pydantic
16
+ Requires-Dist: motor
17
+ Requires-Dist: pymongo
18
+ Requires-Dist: psycopg2-binary
19
+ Requires-Dist: pymysql
20
+
21
+ tpy/templates/project/.gitignore# tamilPY (TPY Framework)
22
+
23
+ Schema-driven Python web framework by **Selvaganapathi Arumugam**.
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install tamilPY
29
+ ```
30
+
31
+ ## Client flow
32
+
33
+ 1. `tpy new myapp` — create the app
34
+ 2. Edit `schema.tpy` — define models
35
+ 3. `tpy build` — choose DB (SQLite / PostgreSQL / MySQL / MongoDB), enter connection details, generate code
36
+ 4. `tpy migrate` — apply migrations
37
+ 5. `tpy seed` — seed sample data
38
+ 6. `tpy serve` — run the API
39
+
40
+ ## Commands
41
+
42
+ | Command | Description |
43
+ |---------|-------------|
44
+ | `tpy new <name>` | Create a new project |
45
+ | `tpy build` | Interactive DB setup + generate app layers |
46
+ | `tpy build --skip-db` | Generate using existing `.env` |
47
+ | `tpy db configure` | Re-run DB wizard anytime |
48
+ | `tpy migrate` | Apply pending migrations |
49
+ | `tpy migrate rollback` | Roll back latest migration |
50
+ | `tpy seed` | Run `database/seeds` |
51
+ | `tpy serve` | Start FastAPI server |
52
+ | `tpy doctor` | Validate project structure |
53
+ | `tpy version` | Show framework version |
54
+
55
+ ## Docs
56
+
57
+ Open [TamilPY](https://selvaganapathiarumugam.github.io/tamilPY/) for the full client guide.
58
+
59
+ ## Author
60
+
61
+ **Selvaganapathi Arumugam**
62
+ Software Developer
@@ -0,0 +1,93 @@
1
+ README.md
2
+ pyproject.toml
3
+ tamilPY.egg-info/PKG-INFO
4
+ tamilPY.egg-info/SOURCES.txt
5
+ tamilPY.egg-info/dependency_links.txt
6
+ tamilPY.egg-info/entry_points.txt
7
+ tamilPY.egg-info/requires.txt
8
+ tamilPY.egg-info/top_level.txt
9
+ tpy/__init__.py
10
+ tpy/cli.py
11
+ tpy/commands/__init__.py
12
+ tpy/commands/build.py
13
+ tpy/commands/crud.py
14
+ tpy/commands/db.py
15
+ tpy/commands/doctor.py
16
+ tpy/commands/migrate.py
17
+ tpy/commands/new.py
18
+ tpy/commands/seed.py
19
+ tpy/commands/serve.py
20
+ tpy/commands/version.py
21
+ tpy/config/__init__.py
22
+ tpy/config/loader.py
23
+ tpy/config/settings.py
24
+ tpy/database/__init__.py
25
+ tpy/database/column.py
26
+ tpy/database/migration.py
27
+ tpy/database/seeder.py
28
+ tpy/generator/__init__.py
29
+ tpy/generator/controller_generator.py
30
+ tpy/generator/crud_generator.py
31
+ tpy/generator/migration_generator.py
32
+ tpy/generator/model_generator.py
33
+ tpy/generator/repository_generator.py
34
+ tpy/generator/route_generator.py
35
+ tpy/generator/schema_generator.py
36
+ tpy/generator/service_generator.py
37
+ tpy/parser/__init__.py
38
+ tpy/parser/ast.py
39
+ tpy/parser/lexer.py
40
+ tpy/parser/parser.py
41
+ tpy/parser/tokens.py
42
+ tpy/providers/__init__.py
43
+ tpy/providers/base.py
44
+ tpy/providers/factory.py
45
+ tpy/providers/mongodb/__init__.py
46
+ tpy/providers/mongodb/connection.py
47
+ tpy/providers/mongodb/indexes.py
48
+ tpy/providers/mongodb/provider.py
49
+ tpy/providers/mongodb/repository.py
50
+ tpy/providers/mysql/__init__.py
51
+ tpy/providers/mysql/connection.py
52
+ tpy/providers/mysql/migration.py
53
+ tpy/providers/mysql/provider.py
54
+ tpy/providers/mysql/repository.py
55
+ tpy/providers/postgres/__init__.py
56
+ tpy/providers/postgres/connection.py
57
+ tpy/providers/postgres/migration.py
58
+ tpy/providers/postgres/provider.py
59
+ tpy/providers/postgres/repository.py
60
+ tpy/providers/sqlite/__init__.py
61
+ tpy/providers/sqlite/connection.py
62
+ tpy/providers/sqlite/migration.py
63
+ tpy/providers/sqlite/provider.py
64
+ tpy/providers/sqlite/repository.py
65
+ tpy/runtime/__init__.py
66
+ tpy/runtime/base_model.py
67
+ tpy/runtime/builder.py
68
+ tpy/runtime/logger.py
69
+ tpy/runtime/request.py
70
+ tpy/runtime/response.py
71
+ tpy/runtime/routing.py
72
+ tpy/runtime/template_engine.py
73
+ tpy/runtime/validation.py
74
+ tpy/templates/generators/controller.py.j2
75
+ tpy/templates/generators/migration.py.j2
76
+ tpy/templates/generators/model.py.j2
77
+ tpy/templates/generators/repository.py.j2
78
+ tpy/templates/generators/route.py.j2
79
+ tpy/templates/generators/schema.py.j2
80
+ tpy/templates/generators/service.py.j2
81
+ tpy/templates/project/README.md
82
+ tpy/templates/project/app_logger.py
83
+ tpy/templates/project/app_providers_database.py
84
+ tpy/templates/project/database_seed_demo.py
85
+ tpy/templates/project/main.py
86
+ tpy/templates/project/requirements.txt
87
+ tpy/templates/project/schema.tpy
88
+ tpy/templates/project/tpy.toml
89
+ tpy/utils/__init__.py
90
+ tpy/utils/console.py
91
+ tpy/utils/db_wizard.py
92
+ tpy/utils/file_manager.py
93
+ tpy/utils/files.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tpy = tpy.cli:app
@@ -0,0 +1,11 @@
1
+ typer
2
+ jinja2
3
+ rich
4
+ fastapi
5
+ uvicorn
6
+ sqlalchemy
7
+ pydantic
8
+ motor
9
+ pymongo
10
+ psycopg2-binary
11
+ pymysql
@@ -0,0 +1 @@
1
+ tpy
@@ -0,0 +1,3 @@
1
+ """tamilPY — Tamil Python web framework."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,14 @@
1
+ import importlib
2
+ import pkgutil
3
+ import typer
4
+ import tpy.commands
5
+
6
+ app = typer.Typer()
7
+
8
+ for _, module_name, _ in pkgutil.iter_modules(tpy.commands.__path__):
9
+ module = importlib.import_module(f"tpy.commands.{module_name}")
10
+ if hasattr(module, "register"):
11
+ module.register(app)
12
+
13
+ if __name__ == "__main__":
14
+ app()
File without changes
@@ -0,0 +1,53 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from tpy.runtime.builder import Builder
6
+ from tpy.utils.console import Console
7
+ from tpy.utils.db_wizard import DatabaseWizard
8
+
9
+
10
+ def register(app: typer.Typer) -> None:
11
+ """Register the build command."""
12
+
13
+ @app.command("build")
14
+ def build(
15
+ skip_db: bool = typer.Option(
16
+ False,
17
+ "--skip-db",
18
+ help="Skip interactive database setup and use existing .env",
19
+ ),
20
+ ) -> None:
21
+ """
22
+ Configure database, parse schema.tpy, and generate the application.
23
+ """
24
+ root = Path(".")
25
+
26
+ if not (root / "schema.tpy").exists():
27
+ Console.error("schema.tpy not found. Run this inside a TPY project.")
28
+ raise typer.Exit(1)
29
+
30
+ try:
31
+ Console.info("Starting TPY build...")
32
+
33
+ if not skip_db:
34
+ Console.info("Step 1/2 — Database configuration")
35
+ DatabaseWizard(root).run()
36
+ Console.info("")
37
+ Console.info("Step 2/2 — Generating application code")
38
+ else:
39
+ Console.info("Using existing database configuration (--skip-db)")
40
+
41
+ builder = Builder(project_root=root)
42
+ ast = builder.build()
43
+ model_count = len(ast.models)
44
+ Console.success(
45
+ f"Build completed successfully ({model_count} model(s))."
46
+ )
47
+ Console.info("Next: tpy migrate && tpy seed && tpy serve")
48
+ except FileNotFoundError as error:
49
+ Console.error(str(error))
50
+ raise typer.Exit(1)
51
+ except Exception as error:
52
+ Console.error(str(error))
53
+ raise typer.Exit(1)
@@ -0,0 +1,26 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from tpy.runtime.builder import Builder
6
+ from tpy.utils.console import Console
7
+
8
+
9
+ def register(app: typer.Typer) -> None:
10
+ """Register the CRUD generation command."""
11
+
12
+ @app.command("crud")
13
+ def crud() -> None:
14
+ """
15
+ Generate full CRUD layers from ``schema.tpy``.
16
+ """
17
+ try:
18
+ Console.info("Generating CRUD from schema.tpy...")
19
+ builder = Builder(project_root=Path("."))
20
+ ast = builder.build()
21
+ Console.success(
22
+ f"CRUD generated for {len(ast.models)} model(s)."
23
+ )
24
+ except Exception as error:
25
+ Console.error(str(error))
26
+ raise typer.Exit(1)
@@ -0,0 +1,43 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from tpy.config.loader import ConfigLoader
6
+ from tpy.providers.factory import get_provider
7
+ from tpy.utils.console import Console
8
+ from tpy.utils.db_wizard import DatabaseWizard
9
+
10
+
11
+ def register(app: typer.Typer) -> None:
12
+ """Register database utility commands."""
13
+
14
+ db_app = typer.Typer(help="Database utilities.")
15
+ app.add_typer(db_app, name="db")
16
+
17
+ @db_app.command("configure")
18
+ def db_configure() -> None:
19
+ """Interactively choose and configure the database provider."""
20
+ try:
21
+ DatabaseWizard(Path(".")).run()
22
+ except Exception as error:
23
+ Console.error(str(error))
24
+ raise typer.Exit(1)
25
+
26
+ @db_app.command("info")
27
+ def db_info() -> None:
28
+ """Show configured database provider details."""
29
+ settings = ConfigLoader(Path(".")).load()
30
+ Console.info(f"Provider : {settings.database}")
31
+ Console.info(f"URL : {settings.database_url or '(default)'}")
32
+
33
+ @db_app.command("ping")
34
+ def db_ping() -> None:
35
+ """Test the database connection."""
36
+ try:
37
+ provider = get_provider(project_root=Path("."))
38
+ provider.connect()
39
+ provider.close()
40
+ Console.success("Database connection OK.")
41
+ except Exception as error:
42
+ Console.error(str(error))
43
+ raise typer.Exit(1)
@@ -0,0 +1,45 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from tpy.config.loader import ConfigLoader
6
+ from tpy.utils.console import Console
7
+
8
+
9
+ def register(app: typer.Typer) -> None:
10
+ """Register the doctor command."""
11
+
12
+ @app.command("doctor")
13
+ def doctor() -> None:
14
+ """
15
+ Check that the current directory looks like a valid TPY project.
16
+ """
17
+ root = Path(".")
18
+ required = [
19
+ "schema.tpy",
20
+ "tpy.toml",
21
+ "main.py",
22
+ "app",
23
+ "app/logger.py",
24
+ "database",
25
+ "database/seeds",
26
+ ]
27
+
28
+ ok = True
29
+ for item in required:
30
+ path = root / item
31
+ if path.exists():
32
+ Console.success(f"OK {item}")
33
+ else:
34
+ Console.error(f"MISS {item}")
35
+ ok = False
36
+
37
+ settings = ConfigLoader(root).load()
38
+ Console.info(
39
+ f"Project={settings.name} database={settings.database}"
40
+ )
41
+
42
+ if not ok:
43
+ raise typer.Exit(1)
44
+
45
+ Console.success("TPY project looks healthy.")
@@ -0,0 +1,84 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from tpy.providers.factory import get_provider
6
+ from tpy.utils.console import Console
7
+
8
+
9
+ def register(app: typer.Typer) -> None:
10
+ """Register migration commands."""
11
+
12
+ migrate_app = typer.Typer(help="Database migration commands.")
13
+ app.add_typer(migrate_app, name="migrate")
14
+
15
+ @migrate_app.callback(invoke_without_command=True)
16
+ def migrate_default(
17
+ ctx: typer.Context,
18
+ ) -> None:
19
+ """Run pending migrations when no subcommand is given."""
20
+ if ctx.invoked_subcommand is not None:
21
+ return
22
+ _run_migrate()
23
+
24
+ @migrate_app.command("up")
25
+ def migrate_up() -> None:
26
+ """Apply pending migrations."""
27
+ _run_migrate()
28
+
29
+ @migrate_app.command("rollback")
30
+ def migrate_rollback() -> None:
31
+ """Roll back the latest migration."""
32
+ try:
33
+ provider = get_provider(project_root=Path("."))
34
+ name = provider.rollback()
35
+ provider.close()
36
+
37
+ if name is None:
38
+ Console.warning("No migrations to roll back.")
39
+ return
40
+
41
+ Console.success(f"Rolled back: {name}")
42
+ except Exception as error:
43
+ Console.error(str(error))
44
+ raise typer.Exit(1)
45
+
46
+ @migrate_app.command("status")
47
+ def migrate_status() -> None:
48
+ """Show applied migrations."""
49
+ try:
50
+ provider = get_provider(project_root=Path("."))
51
+ provider.connect()
52
+ provider.ensure_migrations_table()
53
+ rows = provider.fetch_all(
54
+ "SELECT name, applied_at FROM _tpy_migrations ORDER BY id"
55
+ )
56
+ provider.close()
57
+
58
+ if not rows:
59
+ Console.info("No migrations applied yet.")
60
+ return
61
+
62
+ for row in rows:
63
+ Console.info(f"{row['name']} @ {row['applied_at']}")
64
+ except Exception as error:
65
+ Console.error(str(error))
66
+ raise typer.Exit(1)
67
+
68
+
69
+ def _run_migrate() -> None:
70
+ try:
71
+ Console.info("Running migrations...")
72
+ provider = get_provider(project_root=Path("."))
73
+ applied = provider.migrate()
74
+ provider.close()
75
+
76
+ if not applied:
77
+ Console.info("Nothing to migrate.")
78
+ return
79
+
80
+ for name in applied:
81
+ Console.success(f"Migrated: {name}")
82
+ except Exception as error:
83
+ Console.error(str(error))
84
+ raise typer.Exit(1)