jac-scale 0.1.0__tar.gz → 0.1.1__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 (64) hide show
  1. {jac_scale-0.1.0 → jac_scale-0.1.1}/PKG-INFO +2 -2
  2. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/memory_hierarchy.main.impl.jac +2 -2
  3. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/serve.impl.jac +37 -57
  4. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/jserver/impl/jfast_api.impl.jac +50 -2
  5. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/jserver/jfast_api.jac +1 -0
  6. jac_scale-0.1.1/jac_scale/serve.jac +118 -0
  7. jac_scale-0.1.1/jac_scale/utilities/loggers/standard_logger.jac +40 -0
  8. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/PKG-INFO +2 -2
  9. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/requires.txt +1 -1
  10. {jac_scale-0.1.0 → jac_scale-0.1.1}/pyproject.toml +2 -2
  11. jac_scale-0.1.0/jac_scale/serve.jac +0 -148
  12. jac_scale-0.1.0/jac_scale/utilities/loggers/standard_logger.jac +0 -56
  13. {jac_scale-0.1.0 → jac_scale-0.1.1}/README.md +0 -0
  14. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/__init__.py +0 -0
  15. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/config/app_config.jac +0 -0
  16. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/config/base_config.jac +0 -0
  17. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/database_provider.jac +0 -0
  18. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/deployment_target.jac +0 -0
  19. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/image_registry.jac +0 -0
  20. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/logger.jac +0 -0
  21. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/models/deployment_result.jac +0 -0
  22. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/abstractions/models/resource_status.jac +0 -0
  23. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/config_loader.jac +0 -0
  24. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/context.jac +0 -0
  25. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/factories/database_factory.jac +0 -0
  26. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/factories/deployment_factory.jac +0 -0
  27. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/factories/registry_factory.jac +0 -0
  28. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/factories/utility_factory.jac +0 -0
  29. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/config_loader.impl.jac +0 -0
  30. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/context.impl.jac +0 -0
  31. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/memory_hierarchy.mongo.impl.jac +0 -0
  32. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/impl/memory_hierarchy.redis.impl.jac +0 -0
  33. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/jserver/__init__.py +0 -0
  34. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/jserver/impl/jserver.impl.jac +0 -0
  35. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/jserver/jserver.jac +0 -0
  36. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/memory_hierarchy.jac +0 -0
  37. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/plugin.jac +0 -0
  38. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/plugin_config.jac +0 -0
  39. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/providers/database/kubernetes_mongo.jac +0 -0
  40. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/providers/database/kubernetes_redis.jac +0 -0
  41. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/providers/registry/dockerhub.jac +0 -0
  42. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/targets/kubernetes/kubernetes_config.jac +0 -0
  43. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/targets/kubernetes/kubernetes_target.jac +0 -0
  44. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/targets/kubernetes/utils/kubernetes_utils.impl.jac +0 -0
  45. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/targets/kubernetes/utils/kubernetes_utils.jac +0 -0
  46. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/__init__.py +0 -0
  47. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/conftest.py +0 -0
  48. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/fixtures/test_api.jac +0 -0
  49. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/fixtures/todo_app.jac +0 -0
  50. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_abstractions.py +0 -0
  51. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_deploy_k8s.py +0 -0
  52. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_examples.py +0 -0
  53. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_factories.py +0 -0
  54. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_file_upload.py +0 -0
  55. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_k8s_utils.py +0 -0
  56. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_memory_hierarchy.py +0 -0
  57. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_serve.py +0 -0
  58. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/tests/test_sso.py +0 -0
  59. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale/utils.jac +0 -0
  60. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/SOURCES.txt +0 -0
  61. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/dependency_links.txt +0 -0
  62. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/entry_points.txt +0 -0
  63. {jac_scale-0.1.0 → jac_scale-0.1.1}/jac_scale.egg-info/top_level.txt +0 -0
  64. {jac_scale-0.1.0 → jac_scale-0.1.1}/setup.cfg +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jac-scale
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Author-email: Jason Mars <jason@mars.ninja>
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
- Requires-Dist: jaclang>=0.9.9
7
+ Requires-Dist: jaclang>=0.9.10
8
8
  Requires-Dist: python-dotenv<2.0.0,>=1.2.1
9
9
  Requires-Dist: docker<8.0.0,>=7.1.0
10
10
  Requires-Dist: kubernetes<35.0.0,>=34.1.0
@@ -31,7 +31,7 @@ impl ScaleTieredMemory.init(use_cache: bool = True) -> None {
31
31
  # Show subtle message (optional - uncomment to enable)
32
32
  try {
33
33
  import from jaclang.cli.console { console }
34
- console.print(" ✔ Using MongoDB for persistence", style="muted");
34
+ logger.debug(" ✔ Using MongoDB for persistence", style="muted");
35
35
  } except Exception { }
36
36
  } else {
37
37
  # Fall back to jaclang's SqliteMemory using configured path
@@ -41,7 +41,7 @@ impl ScaleTieredMemory.init(use_cache: bool = True) -> None {
41
41
  # Show subtle message
42
42
  try {
43
43
  import from jaclang.cli.console { console }
44
- console.print(" ✔ Using SQLite for persistence", style="muted");
44
+ logger.debug(" ✔ Using SQLite for persistence", style="muted");
45
45
  } except Exception { }
46
46
  }
47
47
  }
@@ -57,7 +57,7 @@ def _transport_response_to_json_response(
57
57
  );
58
58
  }
59
59
 
60
- impl JacAPIServer.start(self: JacAPIServer, dev: bool = False) -> None {
60
+ impl JacAPIServer.start(dev: bool = False) -> None {
61
61
  self.introspector.load();
62
62
  # Eagerly build client bundle if there are client exports (skip in dev mode)
63
63
  if not dev {
@@ -112,7 +112,7 @@ impl JacAPIServer.start(self: JacAPIServer, dev: bool = False) -> None {
112
112
  }
113
113
 
114
114
  """Configure OpenAPI security scheme to only apply to walker endpoints that require auth."""
115
- impl JacAPIServer._configure_openapi_security(self: JacAPIServer) -> None {
115
+ impl JacAPIServer._configure_openapi_security -> None {
116
116
  import from fastapi.openapi.utils { get_openapi }
117
117
  def custom_openapi -> dict[str, Any] {
118
118
  if self.server.app.openapi_schema {
@@ -178,7 +178,7 @@ impl JacAPIServer._configure_openapi_security(self: JacAPIServer) -> None {
178
178
  }
179
179
 
180
180
  """Serve root-level assets like /img.png, /icons/logo.svg, etc."""
181
- impl JacAPIServer.serve_root_asset(self: JacAPIServer, file_path: str) -> Response {
181
+ impl JacAPIServer.serve_root_asset(file_path: str) -> Response {
182
182
  allowed_extensions = {'.png','.jpg','.jpeg','.gif','.webp','.svg','.ico','.woff','.woff2','.ttf','.otf','.eot','.mp4','.webm','.mp3','.wav','.css','.js','.json','.pdf','.txt','.xml'};
183
183
  file_ext = Path(file_path).suffix.lower();
184
184
  if (not file_ext or (file_ext not in allowed_extensions)) {
@@ -235,7 +235,7 @@ impl JacAPIServer.serve_root_asset(self: JacAPIServer, file_path: str) -> Respon
235
235
  }
236
236
 
237
237
  """Register root-level asset serving endpoint for files like /img.png, /logo.svg"""
238
- impl JacAPIServer.register_root_asset_endpoint(self: JacAPIServer) -> None {
238
+ impl JacAPIServer.register_root_asset_endpoint -> None {
239
239
  self.server.add_endpoint(
240
240
  JEndPoint(
241
241
  method=HTTPMethod.GET,
@@ -260,7 +260,7 @@ impl JacAPIServer.register_root_asset_endpoint(self: JacAPIServer) -> None {
260
260
  }
261
261
 
262
262
  """Serve a static file given its path."""
263
- impl JacAPIServer.serve_static_file(self: JacAPIServer, file_path: str) -> Response {
263
+ impl JacAPIServer.serve_static_file(file_path: str) -> Response {
264
264
  try {
265
265
  # Find project root (where jac.toml is) instead of using base_path_dir
266
266
  # base_path_dir might be src/ when serving src/app.jac, but we need project root
@@ -338,7 +338,7 @@ impl JacAPIServer.serve_static_file(self: JacAPIServer, file_path: str) -> Respo
338
338
  }
339
339
 
340
340
  """Register the static file serving endpoint using JEndPoint."""
341
- impl JacAPIServer.register_static_file_endpoint(self: JacAPIServer) -> None {
341
+ impl JacAPIServer.register_static_file_endpoint -> None {
342
342
  self.server.add_endpoint(
343
343
  JEndPoint(
344
344
  method=HTTPMethod.GET,
@@ -363,7 +363,7 @@ impl JacAPIServer.register_static_file_endpoint(self: JacAPIServer) -> None {
363
363
  }
364
364
 
365
365
  """Register the client.js serving endpoint using JEndPoint."""
366
- impl JacAPIServer.register_client_js_endpoint(self: JacAPIServer) -> None {
366
+ impl JacAPIServer.register_client_js_endpoint -> None {
367
367
  self.server.add_endpoint(
368
368
  JEndPoint(
369
369
  method=HTTPMethod.GET,
@@ -379,9 +379,7 @@ impl JacAPIServer.register_client_js_endpoint(self: JacAPIServer) -> None {
379
379
  }
380
380
 
381
381
  """Create callback to serve the client.js file."""
382
- impl JacAPIServer.serve_client_js_callback(
383
- self: JacAPIServer
384
- ) -> Callable[..., Response] {
382
+ impl JacAPIServer.serve_client_js_callback -> Callable[..., Response] {
385
383
  def callback -> Response {
386
384
  try {
387
385
  self.introspector.load();
@@ -398,7 +396,7 @@ impl JacAPIServer.serve_client_js_callback(
398
396
  }
399
397
 
400
398
  """Register the page rendering endpoint using JEndPoint."""
401
- impl JacAPIServer.register_page_endpoint(self: JacAPIServer) -> None {
399
+ impl JacAPIServer.register_page_endpoint -> None {
402
400
  import from jaclang.project.config { get_config }
403
401
  config = get_config();
404
402
  cl_route_prefix = config.serve.cl_route_prefix if config else "cl";
@@ -443,9 +441,7 @@ impl JacAPIServer.register_page_endpoint(self: JacAPIServer) -> None {
443
441
  }
444
442
 
445
443
  """Create callback that extracts all query parameters from FastAPI Request."""
446
- impl JacAPIServer.render_page_callback(
447
- self: JacAPIServer
448
- ) -> Callable[..., HTMLResponse] {
444
+ impl JacAPIServer.render_page_callback -> Callable[..., HTMLResponse] {
449
445
  """Render a page by name with all query parameters.""";
450
446
  def callback(page_name: str, **kwargs: JsonValue) -> HTMLResponse {
451
447
  try {
@@ -467,7 +463,7 @@ impl JacAPIServer.render_page_callback(
467
463
 
468
464
  """Create callback for base route app rendering."""
469
465
  impl JacAPIServer.render_base_route_callback(
470
- self: JacAPIServer, app_name: str
466
+ app_name: str
471
467
  ) -> Callable[..., HTMLResponse] {
472
468
  """Render the base route app.""";
473
469
  def callback(**kwargs: JsonValue) -> HTMLResponse {
@@ -488,7 +484,7 @@ impl JacAPIServer.render_base_route_callback(
488
484
  return callback;
489
485
  }
490
486
 
491
- impl JacAPIServer.register_functions_endpoints(self: JacAPIServer) -> None {
487
+ impl JacAPIServer.register_functions_endpoints -> None {
492
488
  for func_name in self.get_functions() {
493
489
  self.server.add_endpoint(
494
490
  JEndPoint(
@@ -505,9 +501,7 @@ impl JacAPIServer.register_functions_endpoints(self: JacAPIServer) -> None {
505
501
  }
506
502
  }
507
503
 
508
- impl JacAPIServer.create_function_parameters(
509
- self: JacAPIServer, func_name: str
510
- ) -> list[APIParameter] {
504
+ impl JacAPIServer.create_function_parameters(func_name: str) -> list[APIParameter] {
511
505
  parameters: list[APIParameter] = [];
512
506
  if self.introspector.is_auth_required_for_function(func_name) {
513
507
  parameters.append(
@@ -548,7 +542,7 @@ impl JacAPIServer.create_function_parameters(
548
542
  }
549
543
 
550
544
  impl JacAPIServer.create_function_callback(
551
- self: JacAPIServer, func_name: str
545
+ func_name: str
552
546
  ) -> Callable[..., TransportResponse] {
553
547
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
554
548
  requires_auth = self.introspector.is_auth_required_for_function(func_name);
@@ -592,7 +586,7 @@ impl JacAPIServer.create_function_callback(
592
586
  return callback;
593
587
  }
594
588
 
595
- impl JacAPIServer.register_walkers_endpoints(self: JacAPIServer) -> None {
589
+ impl JacAPIServer.register_walkers_endpoints -> None {
596
590
  for walker_name in self.get_walkers() {
597
591
  self.server.add_endpoint(
598
592
  JEndPoint(
@@ -626,7 +620,7 @@ impl JacAPIServer.register_walkers_endpoints(self: JacAPIServer) -> None {
626
620
  }
627
621
 
628
622
  impl JacAPIServer.create_walker_parameters(
629
- self: JacAPIServer, walker_name: str, invoke_on_root: bool
623
+ walker_name: str, invoke_on_root: bool
630
624
  ) -> list[APIParameter] {
631
625
  parameters: list[APIParameter] = [];
632
626
  if self.introspector.is_auth_required_for_walker(walker_name) {
@@ -673,7 +667,7 @@ impl JacAPIServer.create_walker_parameters(
673
667
  }
674
668
 
675
669
  impl JacAPIServer.create_walker_callback(
676
- self: JacAPIServer, walker_name: str, has_node_param: bool = False
670
+ walker_name: str, has_node_param: bool = False
677
671
  ) -> Callable[..., TransportResponse] {
678
672
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
679
673
  requires_auth = self.introspector.is_auth_required_for_walker(walker_name);
@@ -721,7 +715,7 @@ impl JacAPIServer.create_walker_callback(
721
715
  return callback;
722
716
  }
723
717
 
724
- impl JacAPIServer.register_refresh_token_endpoint(self: JacAPIServer) -> None {
718
+ impl JacAPIServer.register_refresh_token_endpoint -> None {
725
719
  self.server.add_endpoint(
726
720
  JEndPoint(
727
721
  method=HTTPMethod.POST,
@@ -745,7 +739,7 @@ impl JacAPIServer.register_refresh_token_endpoint(self: JacAPIServer) -> None {
745
739
  );
746
740
  }
747
741
 
748
- impl JacAPIServer.register_create_user_endpoint(self: JacAPIServer) -> None {
742
+ impl JacAPIServer.register_create_user_endpoint -> None {
749
743
  self.server.add_endpoint(
750
744
  JEndPoint(
751
745
  method=HTTPMethod.POST,
@@ -777,9 +771,7 @@ impl JacAPIServer.register_create_user_endpoint(self: JacAPIServer) -> None {
777
771
  );
778
772
  }
779
773
 
780
- impl JacAPIServer.refresh_token(
781
- self: JacAPIServer, token: (str | None) = None
782
- ) -> TransportResponse {
774
+ impl JacAPIServer.refresh_token(token: (str | None) = None) -> TransportResponse {
783
775
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
784
776
  if (not token) {
785
777
  return TransportResponse.fail(
@@ -805,9 +797,7 @@ impl JacAPIServer.refresh_token(
805
797
  );
806
798
  }
807
799
 
808
- impl JacAPIServer.create_user(
809
- self: JacAPIServer, username: str, password: str
810
- ) -> TransportResponse {
800
+ impl JacAPIServer.create_user(username: str, password: str) -> TransportResponse {
811
801
  import traceback;
812
802
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
813
803
  try {
@@ -835,10 +825,7 @@ impl JacAPIServer.create_user(
835
825
  }
836
826
 
837
827
  impl JacAPIServer.update_username(
838
- self: JacAPIServer,
839
- current_username: str,
840
- new_username: str,
841
- Authorization: (str | None) = None
828
+ current_username: str, new_username: str, Authorization: (str | None) = None
842
829
  ) -> TransportResponse {
843
830
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
844
831
  # Validate token and extract username
@@ -889,7 +876,6 @@ impl JacAPIServer.update_username(
889
876
  }
890
877
 
891
878
  impl JacAPIServer.update_password(
892
- self: JacAPIServer,
893
879
  username: str,
894
880
  current_password: str,
895
881
  new_password: str,
@@ -943,7 +929,7 @@ impl JacAPIServer.update_password(
943
929
  );
944
930
  }
945
931
 
946
- impl JacAPIServer.register_update_username_endpoint(self: JacAPIServer) -> None {
932
+ impl JacAPIServer.register_update_username_endpoint -> None {
947
933
  import from fastapi { Request }
948
934
  async def update_username_handler(
949
935
  request: Request, current_username: str, new_username: str
@@ -982,7 +968,7 @@ impl JacAPIServer.register_update_username_endpoint(self: JacAPIServer) -> None
982
968
  );
983
969
  }
984
970
 
985
- impl JacAPIServer.register_update_password_endpoint(self: JacAPIServer) -> None {
971
+ impl JacAPIServer.register_update_password_endpoint -> None {
986
972
  import from fastapi { Request }
987
973
  async def update_password_handler(
988
974
  request: Request, username: str, current_password: str, new_password: str
@@ -1031,7 +1017,7 @@ impl JacAPIServer.register_update_password_endpoint(self: JacAPIServer) -> None
1031
1017
  );
1032
1018
  }
1033
1019
 
1034
- impl JacAPIServer.register_login_endpoint(self: JacAPIServer) -> None {
1020
+ impl JacAPIServer.register_login_endpoint -> None {
1035
1021
  self.server.add_endpoint(
1036
1022
  JEndPoint(
1037
1023
  method=HTTPMethod.POST,
@@ -1063,9 +1049,7 @@ impl JacAPIServer.register_login_endpoint(self: JacAPIServer) -> None {
1063
1049
  );
1064
1050
  }
1065
1051
 
1066
- impl JacAPIServer.login(
1067
- self: JacAPIServer, username: str, password: str
1068
- ) -> TransportResponse {
1052
+ impl JacAPIServer.login(username: str, password: str) -> TransportResponse {
1069
1053
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
1070
1054
  if (not username or not password) {
1071
1055
  return TransportResponse.fail(
@@ -1088,10 +1072,8 @@ impl JacAPIServer.login(
1088
1072
  );
1089
1073
  }
1090
1074
 
1091
- impl JacAPIServer.init(
1092
- self: JacAPIServer, module_name: str, port: int = 8000, base_path: str = ""
1093
- ) -> None {
1094
- super.init(module_name, port, base_path);
1075
+ impl JacAPIServer.postinit -> None {
1076
+ super.postinit();
1095
1077
  self.server.app.add_middleware(
1096
1078
  CORSMiddleware,
1097
1079
  allow_origins=['*'],
@@ -1104,7 +1086,7 @@ impl JacAPIServer.init(
1104
1086
  import from starlette.middleware.base { BaseHTTPMiddleware }
1105
1087
  import from pathlib { Path }
1106
1088
  # Use base_path to find the correct jac.toml for this project
1107
- start_path = Path(base_path) if base_path else None;
1089
+ start_path = Path(self.base_path) if self.base_path else None;
1108
1090
  config = JacConfig.discover(start_path);
1109
1091
  custom_headers: dict = {};
1110
1092
  if config
@@ -1184,9 +1166,7 @@ impl JacAPIServer.create_jwt_token(username: str) -> str {
1184
1166
  return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM);
1185
1167
  }
1186
1168
 
1187
- impl JacAPIServer.get_sso(
1188
- self: JacAPIServer, platform: str, operation: str
1189
- ) -> (GoogleSSO | None) {
1169
+ impl JacAPIServer.get_sso(platform: str, operation: str) -> (GoogleSSO | None) {
1190
1170
  if (platform not in self.SUPPORTED_PLATFORMS) {
1191
1171
  return None;
1192
1172
  }
@@ -1204,7 +1184,7 @@ impl JacAPIServer.get_sso(
1204
1184
  }
1205
1185
 
1206
1186
  impl JacAPIServer.sso_initiate(
1207
- self: JacAPIServer, platform: str, operation: str
1187
+ platform: str, operation: str
1208
1188
  ) -> (Response | TransportResponse) {
1209
1189
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
1210
1190
  if (platform not in [p.value for p in Platforms]) {
@@ -1244,7 +1224,7 @@ impl JacAPIServer.sso_initiate(
1244
1224
  }
1245
1225
 
1246
1226
  impl JacAPIServer.sso_callback(
1247
- self: JacAPIServer, request: Request, platform: str, operation: str
1227
+ request: Request, platform: str, operation: str
1248
1228
  ) -> TransportResponse {
1249
1229
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
1250
1230
  if (platform not in [p.value for p in Platforms]) {
@@ -1344,7 +1324,7 @@ impl JacAPIServer.sso_callback(
1344
1324
  }
1345
1325
  }
1346
1326
 
1347
- impl JacAPIServer.register_sso_endpoints(self: JacAPIServer) -> None {
1327
+ impl JacAPIServer.register_sso_endpoints -> None {
1348
1328
  self.server.add_endpoint(
1349
1329
  JEndPoint(
1350
1330
  method=HTTPMethod.GET,
@@ -1409,7 +1389,7 @@ impl JacAPIServer.register_sso_endpoints(self: JacAPIServer) -> None {
1409
1389
  # HMR (Hot Module Replacement) Dynamic Routing Support
1410
1390
  # ============================================================================
1411
1391
  """Enable HMR mode - file changes trigger reload on next request."""
1412
- impl JacAPIServer.enable_hmr(self: JacAPIServer, hot_reloader: Any) -> None {
1392
+ impl JacAPIServer.enable_hmr(hot_reloader: Any) -> None {
1413
1393
  self._hot_reloader = hot_reloader;
1414
1394
  # Callback when file changes - sets pending flag
1415
1395
  def on_change(event: Any) -> None {
@@ -1427,7 +1407,7 @@ Instead of pre-registering /walker/WalkerA, /walker/WalkerB, etc.,
1427
1407
  we register catch-all routes that look up walkers at request time.
1428
1408
  This enables HMR since introspector.load() is called per-request.
1429
1409
  """
1430
- impl JacAPIServer.register_dynamic_walker_endpoint(self: JacAPIServer) -> None {
1410
+ impl JacAPIServer.register_dynamic_walker_endpoint -> None {
1431
1411
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
1432
1412
  import from fastapi { Request }
1433
1413
  # Dynamic handler that looks up walker at request time
@@ -1579,7 +1559,7 @@ impl JacAPIServer.register_dynamic_walker_endpoint(self: JacAPIServer) -> None {
1579
1559
 
1580
1560
  Similar to dynamic walker routing, this enables HMR for functions.
1581
1561
  """
1582
- impl JacAPIServer.register_dynamic_function_endpoint(self: JacAPIServer) -> None {
1562
+ impl JacAPIServer.register_dynamic_function_endpoint -> None {
1583
1563
  import from fastapi.responses { JSONResponse }
1584
1564
  import from fastapi { Request }
1585
1565
  import from jaclang.runtimelib.transport { TransportResponse, Meta }
@@ -1685,7 +1665,7 @@ impl JacAPIServer.register_dynamic_function_endpoint(self: JacAPIServer) -> None
1685
1665
  These endpoints allow clients to discover what walkers and functions are available,
1686
1666
  which is especially useful in HMR mode where the list can change dynamically.
1687
1667
  """
1688
- impl JacAPIServer.register_dynamic_introspection_endpoints(self: JacAPIServer) -> None {
1668
+ impl JacAPIServer.register_dynamic_introspection_endpoints -> None {
1689
1669
  import from fastapi.responses { JSONResponse }
1690
1670
  def list_walkers -> dict[str, Any] {
1691
1671
  # Reload introspector if files changed (HMR)
@@ -1,3 +1,5 @@
1
+ import logging;
2
+
1
3
  """Helper function to convert TransportResponse to JSONResponse (similar to HTTPTransport.send)."""
2
4
  def _convert_transport_response_to_json_response(
3
5
  transport_response: TransportResponse
@@ -53,13 +55,59 @@ def _convert_transport_response_to_json_response(
53
55
  return JSONResponse(status_code=status, content=response_body);
54
56
  }
55
57
 
58
+ """Custom logging handler that routes logs to jac-super console."""
59
+ class ConsoleLogHandler(logging.Handler) {
60
+ """A logging handler that forwards log messages to jac-super's console."""
61
+ def emit(self: ConsoleLogHandler, record: logging.LogRecord) -> None {
62
+ import from jaclang.cli.console { console }
63
+ message = self.format(record);
64
+ console.print(f" {message}");
65
+ }
66
+ }
67
+
56
68
  """Run the FastAPI server using Uvicorn."""
57
69
  impl JFastApiServer.run_server(
58
70
  self: JFastApiServer, host: str = '0.0.0.0', port: int = 8000
59
71
  ) -> None {
60
72
  app = self.create_server();
61
- # Suppress INFO logs to avoid duplicate server messages (we show our own JAC DEV SERVER banner)
62
- uvicorn.run(app, host=host, port=port, log_level="warning");
73
+ # Create custom handler for console logging
74
+ console_handler = ConsoleLogHandler();
75
+ console_handler.setFormatter(logging.Formatter("%(message)s"));
76
+ # Suppress startup logs but route access logs through jac-super console
77
+ log_config = {
78
+ "version": 1,
79
+ "disable_existing_loggers": False,
80
+ "formatters": {
81
+ "default": {"format": "%(message)s"},
82
+ "access": {"format": "%(message)s"},
83
+
84
+ },
85
+ "handlers": {
86
+ "default": {
87
+ "formatter": "default",
88
+ "class": "logging.StreamHandler",
89
+ "stream": "ext://sys.stderr"
90
+ },
91
+ "access": {"()": lambda : console_handler },
92
+
93
+ },
94
+ "loggers": {
95
+ "uvicorn": {
96
+ "handlers": ["default"],
97
+ "level": "WARNING",
98
+ "propagate": False
99
+ },
100
+ "uvicorn.error": {"level": "WARNING", "propagate": False},
101
+ "uvicorn.access": {
102
+ "handlers": ["access"],
103
+ "level": "INFO",
104
+ "propagate": False
105
+ },
106
+
107
+ },
108
+
109
+ };
110
+ uvicorn.run(app, host=host, port=port, log_config=log_config);
63
111
  }
64
112
 
65
113
  """Get the underlying FastAPI application instance."""
@@ -18,6 +18,7 @@ Advanced Features:
18
18
  """
19
19
 
20
20
  import inspect;
21
+ import logging;
21
22
  import uvicorn;
22
23
  import from collections.abc { Callable }
23
24
  import from typing { Any, Optional, TypeAlias, get_type_hints }
@@ -0,0 +1,118 @@
1
+ import logging;
2
+ import mimetypes;
3
+ import from collections.abc { Callable }
4
+ import from datetime { UTC, datetime, timedelta }
5
+ import from pathlib { Path }
6
+ import from pydantic { BaseModel, Field }
7
+ import from typing { Any }
8
+ import jwt;
9
+ import from os { getenv }
10
+ import from fastapi.middleware.cors { CORSMiddleware }
11
+ import from fastapi.responses { HTMLResponse, JSONResponse, Response, RedirectResponse }
12
+ import from jac_scale.jserver.jfast_api { JFastApiServer }
13
+ import from jac_scale.jserver.jserver {
14
+ APIParameter,
15
+ HTTPMethod,
16
+ JEndPoint,
17
+ ParameterType
18
+ }
19
+ import from jaclang.pycore.runtime { JacRuntime as Jac }
20
+ import from jaclang.runtimelib.server { JacAPIServer as JServer }
21
+ import from jaclang.runtimelib.server { JsonValue }
22
+ import from jaclang.runtimelib.transport { TransportResponse, Meta, MessageType }
23
+ import from enum { StrEnum }
24
+ import from fastapi_sso.sso.google { GoogleSSO }
25
+ import from jac_scale.utils { generate_random_password }
26
+ import from jac_scale.config_loader { get_scale_config }
27
+
28
+ # Load configuration from jac.toml with env var overrides
29
+ glob _jwt_config = get_scale_config().get_jwt_config(),
30
+ _sso_config = get_scale_config().get_sso_config(),
31
+ JWT_SECRET = _jwt_config['secret'],
32
+ JWT_ALGORITHM = _jwt_config['algorithm'],
33
+ JWT_EXP_DELTA_DAYS = _jwt_config['exp_delta_days'],
34
+ SSO_HOST = _sso_config['host'],
35
+ logger = logging.getLogger(__name__);
36
+
37
+ enum Platforms ( StrEnum ) { GOOGLE = 'google' }
38
+
39
+ enum Operations ( StrEnum ) { LOGIN = 'login', REGISTER = 'register' }
40
+
41
+ obj JacAPIServer(JServer) {
42
+ # HMR (Hot Module Replacement) support fields
43
+ has _hmr_pending: bool = False,
44
+ _hot_reloader: Any | None = None;
45
+
46
+ static def create_jwt_token(username: str) -> str;
47
+ static def validate_jwt_token(token: str) -> (str | None);
48
+ static def refresh_jwt_token(token: str) -> (str | None);
49
+ def postinit -> None;
50
+ def login(username: str, password: str) -> TransportResponse;
51
+ def register_login_endpoint -> None;
52
+ def update_username(
53
+ current_username: str, new_username: str, Authorization: (str | None) = None
54
+ ) -> TransportResponse;
55
+
56
+ def update_password(
57
+ username: str,
58
+ current_password: str,
59
+ new_password: str,
60
+ Authorization: (str | None) = None
61
+ ) -> TransportResponse;
62
+
63
+ def register_update_username_endpoint -> None;
64
+ def register_update_password_endpoint -> None;
65
+ def create_user(username: str, password: str) -> TransportResponse;
66
+ def refresh_token(token: (str | None) = None) -> TransportResponse;
67
+ def register_create_user_endpoint -> None;
68
+ def register_refresh_token_endpoint -> None;
69
+ def get_sso(platform: str, operation: str) -> (GoogleSSO | None);
70
+ async def sso_initiate(
71
+ platform: str, operation: str
72
+ ) -> (Response | TransportResponse);
73
+
74
+ async def sso_callback(
75
+ request: Request, platform: str, operation: str
76
+ ) -> TransportResponse;
77
+
78
+ def register_sso_endpoints -> None;
79
+ def create_walker_callback(
80
+ walker_name: str, has_node_param: bool = False
81
+ ) -> Callable[..., TransportResponse];
82
+
83
+ def create_walker_parameters(
84
+ walker_name: str, invoke_on_root: bool
85
+ ) -> list[APIParameter];
86
+
87
+ def register_walkers_endpoints -> None;
88
+ def create_function_callback(func_name: str) -> Callable[..., TransportResponse];
89
+ def create_function_parameters(func_name: str) -> list[APIParameter];
90
+ def register_functions_endpoints -> None;
91
+ def render_page_callback -> Callable[..., HTMLResponse];
92
+ def render_base_route_callback(app_name: str) -> Callable[..., HTMLResponse];
93
+ def register_page_endpoint -> None;
94
+ def serve_client_js_callback -> Callable[..., Response];
95
+ def register_client_js_endpoint -> None;
96
+ def register_static_file_endpoint -> None;
97
+ def serve_static_file(file_path: str) -> Response;
98
+ def register_root_asset_endpoint -> None;
99
+ def serve_root_asset(file_path: str) -> Response;
100
+ def _configure_openapi_security -> None;
101
+ def start(dev: bool = False) -> None;
102
+ # HMR (Hot Module Replacement) dynamic routing methods
103
+ def enable_hmr(hot_reloader: Any) -> None;
104
+ def register_dynamic_walker_endpoint -> None;
105
+ def register_dynamic_function_endpoint -> None;
106
+ def register_dynamic_introspection_endpoints -> None;
107
+ }
108
+
109
+ class UpdateUsernameRequest(BaseModel) {
110
+ has current_username: str = Field(..., description='Current username'),
111
+ new_username: str = Field(..., description='New username');
112
+ }
113
+
114
+ class UpdatePasswordRequest(BaseModel) {
115
+ has username: str = Field(..., description='Username'),
116
+ current_password: str = Field(..., description='Current password'),
117
+ new_password: str = Field(..., description='New password');
118
+ }
@@ -0,0 +1,40 @@
1
+ """Standard logger implementation using jac console."""
2
+ import from typing { Any }
3
+ import from jac_scale.abstractions.logger { Logger }
4
+ import from jaclang.cli.console { console }
5
+
6
+ """Standard logger using jac console for Rich-styled output."""
7
+ class StandardLogger(Logger) {
8
+ def init(self: StandardLogger, config: dict[str, Any] = {}) -> None { }
9
+ def info(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
10
+ if context {
11
+ console.info(f"{message} | Context: {context}");
12
+ } else {
13
+ console.info(message);
14
+ }
15
+ }
16
+
17
+ def error(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
18
+ if context {
19
+ console.error(f"{message} | Context: {context}");
20
+ } else {
21
+ console.error(message);
22
+ }
23
+ }
24
+
25
+ def warn(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
26
+ if context {
27
+ console.warning(f"{message} | Context: {context}");
28
+ } else {
29
+ console.warning(message);
30
+ }
31
+ }
32
+
33
+ def debug(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
34
+ if context {
35
+ console.print(f"[DEBUG] {message} | Context: {context}", style="muted");
36
+ } else {
37
+ console.print(f"[DEBUG] {message}", style="muted");
38
+ }
39
+ }
40
+ }
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jac-scale
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Author-email: Jason Mars <jason@mars.ninja>
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
- Requires-Dist: jaclang>=0.9.9
7
+ Requires-Dist: jaclang>=0.9.10
8
8
  Requires-Dist: python-dotenv<2.0.0,>=1.2.1
9
9
  Requires-Dist: docker<8.0.0,>=7.1.0
10
10
  Requires-Dist: kubernetes<35.0.0,>=34.1.0
@@ -1,4 +1,4 @@
1
- jaclang>=0.9.9
1
+ jaclang>=0.9.10
2
2
  python-dotenv<2.0.0,>=1.2.1
3
3
  docker<8.0.0,>=7.1.0
4
4
  kubernetes<35.0.0,>=34.1.0
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "jac-scale"
3
- version = "0.1.0"
3
+ version = "0.1.1"
4
4
  description = ""
5
5
  authors = [{ name = "Jason Mars", email = "jason@mars.ninja" }]
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.12"
8
8
  dependencies = [
9
- "jaclang>=0.9.9",
9
+ "jaclang>=0.9.10",
10
10
  "python-dotenv>=1.2.1,<2.0.0",
11
11
  "docker>=7.1.0,<8.0.0",
12
12
  "kubernetes>=34.1.0,<35.0.0",
@@ -1,148 +0,0 @@
1
- import logging;
2
- import mimetypes;
3
- import from collections.abc { Callable }
4
- import from datetime { UTC, datetime, timedelta }
5
- import from pathlib { Path }
6
- import from pydantic { BaseModel, Field }
7
- import from typing { Any }
8
- import jwt;
9
- import from os { getenv }
10
- import from fastapi.middleware.cors { CORSMiddleware }
11
- import from fastapi.responses { HTMLResponse, JSONResponse, Response, RedirectResponse }
12
- import from jac_scale.jserver.jfast_api { JFastApiServer }
13
- import from jac_scale.jserver.jserver {
14
- APIParameter,
15
- HTTPMethod,
16
- JEndPoint,
17
- ParameterType
18
- }
19
- import from jaclang.pycore.runtime { JacRuntime as Jac }
20
- import from jaclang.runtimelib.server { JacAPIServer as JServer }
21
- import from jaclang.runtimelib.server { JsonValue }
22
- import from jaclang.runtimelib.transport { TransportResponse, Meta, MessageType }
23
- import from enum { StrEnum }
24
- import from fastapi_sso.sso.google { GoogleSSO }
25
- import from jac_scale.utils { generate_random_password }
26
- import from jac_scale.config_loader { get_scale_config }
27
-
28
- # Load configuration from jac.toml with env var overrides
29
- glob _jwt_config = get_scale_config().get_jwt_config(),
30
- _sso_config = get_scale_config().get_sso_config(),
31
- JWT_SECRET = _jwt_config['secret'],
32
- JWT_ALGORITHM = _jwt_config['algorithm'],
33
- JWT_EXP_DELTA_DAYS = _jwt_config['exp_delta_days'],
34
- SSO_HOST = _sso_config['host'],
35
- logger = logging.getLogger(__name__);
36
-
37
- class Platforms(StrEnum) {
38
- has GOOGLE: str = 'google';
39
- }
40
-
41
- class Operations(StrEnum) {
42
- has LOGIN: str = 'login',
43
- REGISTER: str = 'register';
44
- }
45
-
46
- class JacAPIServer(JServer) {
47
- # HMR (Hot Module Replacement) support fields
48
- has _hmr_pending: bool = False,
49
- _hot_reloader: Any | None = None;
50
-
51
- static def create_jwt_token(username: str) -> str;
52
- static def validate_jwt_token(token: str) -> (str | None);
53
- static def refresh_jwt_token(token: str) -> (str | None);
54
- def init(
55
- self: JacAPIServer, module_name: str, port: int = 8000, base_path: str = ""
56
- ) -> None;
57
-
58
- def login(self: JacAPIServer, username: str, password: str) -> TransportResponse;
59
- def register_login_endpoint(self: JacAPIServer) -> None;
60
- def update_username(
61
- self: JacAPIServer,
62
- current_username: str,
63
- new_username: str,
64
- Authorization: (str | None) = None
65
- ) -> TransportResponse;
66
-
67
- def update_password(
68
- self: JacAPIServer,
69
- username: str,
70
- current_password: str,
71
- new_password: str,
72
- Authorization: (str | None) = None
73
- ) -> TransportResponse;
74
-
75
- def register_update_username_endpoint(self: JacAPIServer) -> None;
76
- def register_update_password_endpoint(self: JacAPIServer) -> None;
77
- def create_user(
78
- self: JacAPIServer, username: str, password: str
79
- ) -> TransportResponse;
80
-
81
- def refresh_token(
82
- self: JacAPIServer, token: (str | None) = None
83
- ) -> TransportResponse;
84
-
85
- def register_create_user_endpoint(self: JacAPIServer) -> None;
86
- def register_refresh_token_endpoint(self: JacAPIServer) -> None;
87
- def get_sso(
88
- self: JacAPIServer, platform: str, operation: str
89
- ) -> (GoogleSSO | None);
90
-
91
- async def sso_initiate(
92
- self: JacAPIServer, platform: str, operation: str
93
- ) -> (Response | TransportResponse);
94
-
95
- async def sso_callback(
96
- self: JacAPIServer, request: Request, platform: str, operation: str
97
- ) -> TransportResponse;
98
-
99
- def register_sso_endpoints(self: JacAPIServer) -> None;
100
- def create_walker_callback(
101
- self: JacAPIServer, walker_name: str, has_node_param: bool = False
102
- ) -> Callable[..., TransportResponse];
103
-
104
- def create_walker_parameters(
105
- self: JacAPIServer, walker_name: str, invoke_on_root: bool
106
- ) -> list[APIParameter];
107
-
108
- def register_walkers_endpoints(self: JacAPIServer) -> None;
109
- def create_function_callback(
110
- self: JacAPIServer, func_name: str
111
- ) -> Callable[..., TransportResponse];
112
-
113
- def create_function_parameters(
114
- self: JacAPIServer, func_name: str
115
- ) -> list[APIParameter];
116
-
117
- def register_functions_endpoints(self: JacAPIServer) -> None;
118
- def render_page_callback(self: JacAPIServer) -> Callable[..., HTMLResponse];
119
- def render_base_route_callback(
120
- self: JacAPIServer, app_name: str
121
- ) -> Callable[..., HTMLResponse];
122
-
123
- def register_page_endpoint(self: JacAPIServer) -> None;
124
- def serve_client_js_callback(self: JacAPIServer) -> Callable[..., Response];
125
- def register_client_js_endpoint(self: JacAPIServer) -> None;
126
- def register_static_file_endpoint(self: JacAPIServer) -> None;
127
- def serve_static_file(self: JacAPIServer, file_path: str) -> Response;
128
- def register_root_asset_endpoint(self: JacAPIServer) -> None;
129
- def serve_root_asset(self: JacAPIServer, file_path: str) -> Response;
130
- def _configure_openapi_security(self: JacAPIServer) -> None;
131
- def start(self: JacAPIServer, dev: bool = False) -> None;
132
- # HMR (Hot Module Replacement) dynamic routing methods
133
- def enable_hmr(self: JacAPIServer, hot_reloader: Any) -> None;
134
- def register_dynamic_walker_endpoint(self: JacAPIServer) -> None;
135
- def register_dynamic_function_endpoint(self: JacAPIServer) -> None;
136
- def register_dynamic_introspection_endpoints(self: JacAPIServer) -> None;
137
- }
138
-
139
- class UpdateUsernameRequest(BaseModel) {
140
- has current_username: str = Field(..., description='Current username'),
141
- new_username: str = Field(..., description='New username');
142
- }
143
-
144
- class UpdatePasswordRequest(BaseModel) {
145
- has username: str = Field(..., description='Username'),
146
- current_password: str = Field(..., description='Current password'),
147
- new_password: str = Field(..., description='New password');
148
- }
@@ -1,56 +0,0 @@
1
- """Standard logger implementation using Python logging."""
2
- import logging;
3
- import from typing { Any }
4
- import from jac_scale.abstractions.logger { Logger }
5
-
6
- """Standard logger using Python's logging module."""
7
- class StandardLogger(Logger) {
8
- has logger: logging.Logger;
9
-
10
- def init(self: StandardLogger, config: dict[str, Any] = {}) -> None {
11
- name = config.get('name', 'jac_scale');
12
- level = config.get('level', 'INFO');
13
- self.logger = logging.getLogger(name);
14
- self.logger.setLevel(getattr(logging, level.upper(), logging.INFO));
15
- if not self.logger.handlers {
16
- handler = logging.StreamHandler();
17
- formatter = logging.Formatter(
18
- '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
19
- );
20
- handler.setFormatter(formatter);
21
- self.logger.addHandler(handler);
22
- }
23
- }
24
-
25
- def info(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
26
- if context {
27
- self.logger.info(f"{message} | Context: {context}");
28
- } else {
29
- self.logger.info(message);
30
- }
31
- }
32
-
33
- def error(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
34
- if context {
35
- self.logger.error(f"{message} | Context: {context}");
36
- } else {
37
- self.logger.error(message);
38
- }
39
- }
40
-
41
- def warn(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
42
- if context {
43
- self.logger.warn(f"{message} | Context: {context}");
44
- } else {
45
- self.logger.warn(message);
46
- }
47
- }
48
-
49
- def debug(self: StandardLogger, message: str, context: dict[str, Any] = {}) -> None {
50
- if context {
51
- self.logger.debug(f"{message} | Context: {context}");
52
- } else {
53
- self.logger.debug(message);
54
- }
55
- }
56
- }
File without changes
File without changes
File without changes