framework-m 0.2.5__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.
- framework_m-0.2.5/.gitignore +107 -0
- framework_m-0.2.5/CHANGELOG.md +96 -0
- framework_m-0.2.5/PKG-INFO +231 -0
- framework_m-0.2.5/README.md +191 -0
- framework_m-0.2.5/alembic/README +1 -0
- framework_m-0.2.5/alembic/env.py +111 -0
- framework_m-0.2.5/alembic/script.py.mako +28 -0
- framework_m-0.2.5/alembic.ini +148 -0
- framework_m-0.2.5/docs/ports.md +414 -0
- framework_m-0.2.5/examples/run_server.py +136 -0
- framework_m-0.2.5/examples/test_api.py +73 -0
- framework_m-0.2.5/pyproject.toml +173 -0
- framework_m-0.2.5/src/framework_m/__init__.py +13 -0
- framework_m-0.2.5/src/framework_m/adapters/__init__.py +1 -0
- framework_m-0.2.5/src/framework_m/adapters/audit/__init__.py +28 -0
- framework_m-0.2.5/src/framework_m/adapters/audit/database_audit.py +156 -0
- framework_m-0.2.5/src/framework_m/adapters/audit/file_audit.py +166 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/__init__.py +40 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/citadel_policy.py +322 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/federated_identity.py +210 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/local_identity.py +274 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/rbac_permission.py +250 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/session_store.py +437 -0
- framework_m-0.2.5/src/framework_m/adapters/auth/strategies.py +555 -0
- framework_m-0.2.5/src/framework_m/adapters/cache/__init__.py +102 -0
- framework_m-0.2.5/src/framework_m/adapters/cache/redis_cache.py +241 -0
- framework_m-0.2.5/src/framework_m/adapters/db/__init__.py +150 -0
- framework_m-0.2.5/src/framework_m/adapters/db/connection.py +175 -0
- framework_m-0.2.5/src/framework_m/adapters/db/field_registry.py +227 -0
- framework_m-0.2.5/src/framework_m/adapters/db/generic_repository.py +1654 -0
- framework_m-0.2.5/src/framework_m/adapters/db/migration.py +645 -0
- framework_m-0.2.5/src/framework_m/adapters/db/outbox_repository.py +195 -0
- framework_m-0.2.5/src/framework_m/adapters/db/repository_factory.py +209 -0
- framework_m-0.2.5/src/framework_m/adapters/db/schema_mapper.py +807 -0
- framework_m-0.2.5/src/framework_m/adapters/db/session.py +114 -0
- framework_m-0.2.5/src/framework_m/adapters/db/table_registry.py +126 -0
- framework_m-0.2.5/src/framework_m/adapters/email/__init__.py +136 -0
- framework_m-0.2.5/src/framework_m/adapters/email/processor.py +237 -0
- framework_m-0.2.5/src/framework_m/adapters/email/queue_adapter.py +229 -0
- framework_m-0.2.5/src/framework_m/adapters/email/sender_adapter.py +288 -0
- framework_m-0.2.5/src/framework_m/adapters/events/__init__.py +13 -0
- framework_m-0.2.5/src/framework_m/adapters/events/inmemory_event_bus.py +139 -0
- framework_m-0.2.5/src/framework_m/adapters/events/nats_event_bus.py +206 -0
- framework_m-0.2.5/src/framework_m/adapters/factory.py +114 -0
- framework_m-0.2.5/src/framework_m/adapters/i18n/__init__.py +344 -0
- framework_m-0.2.5/src/framework_m/adapters/jobs/__init__.py +269 -0
- framework_m-0.2.5/src/framework_m/adapters/jobs/job_logger.py +177 -0
- framework_m-0.2.5/src/framework_m/adapters/jobs/outbox_worker.py +148 -0
- framework_m-0.2.5/src/framework_m/adapters/jobs/schedules.py +38 -0
- framework_m-0.2.5/src/framework_m/adapters/jobs/taskiq_adapter.py +522 -0
- framework_m-0.2.5/src/framework_m/adapters/print/__init__.py +42 -0
- framework_m-0.2.5/src/framework_m/adapters/print/gotenberg_adapter.py +225 -0
- framework_m-0.2.5/src/framework_m/adapters/print/jinja_adapter.py +215 -0
- framework_m-0.2.5/src/framework_m/adapters/socket/__init__.py +8 -0
- framework_m-0.2.5/src/framework_m/adapters/socket/nats_socket.py +128 -0
- framework_m-0.2.5/src/framework_m/adapters/storage/__init__.py +32 -0
- framework_m-0.2.5/src/framework_m/adapters/storage/local.py +315 -0
- framework_m-0.2.5/src/framework_m/adapters/storage/memory.py +92 -0
- framework_m-0.2.5/src/framework_m/adapters/storage/s3.py +639 -0
- framework_m-0.2.5/src/framework_m/adapters/tenant.py +233 -0
- framework_m-0.2.5/src/framework_m/adapters/web/__init__.py +63 -0
- framework_m-0.2.5/src/framework_m/adapters/web/activity_routes.py +170 -0
- framework_m-0.2.5/src/framework_m/adapters/web/api_key_routes.py +223 -0
- framework_m-0.2.5/src/framework_m/adapters/web/app.py +498 -0
- framework_m-0.2.5/src/framework_m/adapters/web/auth_middleware.py +237 -0
- framework_m-0.2.5/src/framework_m/adapters/web/auth_router.py +62 -0
- framework_m-0.2.5/src/framework_m/adapters/web/auth_routes.py +252 -0
- framework_m-0.2.5/src/framework_m/adapters/web/dtos.py +134 -0
- framework_m-0.2.5/src/framework_m/adapters/web/error_handler.py +221 -0
- framework_m-0.2.5/src/framework_m/adapters/web/file_routes.py +405 -0
- framework_m-0.2.5/src/framework_m/adapters/web/job_router.py +205 -0
- framework_m-0.2.5/src/framework_m/adapters/web/magic_link_routes.py +371 -0
- framework_m-0.2.5/src/framework_m/adapters/web/meta_router.py +573 -0
- framework_m-0.2.5/src/framework_m/adapters/web/meta_routes.py +175 -0
- framework_m-0.2.5/src/framework_m/adapters/web/metadata_router.py +141 -0
- framework_m-0.2.5/src/framework_m/adapters/web/middleware/__init__.py +31 -0
- framework_m-0.2.5/src/framework_m/adapters/web/middleware/locale.py +180 -0
- framework_m-0.2.5/src/framework_m/adapters/web/middleware_registry.py +211 -0
- framework_m-0.2.5/src/framework_m/adapters/web/notification_routes.py +326 -0
- framework_m-0.2.5/src/framework_m/adapters/web/oauth_routes.py +279 -0
- framework_m-0.2.5/src/framework_m/adapters/web/print_routes.py +180 -0
- framework_m-0.2.5/src/framework_m/adapters/web/rpc_routes.py +223 -0
- framework_m-0.2.5/src/framework_m/adapters/web/session_routes.py +187 -0
- framework_m-0.2.5/src/framework_m/adapters/web/settings_routes.py +137 -0
- framework_m-0.2.5/src/framework_m/adapters/web/share_routes.py +246 -0
- framework_m-0.2.5/src/framework_m/adapters/web/socket.py +178 -0
- framework_m-0.2.5/src/framework_m/adapters/web/user_data_routes.py +159 -0
- framework_m-0.2.5/src/framework_m/adapters/web/workflow_router.py +286 -0
- framework_m-0.2.5/src/framework_m/adapters/webhooks/__init__.py +26 -0
- framework_m-0.2.5/src/framework_m/adapters/webhooks/delivery.py +150 -0
- framework_m-0.2.5/src/framework_m/adapters/webhooks/listener.py +180 -0
- framework_m-0.2.5/src/framework_m/adapters/workflow/__init__.py +11 -0
- framework_m-0.2.5/src/framework_m/adapters/workflow/internal_workflow.py +376 -0
- framework_m-0.2.5/src/framework_m/adapters/workflow/temporal_adapter.py +321 -0
- framework_m-0.2.5/src/framework_m/cli/__init__.py +1 -0
- framework_m-0.2.5/src/framework_m/cli/build.py +422 -0
- framework_m-0.2.5/src/framework_m/cli/config.py +268 -0
- framework_m-0.2.5/src/framework_m/cli/jobs.py +139 -0
- framework_m-0.2.5/src/framework_m/cli/main.py +101 -0
- framework_m-0.2.5/src/framework_m/cli/migrate.py +293 -0
- framework_m-0.2.5/src/framework_m/cli/new.py +657 -0
- framework_m-0.2.5/src/framework_m/cli/plugin_loader.py +132 -0
- framework_m-0.2.5/src/framework_m/cli/quality.py +265 -0
- framework_m-0.2.5/src/framework_m/cli/start.py +229 -0
- framework_m-0.2.5/src/framework_m/cli/studio.py +159 -0
- framework_m-0.2.5/src/framework_m/cli/utility.py +236 -0
- framework_m-0.2.5/src/framework_m/cli/worker.py +194 -0
- framework_m-0.2.5/src/framework_m/core/__init__.py +6 -0
- framework_m-0.2.5/src/framework_m/core/container.py +323 -0
- framework_m-0.2.5/src/framework_m/core/decorators.py +306 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/__init__.py +49 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/activity_log.py +123 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/api_key.py +89 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/custom_permission.py +118 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/document_share.py +142 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/email_queue.py +209 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/error_log.py +127 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/file.py +97 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/job_log.py +144 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/notification.py +146 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/print_format.py +124 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/recent_document.py +75 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/scheduled_job.py +97 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/session.py +71 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/social_account.py +88 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/system_settings.py +119 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/tenant_translation.py +133 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/todo.py +59 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/translation.py +107 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/user.py +115 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/webhook.py +114 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/webhook_log.py +114 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/workflow.py +51 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/workflow_state.py +56 -0
- framework_m-0.2.5/src/framework_m/core/doctypes/workflow_transition.py +57 -0
- framework_m-0.2.5/src/framework_m/core/domain/__init__.py +13 -0
- framework_m-0.2.5/src/framework_m/core/domain/base_controller.py +224 -0
- framework_m-0.2.5/src/framework_m/core/domain/base_doctype.py +287 -0
- framework_m-0.2.5/src/framework_m/core/domain/mixins.py +69 -0
- framework_m-0.2.5/src/framework_m/core/domain/naming_counter.py +50 -0
- framework_m-0.2.5/src/framework_m/core/domain/outbox.py +85 -0
- framework_m-0.2.5/src/framework_m/core/events/__init__.py +112 -0
- framework_m-0.2.5/src/framework_m/core/exceptions.py +144 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/__init__.py +103 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/audit.py +216 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/auth_context.py +165 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/authentication.py +86 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/cache.py +140 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/email_queue.py +187 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/email_sender.py +143 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/event_bus.py +167 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/i18n.py +89 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/identity.py +198 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/job_queue.py +154 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/notification.py +145 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/oauth.py +130 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/permission.py +141 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/print.py +85 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/repository.py +228 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/search.py +133 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/session.py +167 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/socket.py +99 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/storage.py +181 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/tenant.py +165 -0
- framework_m-0.2.5/src/framework_m/core/interfaces/workflow.py +214 -0
- framework_m-0.2.5/src/framework_m/core/permission_lookup.py +203 -0
- framework_m-0.2.5/src/framework_m/core/permissions.py +224 -0
- framework_m-0.2.5/src/framework_m/core/pii.py +215 -0
- framework_m-0.2.5/src/framework_m/core/registry.py +312 -0
- framework_m-0.2.5/src/framework_m/core/rls.py +198 -0
- framework_m-0.2.5/src/framework_m/core/rpc_registry.py +90 -0
- framework_m-0.2.5/src/framework_m/core/services/__init__.py +12 -0
- framework_m-0.2.5/src/framework_m/core/services/user_manager.py +187 -0
- framework_m-0.2.5/src/framework_m/core/system_context.py +151 -0
- framework_m-0.2.5/src/framework_m/core/types/job_context.py +94 -0
- framework_m-0.2.5/src/framework_m/core/unit_of_work.py +138 -0
- framework_m-0.2.5/src/framework_m/public/__init__.py +1 -0
- framework_m-0.2.5/src/framework_m/py.typed +0 -0
- framework_m-0.2.5/tests/adapters/__init__.py +1 -0
- framework_m-0.2.5/tests/adapters/audit/test_database_audit.py +169 -0
- framework_m-0.2.5/tests/adapters/audit/test_file_audit.py +197 -0
- framework_m-0.2.5/tests/adapters/auth/__init__.py +1 -0
- framework_m-0.2.5/tests/adapters/auth/test_citadel_policy.py +336 -0
- framework_m-0.2.5/tests/adapters/auth/test_federated_identity.py +234 -0
- framework_m-0.2.5/tests/adapters/auth/test_local_identity.py +273 -0
- framework_m-0.2.5/tests/adapters/auth/test_local_identity_extended.py +512 -0
- framework_m-0.2.5/tests/adapters/auth/test_rbac_permission.py +306 -0
- framework_m-0.2.5/tests/adapters/auth/test_session_store.py +620 -0
- framework_m-0.2.5/tests/adapters/auth/test_strategies.py +595 -0
- framework_m-0.2.5/tests/adapters/auth/test_strategies_config.py +96 -0
- framework_m-0.2.5/tests/adapters/cache/test_inmemory_cache.py +435 -0
- framework_m-0.2.5/tests/adapters/cache/test_redis_cache.py +506 -0
- framework_m-0.2.5/tests/adapters/db/__init__.py +1 -0
- framework_m-0.2.5/tests/adapters/db/test_bulk_operations_rls.py +333 -0
- framework_m-0.2.5/tests/adapters/db/test_connection.py +263 -0
- framework_m-0.2.5/tests/adapters/db/test_db_init.py +217 -0
- framework_m-0.2.5/tests/adapters/db/test_field_registry.py +328 -0
- framework_m-0.2.5/tests/adapters/db/test_generic_repository.py +1599 -0
- framework_m-0.2.5/tests/adapters/db/test_migration.py +591 -0
- framework_m-0.2.5/tests/adapters/db/test_outbox_repository.py +309 -0
- framework_m-0.2.5/tests/adapters/db/test_query_optimization.py +191 -0
- framework_m-0.2.5/tests/adapters/db/test_repository_factory.py +301 -0
- framework_m-0.2.5/tests/adapters/db/test_schema_mapper.py +399 -0
- framework_m-0.2.5/tests/adapters/db/test_select_in_loading.py +268 -0
- framework_m-0.2.5/tests/adapters/db/test_session.py +156 -0
- framework_m-0.2.5/tests/adapters/db/test_table_registry.py +154 -0
- framework_m-0.2.5/tests/adapters/email/test_processor.py +400 -0
- framework_m-0.2.5/tests/adapters/email/test_queue_adapter.py +312 -0
- framework_m-0.2.5/tests/adapters/email/test_sender_processor.py +635 -0
- framework_m-0.2.5/tests/adapters/events/__init__.py +1 -0
- framework_m-0.2.5/tests/adapters/events/test_inmemory_event_bus.py +312 -0
- framework_m-0.2.5/tests/adapters/events/test_nats_event_bus.py +197 -0
- framework_m-0.2.5/tests/adapters/jobs/test_cron.py +102 -0
- framework_m-0.2.5/tests/adapters/jobs/test_inmemory_job_queue.py +418 -0
- framework_m-0.2.5/tests/adapters/jobs/test_job_logger.py +117 -0
- framework_m-0.2.5/tests/adapters/jobs/test_outbox_worker.py +357 -0
- framework_m-0.2.5/tests/adapters/jobs/test_schedules.py +69 -0
- framework_m-0.2.5/tests/adapters/jobs/test_taskiq_adapter.py +574 -0
- framework_m-0.2.5/tests/adapters/jobs/test_taskiq_context.py +94 -0
- framework_m-0.2.5/tests/adapters/print/test_gotenberg_adapter.py +350 -0
- framework_m-0.2.5/tests/adapters/print/test_jinja_adapter.py +193 -0
- framework_m-0.2.5/tests/adapters/socket/test_nats_socket.py +153 -0
- framework_m-0.2.5/tests/adapters/storage/test_local.py +317 -0
- framework_m-0.2.5/tests/adapters/storage/test_s3.py +616 -0
- framework_m-0.2.5/tests/adapters/test_factory.py +149 -0
- framework_m-0.2.5/tests/adapters/test_internal_workflow.py +529 -0
- framework_m-0.2.5/tests/adapters/test_temporal_workflow.py +359 -0
- framework_m-0.2.5/tests/adapters/test_tenant.py +240 -0
- framework_m-0.2.5/tests/adapters/web/__init__.py +1 -0
- framework_m-0.2.5/tests/adapters/web/test_activity_routes.py +252 -0
- framework_m-0.2.5/tests/adapters/web/test_api_key_routes.py +101 -0
- framework_m-0.2.5/tests/adapters/web/test_app.py +266 -0
- framework_m-0.2.5/tests/adapters/web/test_auth_router.py +148 -0
- framework_m-0.2.5/tests/adapters/web/test_auth_routes.py +192 -0
- framework_m-0.2.5/tests/adapters/web/test_dtos.py +157 -0
- framework_m-0.2.5/tests/adapters/web/test_error_handler.py +202 -0
- framework_m-0.2.5/tests/adapters/web/test_file_routes.py +300 -0
- framework_m-0.2.5/tests/adapters/web/test_job_router.py +394 -0
- framework_m-0.2.5/tests/adapters/web/test_magic_link_routes.py +451 -0
- framework_m-0.2.5/tests/adapters/web/test_meta_router.py +649 -0
- framework_m-0.2.5/tests/adapters/web/test_meta_router_extended.py +594 -0
- framework_m-0.2.5/tests/adapters/web/test_meta_routes_api.py +193 -0
- framework_m-0.2.5/tests/adapters/web/test_metadata_router.py +288 -0
- framework_m-0.2.5/tests/adapters/web/test_middleware.py +274 -0
- framework_m-0.2.5/tests/adapters/web/test_middleware_registry.py +280 -0
- framework_m-0.2.5/tests/adapters/web/test_notification_routes.py +327 -0
- framework_m-0.2.5/tests/adapters/web/test_oauth_routes.py +421 -0
- framework_m-0.2.5/tests/adapters/web/test_print_routes.py +182 -0
- framework_m-0.2.5/tests/adapters/web/test_rpc_routes.py +362 -0
- framework_m-0.2.5/tests/adapters/web/test_session_routes.py +120 -0
- framework_m-0.2.5/tests/adapters/web/test_settings_routes.py +112 -0
- framework_m-0.2.5/tests/adapters/web/test_share_routes.py +161 -0
- framework_m-0.2.5/tests/adapters/web/test_socket.py +253 -0
- framework_m-0.2.5/tests/adapters/web/test_user_data_routes.py +95 -0
- framework_m-0.2.5/tests/adapters/web/test_workflow_router.py +447 -0
- framework_m-0.2.5/tests/adapters/webhooks/test_delivery.py +211 -0
- framework_m-0.2.5/tests/adapters/webhooks/test_listener.py +191 -0
- framework_m-0.2.5/tests/architecture/test_package_separation.py +141 -0
- framework_m-0.2.5/tests/cli/__init__.py +1 -0
- framework_m-0.2.5/tests/cli/test_build.py +357 -0
- framework_m-0.2.5/tests/cli/test_build_extended.py +579 -0
- framework_m-0.2.5/tests/cli/test_cli_main.py +96 -0
- framework_m-0.2.5/tests/cli/test_config.py +344 -0
- framework_m-0.2.5/tests/cli/test_jobs.py +296 -0
- framework_m-0.2.5/tests/cli/test_main.py +247 -0
- framework_m-0.2.5/tests/cli/test_migrate.py +401 -0
- framework_m-0.2.5/tests/cli/test_new.py +590 -0
- framework_m-0.2.5/tests/cli/test_plugin_loader.py +131 -0
- framework_m-0.2.5/tests/cli/test_quality.py +412 -0
- framework_m-0.2.5/tests/cli/test_schedule_loading.py +122 -0
- framework_m-0.2.5/tests/cli/test_start.py +315 -0
- framework_m-0.2.5/tests/cli/test_studio.py +262 -0
- framework_m-0.2.5/tests/cli/test_utility.py +173 -0
- framework_m-0.2.5/tests/cli/test_worker.py +543 -0
- framework_m-0.2.5/tests/conftest.py +223 -0
- framework_m-0.2.5/tests/core/doctypes/test_api_key.py +124 -0
- framework_m-0.2.5/tests/core/doctypes/test_job_log.py +193 -0
- framework_m-0.2.5/tests/core/doctypes/test_scheduled_job.py +72 -0
- framework_m-0.2.5/tests/core/doctypes/test_social_account.py +134 -0
- framework_m-0.2.5/tests/core/doctypes/test_user.py +239 -0
- framework_m-0.2.5/tests/core/doctypes/test_webhook.py +178 -0
- framework_m-0.2.5/tests/core/doctypes/test_webhook_log.py +183 -0
- framework_m-0.2.5/tests/core/events/test_doc_events.py +181 -0
- framework_m-0.2.5/tests/core/interfaces/test_cache.py +123 -0
- framework_m-0.2.5/tests/core/interfaces/test_email_queue_protocol.py +230 -0
- framework_m-0.2.5/tests/core/interfaces/test_identity.py +218 -0
- framework_m-0.2.5/tests/core/interfaces/test_socket.py +135 -0
- framework_m-0.2.5/tests/core/interfaces/test_workflow.py +664 -0
- framework_m-0.2.5/tests/core/services/test_user_manager.py +280 -0
- framework_m-0.2.5/tests/core/test_activity_log.py +162 -0
- framework_m-0.2.5/tests/core/test_child_table_permissions.py +166 -0
- framework_m-0.2.5/tests/core/test_child_tables.py +801 -0
- framework_m-0.2.5/tests/core/test_container.py +215 -0
- framework_m-0.2.5/tests/core/test_custom_permission.py +174 -0
- framework_m-0.2.5/tests/core/test_custom_protocols.py +511 -0
- framework_m-0.2.5/tests/core/test_document_share.py +171 -0
- framework_m-0.2.5/tests/core/test_email_queue.py +293 -0
- framework_m-0.2.5/tests/core/test_error_log.py +149 -0
- framework_m-0.2.5/tests/core/test_exceptions.py +214 -0
- framework_m-0.2.5/tests/core/test_file.py +151 -0
- framework_m-0.2.5/tests/core/test_link_fetching.py +612 -0
- framework_m-0.2.5/tests/core/test_link_field_leakage.py +238 -0
- framework_m-0.2.5/tests/core/test_link_fields.py +475 -0
- framework_m-0.2.5/tests/core/test_meta_registry_overrides.py +274 -0
- framework_m-0.2.5/tests/core/test_naming_series.py +670 -0
- framework_m-0.2.5/tests/core/test_notification.py +151 -0
- framework_m-0.2.5/tests/core/test_object_level_permissions.py +289 -0
- framework_m-0.2.5/tests/core/test_outbox.py +114 -0
- framework_m-0.2.5/tests/core/test_permission_config.py +229 -0
- framework_m-0.2.5/tests/core/test_permission_conveniences.py +293 -0
- framework_m-0.2.5/tests/core/test_permission_lookup.py +252 -0
- framework_m-0.2.5/tests/core/test_pii.py +197 -0
- framework_m-0.2.5/tests/core/test_print_format.py +183 -0
- framework_m-0.2.5/tests/core/test_rls.py +250 -0
- framework_m-0.2.5/tests/core/test_rpc_decorator.py +205 -0
- framework_m-0.2.5/tests/core/test_schema_extension.py +579 -0
- framework_m-0.2.5/tests/core/test_session.py +269 -0
- framework_m-0.2.5/tests/core/test_share_lookup.py +183 -0
- framework_m-0.2.5/tests/core/test_system_context.py +125 -0
- framework_m-0.2.5/tests/core/test_system_settings.py +141 -0
- framework_m-0.2.5/tests/core/test_table_alteration.py +503 -0
- framework_m-0.2.5/tests/core/test_team_based_access.py +244 -0
- framework_m-0.2.5/tests/core/test_tenant.py +177 -0
- framework_m-0.2.5/tests/core/test_unit_of_work.py +156 -0
- framework_m-0.2.5/tests/core/test_validation.py +301 -0
- framework_m-0.2.5/tests/core/test_virtual_fields.py +461 -0
- framework_m-0.2.5/tests/core/test_whitelist_decorator.py +162 -0
- framework_m-0.2.5/tests/core/types/test_job_context.py +122 -0
- framework_m-0.2.5/tests/helpers/__init__.py +1 -0
- framework_m-0.2.5/tests/integration/__init__.py +5 -0
- framework_m-0.2.5/tests/integration/test_api_endpoints.py +297 -0
- framework_m-0.2.5/tests/integration/test_app_ports.py +232 -0
- framework_m-0.2.5/tests/integration/test_child_table_integration.py +235 -0
- framework_m-0.2.5/tests/integration/test_crud_flow.py +235 -0
- framework_m-0.2.5/tests/integration/test_jobs_events_webhooks.py +292 -0
- framework_m-0.2.5/tests/integration/test_migration_flow.py +198 -0
- framework_m-0.2.5/tests/integration/test_override_migration.py +213 -0
- framework_m-0.2.5/tests/integration/test_postgres_flow.py +236 -0
- framework_m-0.2.5/tests/integration/test_real_http_client.py +172 -0
- framework_m-0.2.5/tests/integration/test_workflow_lifecycle.py +546 -0
- framework_m-0.2.5/tests/unit/core/domain/test_base_controller.py +481 -0
- framework_m-0.2.5/tests/unit/core/domain/test_mixins.py +121 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_audit.py +261 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_auth_context.py +176 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_event_bus.py +97 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_i18n.py +685 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_job_queue.py +131 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_permission.py +75 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_print.py +28 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_repository.py +188 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_search.py +73 -0
- framework_m-0.2.5/tests/unit/core/interfaces/test_storage.py +200 -0
- framework_m-0.2.5/tests/unit/core/test_registry.py +340 -0
- framework_m-0.2.5/tests/unit/test_base_doctype.py +294 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
.history/
|
|
23
|
+
# static/ - removed generic ignore, specific ignores added below
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.venv/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
env/
|
|
30
|
+
|
|
31
|
+
# UV
|
|
32
|
+
.uv/
|
|
33
|
+
uv.lock
|
|
34
|
+
|
|
35
|
+
# IDE
|
|
36
|
+
.idea/
|
|
37
|
+
.vscode/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
*~
|
|
41
|
+
|
|
42
|
+
# Testing
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
.coverage
|
|
45
|
+
htmlcov/
|
|
46
|
+
.tox/
|
|
47
|
+
.nox/
|
|
48
|
+
coverage.xml
|
|
49
|
+
|
|
50
|
+
# Type checking
|
|
51
|
+
.mypy_cache/
|
|
52
|
+
.dmypy.json
|
|
53
|
+
dmypy.json
|
|
54
|
+
|
|
55
|
+
# Ruff
|
|
56
|
+
.ruff_cache/
|
|
57
|
+
|
|
58
|
+
# OS
|
|
59
|
+
.DS_Store
|
|
60
|
+
Thumbs.db
|
|
61
|
+
|
|
62
|
+
# Logs
|
|
63
|
+
*.log
|
|
64
|
+
|
|
65
|
+
# Local config
|
|
66
|
+
.env
|
|
67
|
+
.env.local
|
|
68
|
+
|
|
69
|
+
# Docker
|
|
70
|
+
docker-compose.override.yml
|
|
71
|
+
|
|
72
|
+
# SQLite databases
|
|
73
|
+
*.db
|
|
74
|
+
*.sqlite
|
|
75
|
+
*.sqlite3
|
|
76
|
+
|
|
77
|
+
# Studio UI built assets
|
|
78
|
+
apps/studio/src/framework_m_studio/static/
|
|
79
|
+
|
|
80
|
+
#doctypes
|
|
81
|
+
doctypes/*.py
|
|
82
|
+
apps/studio/src/doctypes/*.py
|
|
83
|
+
|
|
84
|
+
# Node.js / Frontend
|
|
85
|
+
node_modules/
|
|
86
|
+
.pnpm-store/
|
|
87
|
+
*.tsbuildinfo
|
|
88
|
+
|
|
89
|
+
# Frontend build outputs
|
|
90
|
+
frontend/dist/
|
|
91
|
+
frontend/.vite/
|
|
92
|
+
apps/*/studio_ui/dist/
|
|
93
|
+
apps/*/studio_ui/.vite/
|
|
94
|
+
frontend/playwright-report
|
|
95
|
+
frontend/test-results
|
|
96
|
+
apps/studio/studio_ui/node_modules/
|
|
97
|
+
|
|
98
|
+
# Logs
|
|
99
|
+
npm-debug.log*
|
|
100
|
+
pnpm-debug.log*
|
|
101
|
+
yarn-debug.log*
|
|
102
|
+
yarn-error.log*
|
|
103
|
+
|
|
104
|
+
# Editor directories
|
|
105
|
+
.idea/
|
|
106
|
+
*.sublime-project
|
|
107
|
+
*.sublime-workspace
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## framework-m v0.2.5
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- add pypi and pipeline badges to readme (62590fc)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## framework-m v0.2.4
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- robust package detection and safe MR title truncation (36385b6)
|
|
15
|
+
- improve changelog extraction for GitLab release pages (bb636b0)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## framework-m v0.2.3
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- use show-ref for robust tag check and clear local ghost tags (79563c5)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## framework-m v0.2.2
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
- finalize air-tight release automation with GitLab releases, professional logging, and zero-spam logic (0dc7b19)
|
|
30
|
+
- simplify release rules and regex to stop recursive loops (790b318)
|
|
31
|
+
- fix auto-tagging trigger and regex for merge commits (5e69fb9)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## framework-m v0.2.1
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
- improve commit filtering and fix linting (6e4082d)
|
|
39
|
+
- prevent duplicate changelog entries by ensuring tags are fetched and handled correctly (a498f85)
|
|
40
|
+
- make release tag parsing more robust for large monorepos (8e1b5d8)
|
|
41
|
+
- update project URLs to GitLab and refactor versioning source of truth (84e0bd3)
|
|
42
|
+
- prevent recursive release loops and cleanup dead code (6ff3776)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## framework-m 0.2.0
|
|
46
|
+
|
|
47
|
+
### Features
|
|
48
|
+
|
|
49
|
+
- add unique constraint support and refine docs (5f9af98)
|
|
50
|
+
- add PyPI publishing for framework-m-studio and update docs (d6ed80a)
|
|
51
|
+
- comprehensive documentation covering fundamentals, migration guides, i18n, multi-tenancy usage, and API references (6a2c1df)
|
|
52
|
+
- implement Frontend Build & Serving (9f9aa79)
|
|
53
|
+
- implement desk ui (13ebcc8)
|
|
54
|
+
- implement workflows and advanced features (22a7745)
|
|
55
|
+
- implement system doctypes and features (05e7f3d)
|
|
56
|
+
- implement built-in doctypes and system adapters (23195d1)
|
|
57
|
+
- cli tools implementation (18a1d83)
|
|
58
|
+
- implement events, webhooks, monitoring and websockets (9381d3f)
|
|
59
|
+
- phase-03 complete (00123da)
|
|
60
|
+
- prepare for package split after completion (e8abae2)
|
|
61
|
+
- permission system implemented (632afb7)
|
|
62
|
+
- litestar application setup and authentication middleware (7854664)
|
|
63
|
+
- Complete DocType Engine & Database Layer (523f211)
|
|
64
|
+
- refactor phase-01 and implemented doctype-engine with CRUD, migrations and cli (3c36234)
|
|
65
|
+
- complete Phase 01 - Core Kernel & Interfaces (1dcbfab)
|
|
66
|
+
- automated pipeline for gitlab registry (c1a9e2b)
|
|
67
|
+
|
|
68
|
+
### Bug Fixes
|
|
69
|
+
|
|
70
|
+
- remove create-studio-release-mr and detached HEAD (d814206)
|
|
71
|
+
- lint issues (0c1dc94)
|
|
72
|
+
- studio issues and ci pipeline (e17e9c2)
|
|
73
|
+
- ruff issue (24fb2ef)
|
|
74
|
+
- ruff issue (2b3dfb0)
|
|
75
|
+
- mypy issues (23c539b)
|
|
76
|
+
- Fix ruff linting errors (ad8997c)
|
|
77
|
+
- lint format (8fc33e8)
|
|
78
|
+
- format with ruff (c9d5f39)
|
|
79
|
+
- mypy issues (5ab1715)
|
|
80
|
+
- format all files with ruff (90e3808)
|
|
81
|
+
- remove skip ci from release commit message (2db2b6f)
|
|
82
|
+
- correct directory navigation in release-package job (5b67a98)
|
|
83
|
+
- lint error in base_doctype (47e8c37)
|
|
84
|
+
- lint error in test_base_doctype (354f66f)
|
|
85
|
+
- use twine for GitLab registry publishing (6472dc7)
|
|
86
|
+
- specify dist path for uv publish (86df5c7)
|
|
87
|
+
- exclude cache directories from source (695d2fb)
|
|
88
|
+
- lint errors in tests (8b4120d)
|
|
89
|
+
- rename workspace to avoid package name conflict (20e46bb)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
## framework-m 0.1.0
|
|
93
|
+
|
|
94
|
+
### Features
|
|
95
|
+
|
|
96
|
+
- Initial release of Framework M
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: framework-m
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Summary: A modern, metadata-driven business application framework
|
|
5
|
+
Project-URL: Homepage, https://gitlab.com/castlecraft/framework-m
|
|
6
|
+
Project-URL: Documentation, https://gitlab.com/castlecraft/framework-m#readme
|
|
7
|
+
Project-URL: Repository, https://gitlab.com/castlecraft/framework-m
|
|
8
|
+
Author: Framework M Contributors
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: async,business,doctype,framework,metadata
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: aioboto3>=15.5.0
|
|
21
|
+
Requires-Dist: aiofiles>=25.1.0
|
|
22
|
+
Requires-Dist: alembic>=1.13.0
|
|
23
|
+
Requires-Dist: argon2-cffi>=23.1.0
|
|
24
|
+
Requires-Dist: asyncpg>=0.29.0
|
|
25
|
+
Requires-Dist: boto3-stubs>=1.42.21
|
|
26
|
+
Requires-Dist: botocore-stubs>=1.42.21
|
|
27
|
+
Requires-Dist: cyclopts>=3.0.0
|
|
28
|
+
Requires-Dist: dependency-injector>=4.41.0
|
|
29
|
+
Requires-Dist: litestar[standard]>=2.0.0
|
|
30
|
+
Requires-Dist: nats-py>=2.0.0
|
|
31
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
32
|
+
Requires-Dist: pydantic>=2.0.0
|
|
33
|
+
Requires-Dist: pyjwt>=2.8.0
|
|
34
|
+
Requires-Dist: redis>=5.0.0
|
|
35
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.0
|
|
36
|
+
Requires-Dist: taskiq-nats>=0.4.0
|
|
37
|
+
Requires-Dist: taskiq>=0.11.0
|
|
38
|
+
Requires-Dist: types-aiobotocore>=3.1.0
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# Framework M
|
|
42
|
+
|
|
43
|
+
A modern, metadata-driven business application framework in Python 3.12+.
|
|
44
|
+
|
|
45
|
+
[](https://www.python.org/downloads/)
|
|
46
|
+
[](https://badge.fury.io/py/framework-m)
|
|
47
|
+
[](https://gitlab.com/castlecraft/framework-m/-/pipelines)
|
|
48
|
+
[](https://opensource.org/licenses/MIT)
|
|
49
|
+
[](https://github.com/astral-sh/ruff)
|
|
50
|
+
[](https://mypy-lang.org/)
|
|
51
|
+
|
|
52
|
+
## Overview
|
|
53
|
+
|
|
54
|
+
Framework M is inspired by [Frappe Framework](https://frappeframework.com/) but built from scratch with modern Python practices:
|
|
55
|
+
|
|
56
|
+
- **Hexagonal Architecture**: Clean separation via Ports & Adapters
|
|
57
|
+
- **Async-First**: Native asyncio with Litestar and SQLAlchemy
|
|
58
|
+
- **Type-Safe**: 100% type hints, mypy strict compatible
|
|
59
|
+
- **Stateless**: JWT/Token auth, no server-side sessions
|
|
60
|
+
- **Metadata-Driven**: Define DocTypes as Pydantic models
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install framework-m
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or with `uv`:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv add framework-m
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
### 1. Define a DocType
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from framework_m import DocType, Field
|
|
80
|
+
|
|
81
|
+
class Todo(DocType):
|
|
82
|
+
"""A simple task document."""
|
|
83
|
+
|
|
84
|
+
title: str = Field(description="Task title")
|
|
85
|
+
description: str | None = Field(default=None, description="Task details")
|
|
86
|
+
is_completed: bool = Field(default=False, description="Completion status")
|
|
87
|
+
priority: int = Field(default=1, ge=1, le=5, description="Priority (1-5)")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Use the CLI
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Show version
|
|
94
|
+
m --version
|
|
95
|
+
|
|
96
|
+
# Show framework info
|
|
97
|
+
m info
|
|
98
|
+
|
|
99
|
+
# Start development server (coming soon)
|
|
100
|
+
m start
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Features
|
|
104
|
+
|
|
105
|
+
### Metadata-Driven DocTypes
|
|
106
|
+
|
|
107
|
+
DocTypes are Pydantic models with automatic:
|
|
108
|
+
- Database table generation
|
|
109
|
+
- REST API endpoints
|
|
110
|
+
- JSON Schema for frontends
|
|
111
|
+
- Validation and serialization
|
|
112
|
+
|
|
113
|
+
### Hexagonal Architecture
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
117
|
+
│ Primary Adapters │
|
|
118
|
+
│ (HTTP API, CLI, WebSocket, Background Jobs) │
|
|
119
|
+
└─────────────────────────────────────────────────────────────┘
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
123
|
+
│ Core Domain │
|
|
124
|
+
│ (DocTypes, Controllers, Business Logic) │
|
|
125
|
+
│ │
|
|
126
|
+
│ ┌─────────────┐ ┌───────────────┐ ┌──────────────┐ │
|
|
127
|
+
│ │ BaseDocType │ │ BaseController│ │ MetaRegistry │ │
|
|
128
|
+
│ └─────────────┘ └───────────────┘ └──────────────┘ │
|
|
129
|
+
└─────────────────────────────────────────────────────────────┘
|
|
130
|
+
│
|
|
131
|
+
▼
|
|
132
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
133
|
+
│ Ports (Interfaces) │
|
|
134
|
+
│ RepositoryProtocol │ EventBusProtocol │ PermissionProtocol │
|
|
135
|
+
│ StorageProtocol │ JobQueueProtocol │ CacheProtocol │
|
|
136
|
+
└─────────────────────────────────────────────────────────────┘
|
|
137
|
+
│
|
|
138
|
+
▼
|
|
139
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
140
|
+
│ Secondary Adapters │
|
|
141
|
+
│ (PostgreSQL, Redis, S3, SMTP, External APIs) │
|
|
142
|
+
└─────────────────────────────────────────────────────────────┘
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Built-in Protocols
|
|
146
|
+
|
|
147
|
+
| Protocol | Purpose |
|
|
148
|
+
|----------|---------|
|
|
149
|
+
| `RepositoryProtocol` | CRUD operations for documents |
|
|
150
|
+
| `EventBusProtocol` | Publish/subscribe events |
|
|
151
|
+
| `PermissionProtocol` | Authorization with RLS |
|
|
152
|
+
| `StorageProtocol` | File storage abstraction |
|
|
153
|
+
| `JobQueueProtocol` | Background job processing |
|
|
154
|
+
| `CacheProtocol` | Caching layer |
|
|
155
|
+
| `NotificationProtocol` | Email/SMS notifications |
|
|
156
|
+
| `SearchProtocol` | Full-text search |
|
|
157
|
+
| `PrintProtocol` | PDF generation |
|
|
158
|
+
| `I18nProtocol` | Internationalization |
|
|
159
|
+
|
|
160
|
+
### Extensibility
|
|
161
|
+
|
|
162
|
+
Override any adapter via Python entrypoints:
|
|
163
|
+
|
|
164
|
+
```toml
|
|
165
|
+
# pyproject.toml
|
|
166
|
+
[project.entry-points."framework_m.overrides"]
|
|
167
|
+
repository = "my_app.adapters:CustomRepository"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Technology Stack
|
|
171
|
+
|
|
172
|
+
- **Web Framework**: [Litestar](https://litestar.dev/) 2.0+
|
|
173
|
+
- **ORM**: [SQLAlchemy](https://www.sqlalchemy.org/) 2.0 (Async)
|
|
174
|
+
- **Validation**: [Pydantic](https://docs.pydantic.dev/) V2
|
|
175
|
+
- **Task Queue**: [Taskiq](https://taskiq-python.github.io/) + NATS JetStream
|
|
176
|
+
- **DI Container**: [dependency-injector](https://python-dependency-injector.ets-labs.org/)
|
|
177
|
+
- **Database**: PostgreSQL (default), SQLite (testing)
|
|
178
|
+
- **Cache/Events**: Redis
|
|
179
|
+
|
|
180
|
+
## Project Structure
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
libs/framework-m/
|
|
184
|
+
├── src/framework_m/
|
|
185
|
+
│ ├── core/
|
|
186
|
+
│ │ ├── domain/ # DocType, Controller, Mixins
|
|
187
|
+
│ │ └── interfaces/ # Protocol definitions (Ports)
|
|
188
|
+
│ ├── adapters/ # Infrastructure implementations
|
|
189
|
+
│ ├── cli/ # CLI commands
|
|
190
|
+
│ └── public/ # Built-in DocTypes
|
|
191
|
+
└── tests/
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Development
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Clone and setup
|
|
198
|
+
git clone https://gitlab.com/castlecraft/framework-m.git
|
|
199
|
+
cd framework-m
|
|
200
|
+
|
|
201
|
+
# Install dependencies
|
|
202
|
+
uv sync --all-extras
|
|
203
|
+
|
|
204
|
+
# Run tests
|
|
205
|
+
uv run pytest
|
|
206
|
+
|
|
207
|
+
# Type checking
|
|
208
|
+
uv run mypy src/framework_m --strict
|
|
209
|
+
|
|
210
|
+
# Linting
|
|
211
|
+
uv run ruff check .
|
|
212
|
+
uv run ruff format .
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Documentation
|
|
216
|
+
|
|
217
|
+
- [Architecture Overview](https://gitlab.com/castlecraft/framework-m/blob/main/ARCHITECTURE.md)
|
|
218
|
+
- [Contributing Guide](https://gitlab.com/castlecraft/framework-m/blob/main/CONTRIBUTING.md)
|
|
219
|
+
- [Phase Checklists](https://gitlab.com/castlecraft/framework-m/tree/main/checklists)
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT License - see [LICENSE](https://gitlab.com/castlecraft/framework-m/blob/main/LICENSE) for details.
|
|
224
|
+
|
|
225
|
+
## Acknowledgments
|
|
226
|
+
|
|
227
|
+
Inspired by [Frappe Framework](https://frappeframework.com/), reimagined with:
|
|
228
|
+
- Modern Python (3.12+, async/await, type hints)
|
|
229
|
+
- Clean architecture (Hexagonal/Ports & Adapters)
|
|
230
|
+
- No global state (Dependency Injection)
|
|
231
|
+
- Code-first schemas (Pydantic, not database JSON)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Framework M
|
|
2
|
+
|
|
3
|
+
A modern, metadata-driven business application framework in Python 3.12+.
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](https://badge.fury.io/py/framework-m)
|
|
7
|
+
[](https://gitlab.com/castlecraft/framework-m/-/pipelines)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://github.com/astral-sh/ruff)
|
|
10
|
+
[](https://mypy-lang.org/)
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
Framework M is inspired by [Frappe Framework](https://frappeframework.com/) but built from scratch with modern Python practices:
|
|
15
|
+
|
|
16
|
+
- **Hexagonal Architecture**: Clean separation via Ports & Adapters
|
|
17
|
+
- **Async-First**: Native asyncio with Litestar and SQLAlchemy
|
|
18
|
+
- **Type-Safe**: 100% type hints, mypy strict compatible
|
|
19
|
+
- **Stateless**: JWT/Token auth, no server-side sessions
|
|
20
|
+
- **Metadata-Driven**: Define DocTypes as Pydantic models
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install framework-m
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with `uv`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv add framework-m
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Define a DocType
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from framework_m import DocType, Field
|
|
40
|
+
|
|
41
|
+
class Todo(DocType):
|
|
42
|
+
"""A simple task document."""
|
|
43
|
+
|
|
44
|
+
title: str = Field(description="Task title")
|
|
45
|
+
description: str | None = Field(default=None, description="Task details")
|
|
46
|
+
is_completed: bool = Field(default=False, description="Completion status")
|
|
47
|
+
priority: int = Field(default=1, ge=1, le=5, description="Priority (1-5)")
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Use the CLI
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Show version
|
|
54
|
+
m --version
|
|
55
|
+
|
|
56
|
+
# Show framework info
|
|
57
|
+
m info
|
|
58
|
+
|
|
59
|
+
# Start development server (coming soon)
|
|
60
|
+
m start
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Features
|
|
64
|
+
|
|
65
|
+
### Metadata-Driven DocTypes
|
|
66
|
+
|
|
67
|
+
DocTypes are Pydantic models with automatic:
|
|
68
|
+
- Database table generation
|
|
69
|
+
- REST API endpoints
|
|
70
|
+
- JSON Schema for frontends
|
|
71
|
+
- Validation and serialization
|
|
72
|
+
|
|
73
|
+
### Hexagonal Architecture
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
77
|
+
│ Primary Adapters │
|
|
78
|
+
│ (HTTP API, CLI, WebSocket, Background Jobs) │
|
|
79
|
+
└─────────────────────────────────────────────────────────────┘
|
|
80
|
+
│
|
|
81
|
+
▼
|
|
82
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
83
|
+
│ Core Domain │
|
|
84
|
+
│ (DocTypes, Controllers, Business Logic) │
|
|
85
|
+
│ │
|
|
86
|
+
│ ┌─────────────┐ ┌───────────────┐ ┌──────────────┐ │
|
|
87
|
+
│ │ BaseDocType │ │ BaseController│ │ MetaRegistry │ │
|
|
88
|
+
│ └─────────────┘ └───────────────┘ └──────────────┘ │
|
|
89
|
+
└─────────────────────────────────────────────────────────────┘
|
|
90
|
+
│
|
|
91
|
+
▼
|
|
92
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
93
|
+
│ Ports (Interfaces) │
|
|
94
|
+
│ RepositoryProtocol │ EventBusProtocol │ PermissionProtocol │
|
|
95
|
+
│ StorageProtocol │ JobQueueProtocol │ CacheProtocol │
|
|
96
|
+
└─────────────────────────────────────────────────────────────┘
|
|
97
|
+
│
|
|
98
|
+
▼
|
|
99
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
100
|
+
│ Secondary Adapters │
|
|
101
|
+
│ (PostgreSQL, Redis, S3, SMTP, External APIs) │
|
|
102
|
+
└─────────────────────────────────────────────────────────────┘
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Built-in Protocols
|
|
106
|
+
|
|
107
|
+
| Protocol | Purpose |
|
|
108
|
+
|----------|---------|
|
|
109
|
+
| `RepositoryProtocol` | CRUD operations for documents |
|
|
110
|
+
| `EventBusProtocol` | Publish/subscribe events |
|
|
111
|
+
| `PermissionProtocol` | Authorization with RLS |
|
|
112
|
+
| `StorageProtocol` | File storage abstraction |
|
|
113
|
+
| `JobQueueProtocol` | Background job processing |
|
|
114
|
+
| `CacheProtocol` | Caching layer |
|
|
115
|
+
| `NotificationProtocol` | Email/SMS notifications |
|
|
116
|
+
| `SearchProtocol` | Full-text search |
|
|
117
|
+
| `PrintProtocol` | PDF generation |
|
|
118
|
+
| `I18nProtocol` | Internationalization |
|
|
119
|
+
|
|
120
|
+
### Extensibility
|
|
121
|
+
|
|
122
|
+
Override any adapter via Python entrypoints:
|
|
123
|
+
|
|
124
|
+
```toml
|
|
125
|
+
# pyproject.toml
|
|
126
|
+
[project.entry-points."framework_m.overrides"]
|
|
127
|
+
repository = "my_app.adapters:CustomRepository"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Technology Stack
|
|
131
|
+
|
|
132
|
+
- **Web Framework**: [Litestar](https://litestar.dev/) 2.0+
|
|
133
|
+
- **ORM**: [SQLAlchemy](https://www.sqlalchemy.org/) 2.0 (Async)
|
|
134
|
+
- **Validation**: [Pydantic](https://docs.pydantic.dev/) V2
|
|
135
|
+
- **Task Queue**: [Taskiq](https://taskiq-python.github.io/) + NATS JetStream
|
|
136
|
+
- **DI Container**: [dependency-injector](https://python-dependency-injector.ets-labs.org/)
|
|
137
|
+
- **Database**: PostgreSQL (default), SQLite (testing)
|
|
138
|
+
- **Cache/Events**: Redis
|
|
139
|
+
|
|
140
|
+
## Project Structure
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
libs/framework-m/
|
|
144
|
+
├── src/framework_m/
|
|
145
|
+
│ ├── core/
|
|
146
|
+
│ │ ├── domain/ # DocType, Controller, Mixins
|
|
147
|
+
│ │ └── interfaces/ # Protocol definitions (Ports)
|
|
148
|
+
│ ├── adapters/ # Infrastructure implementations
|
|
149
|
+
│ ├── cli/ # CLI commands
|
|
150
|
+
│ └── public/ # Built-in DocTypes
|
|
151
|
+
└── tests/
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Development
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Clone and setup
|
|
158
|
+
git clone https://gitlab.com/castlecraft/framework-m.git
|
|
159
|
+
cd framework-m
|
|
160
|
+
|
|
161
|
+
# Install dependencies
|
|
162
|
+
uv sync --all-extras
|
|
163
|
+
|
|
164
|
+
# Run tests
|
|
165
|
+
uv run pytest
|
|
166
|
+
|
|
167
|
+
# Type checking
|
|
168
|
+
uv run mypy src/framework_m --strict
|
|
169
|
+
|
|
170
|
+
# Linting
|
|
171
|
+
uv run ruff check .
|
|
172
|
+
uv run ruff format .
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Documentation
|
|
176
|
+
|
|
177
|
+
- [Architecture Overview](https://gitlab.com/castlecraft/framework-m/blob/main/ARCHITECTURE.md)
|
|
178
|
+
- [Contributing Guide](https://gitlab.com/castlecraft/framework-m/blob/main/CONTRIBUTING.md)
|
|
179
|
+
- [Phase Checklists](https://gitlab.com/castlecraft/framework-m/tree/main/checklists)
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT License - see [LICENSE](https://gitlab.com/castlecraft/framework-m/blob/main/LICENSE) for details.
|
|
184
|
+
|
|
185
|
+
## Acknowledgments
|
|
186
|
+
|
|
187
|
+
Inspired by [Frappe Framework](https://frappeframework.com/), reimagined with:
|
|
188
|
+
- Modern Python (3.12+, async/await, type hints)
|
|
189
|
+
- Clean architecture (Hexagonal/Ports & Adapters)
|
|
190
|
+
- No global state (Dependency Injection)
|
|
191
|
+
- Code-first schemas (Pydantic, not database JSON)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Generic single-database configuration.
|