-
Notifications
You must be signed in to change notification settings - Fork 171
Open
Labels
UIRelated to the Hamilton UIRelated to the Hamilton UIbugSomething isn't workingSomething isn't workinghelp wantedExtra attention is neededExtra attention is needed
Description
I was having some trouble running the local hamilton UI while following these docs
This seems only to be an issue with the UI module, the sdk seems to work fine
Current behavior
Outputs: ConfigError: The use of `Config` class is removed for ModelSchema, use 'Meta' instead
Stack Traces
Somewhat full trace (cut-off due to character limit)
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\core\checks\registry.py:89 in run_checks │
│ │
│ 86 │ │ │ checks = [check for check in checks if not set(check.tags).isdisjoint(tags)] │
│ 87 │ │ │
│ 88 │ │ for check in checks: │
│ ❱ 89 │ │ │ new_errors = check(app_configs=app_configs, databases=databases) │
│ 90 │ │ │ if not isinstance(new_errors, Iterable): │
│ 91 │ │ │ │ raise TypeError( │
│ 92 │ │ │ │ │ "The function %r did not return a list. All functions " │
│ │
│ ╭─────────────────────────────────────────────── locals ───────────────────────────────────────────────╮ │
│ │ app_configs = None │ │
│ │ checks = [ │ │
│ │ │ <function check_all_models at 0x0000019E10D71080>, │ │
│ │ │ <function check_csp_settings at 0x0000019E10D720C0>, │ │
│ │ │ <function check_middleware at 0x0000019E126F7100>, │ │
│ │ │ <function check_url_config at 0x0000019E11DBA980>, │ │
│ │ │ <function check_models_permissions at 0x0000019E126F49A0>, │ │
│ │ │ <function check_generic_foreign_keys at 0x0000019E126F71A0>, │ │
│ │ │ <function check_finders at 0x0000019E126F79C0>, │ │
│ │ │ <function check_database_backends at 0x0000019E10D43A60>, │ │
│ │ │ <function check_lazy_references at 0x0000019E10D71260>, │ │
│ │ │ <function check_default_cache_is_configured at 0x0000019E10D40360>, │ │
│ │ │ ... +18 │ │
│ │ ] │ │
│ │ databases = ['default'] │ │
│ │ errors = [] │ │
│ │ include_deployment_checks = False │ │
│ │ new_errors = [] │ │
│ │ self = <django.core.checks.registry.CheckRegistry object at 0x0000019E10BC52B0> │ │
│ │ tags = None │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\core\checks\urls.py:16 in check_url_config │
│ │
│ 13 │ │ from django.urls import get_resolver ╭────────────────────────── locals ──────────────────────────╮ │
│ 14 │ │ │ app_configs = None │ │
│ 15 │ │ resolver = get_resolver() │ kwargs = {'databases': ['default']} │ │
│ ❱ 16 │ │ return check_resolver(resolver) │ resolver = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ 17 │ return [] ╰────────────────────────────────────────────────────────────╯ │
│ 18 │
│ 19 │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\core\checks\urls.py:26 in check_resolver │
│ │
│ 23 │ """ │
│ 24 │ check_method = getattr(resolver, "check", None) │
│ 25 │ if check_method is not None: │
│ ❱ 26 │ │ return check_method() │
│ 27 │ elif not hasattr(resolver, "resolve"): │
│ 28 │ │ return get_warning_for_invalid_pattern(resolver) │
│ 29 │ else: │
│ │
│ ╭──────────────────────────────────────────── locals ─────────────────────────────────────────────╮ │
│ │ check_method = <bound method URLResolver.check of <URLResolver 'server.urls' (None:None) '^/'>> │ │
│ │ resolver = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\urls\resolvers.py:541 in check │
│ │
│ 538 │ ╭──────────────────────── locals ─────────────────────────╮ │
│ 539 │ def check(self): │ messages = [] │ │
│ 540 │ │ messages = [] │ self = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ ❱ 541 │ │ for pattern in self.url_patterns: ╰─────────────────────────────────────────────────────────╯ │
│ 542 │ │ │ messages.extend(check_resolver(pattern)) │
│ 543 │ │ return messages or self.pattern.check() │
│ 544 │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\utils\functional.py:47 in __get__ │
│ │
│ 44 │ │ """ │
│ 45 │ │ if instance is None: │
│ 46 │ │ │ return self │
│ ❱ 47 │ │ res = instance.__dict__[self.name] = self.func(instance) │
│ 48 │ │ return res │
│ 49 │
│ 50 │
│ │
│ ╭───────────────────────────────────── locals ──────────────────────────────────────╮ │
│ │ instance = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ │ self = <django.utils.functional.cached_property object at 0x0000019E122FFD90> │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\urls\resolvers.py:729 in url_patterns │
│ │
│ 726 │ @cached_property ╭────────────────────── locals ───────────────────────╮ │
│ 727 │ def url_patterns(self): │ self = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ 728 │ │ # urlconf_module might be a valid set of patterns, so we default to it ╰─────────────────────────────────────────────────────╯ │
│ ❱ 729 │ │ patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) │
│ 730 │ │ try: │
│ 731 │ │ │ iter(patterns) │
│ 732 │ │ except TypeError as e: │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\utils\functional.py:47 in __get__ │
│ │
│ 44 │ │ """ │
│ 45 │ │ if instance is None: │
│ 46 │ │ │ return self │
│ ❱ 47 │ │ res = instance.__dict__[self.name] = self.func(instance) │
│ 48 │ │ return res │
│ 49 │
│ 50 │
│ │
│ ╭───────────────────────────────────── locals ──────────────────────────────────────╮ │
│ │ instance = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ │ self = <django.utils.functional.cached_property object at 0x0000019E122FFD20> │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\django\urls\resolvers.py:722 in urlconf_module │
│ │
│ 719 │ @cached_property ╭────────────────────── locals ───────────────────────╮ │
│ 720 │ def urlconf_module(self): │ self = <URLResolver 'server.urls' (None:None) '^/'> │ │
│ 721 │ │ if isinstance(self.urlconf_name, str): ╰─────────────────────────────────────────────────────╯ │
│ ❱ 722 │ │ │ return import_module(self.urlconf_name) │
│ 723 │ │ else: │
│ 724 │ │ │ return self.urlconf_name │
│ 725 │
│ │
│ C:\Users\Daan\AppData\Roaming\uv\python\cpython-3.13.0-windows-x86_64-none\Lib\importlib\__init__.py:88 in import_module │
│ │
│ 85 │ │ │ if character != '.': ╭──────── locals ─────────╮ │
│ 86 │ │ │ │ break │ level = 0 │ │
│ 87 │ │ │ level += 1 │ name = 'server.urls' │ │
│ ❱ 88 │ return _bootstrap._gcd_import(name[level:], package, level) │ package = None │ │
│ 89 ╰─────────────────────────╯ │
│ 90 │
│ 91 _RELOADING = {} │
│ in _gcd_import:1387 │
│ ╭──────── locals ─────────╮ │
│ │ level = 0 │ │
│ │ name = 'server.urls' │ │
│ │ package = None │ │
│ ╰─────────────────────────╯ │
│ in _find_and_load:1360 │
│ ╭──────────────────── locals ────────────────────╮ │
│ │ module = <object object at 0x0000019E72920060> │ │
│ │ name = 'server.urls' │ │
│ ╰────────────────────────────────────────────────╯ │
│ in _find_and_load_unlocked:1331 │
│ ╭────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────╮ │
│ │ child = 'urls' │ │
│ │ name = 'server.urls' │ │
│ │ parent = 'server' │ │
│ │ parent_module = <module 'server' from │ │
│ │ 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\__init__.py'> │ │
│ │ parent_spec = ModuleSpec(name='server', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000019E10D7D070>, │ │
│ │ origin='C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\__init__.py', │ │
│ │ submodule_search_locations=['C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\se… │ │
│ │ path = ['C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\s'+31] │ │
│ │ spec = ModuleSpec(name='server.urls', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000019E12A36810>, │ │
│ │ origin='C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\urls.py') │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ in _load_unlocked:935 │
│ ╭────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────╮ │
│ │ module = <module 'server.urls' from │ │
│ │ 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\urls.py'> │ │
│ │ spec = ModuleSpec(name='server.urls', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000019E12A36810>, │ │
│ │ origin='C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\urls.py') │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ in exec_module:1022 │
│ ╭────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────╮ │
│ │ code = <code object <module> at 0x0000019E0ECFF170, file │ │
│ │ "C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\server\urls.py", line 1> │ │
│ │ module = <module 'server.urls' from │ │
│ │ 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\urls.py'> │ │
│ │ self = <_frozen_importlib_external.SourceFileLoader object at 0x0000019E12A36810> │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ in _call_with_frames_removed:488 │
│ ╭────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────╮ │
│ │ args = ( │ │
│ │ │ <code object <module> at 0x0000019E0ECFF170, file │ │
│ │ "C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\server\urls.py", line 1>, │ │
│ │ │ { │ │
│ │ │ │ '__name__': 'server.urls', │ │
│ │ │ │ '__doc__': 'server URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more '+543, │ │
│ │ │ │ '__package__': 'server', │ │
│ │ │ │ '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000019E12A36810>, │ │
│ │ │ │ '__spec__': ModuleSpec(name='server.urls', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000019E12A36810>, │ │
│ │ origin='C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\hamilton_ui\\server\\urls.py'), │ │
│ │ │ │ '__file__': 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\s'+39, │ │
│ │ │ │ '__cached__': 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\s'+64, │ │
│ │ │ │ '__builtins__': { │ │
│ │ │ │ │ '__name__': 'builtins', │ │
│ │ │ │ │ '__doc__': 'Built-in functions, types, exceptions, and other objects.\n\nThis module provides '+346, │ │
│ │ │ │ │ '__package__': '', │ │
│ │ │ │ │ '__loader__': <class '_frozen_importlib.BuiltinImporter'>, │ │
│ │ │ │ │ '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), │ │
│ │ │ │ │ '__build_class__': <built-in function __build_class__>, │ │
│ │ │ │ │ '__import__': <built-in function __import__>, │ │
│ │ │ │ │ 'abs': <built-in function abs>, │ │
│ │ │ │ │ 'all': <built-in function all>, │ │
│ │ │ │ │ 'any': <built-in function any>, │ │
│ │ │ │ │ ... +150 │ │
│ │ │ │ }, │ │
│ │ │ │ 'settings': <LazySettings "server.settings_mini">, │ │
│ │ │ │ 'static': <function static at 0x0000019E129D37E0>, │ │
│ │ │ │ ... +5 │ │
│ │ │ } │ │
│ │ ) │ │
│ │ f = <built-in function exec> │ │
│ │ kwds = {} │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\server\urls.py:24 in <module> │
│ │
│ 21 from django.views.generic import TemplateView │
│ 22 from django.views.static import serve │
│ 23 │
│ ❱ 24 from . import api, default_views │
│ 25 │
│ 26 # TODO -- ensure we didn't break the actual deployment │
│ 27 if settings.HAMILTON_ENV == "mini": │
│ │
│ ╭────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────╮ │
│ │ admin = <module 'django.contrib.admin' from │ │
│ │ 'C:\\Users\\Daan\\web-projects\\experimental_projects\\my_hamilton_project\\.venv\\Lib\\site-packages\\django\\contrib\\admin\\__init__.py'> │ │
│ │ path = functools.partial(<function _path at 0x0000019E1240C4A0>, Pattern=<class 'django.urls.resolvers.RoutePattern'>) │ │
│ │ re_path = functools.partial(<function _path at 0x0000019E1240C4A0>, Pattern=<class 'django.urls.resolvers.RegexPattern'>) │ │
│ │ settings = <LazySettings "server.settings_mini"> │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\server\api.py:3 in <module> │
│ │
│ 1 from django.conf import settings ╭───────────────────── locals ─────────────────────╮ │
│ 2 from ninja import NinjaAPI │ settings = <LazySettings "server.settings_mini"> │ │
│ ❱ 3 from trackingserver_auth import api as auth_api ╰──────────────────────────────────────────────────╯ │
│ 4 from trackingserver_base import api as base_api │
│ 5 │
│ 6 try: │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\trackingserver_auth\api.py:6 in <module> │
│ │
│ 3 │
│ 4 from ninja import Router │
│ 5 from trackingserver_auth.models import APIKey │
│ ❱ 6 from trackingserver_auth.schema import ApiKeyIn, ApiKeyOut, PhoneHomeResult, WhoAmIResul │
│ 7 from trackingserver_base.auth.api_keys import create_api_key_for_user │
│ 8 from trackingserver_base.permissions.base import permission │
│ 9 from trackingserver_base.permissions.permissions import ( │
│ │
│ ╭───────────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────────╮ │
│ │ logging = <module 'logging' from 'C:\\Users\\Daan\\AppData\\Roaming\\uv\\python\\cpython-3.13.0-windows-x86_64-none\\Lib\\logging\\__init__.py'> │ │
│ │ typing = <module 'typing' from 'C:\\Users\\Daan\\AppData\\Roaming\\uv\\python\\cpython-3.13.0-windows-x86_64-none\\Lib\\typing.py'> │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\hamilton_ui\trackingserver_auth\schema.py:11 in <module> │
│ │
│ 8 ########################################## │
│ 9 # These correspond (ish) to DB models # │
│ 10 ########################################## │
│ ❱ 11 class UserOut(ModelSchema): │
│ 12 │ class Config: │
│ 13 │ │ model = User │
│ 14 │ │ model_fields = ["id", "email", "first_name", "last_name"] │
│ │
│ ╭────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────╮ │
│ │ typing = <module 'typing' from 'C:\\Users\\Daan\\AppData\\Roaming\\uv\\python\\cpython-3.13.0-windows-x86_64-none\\Lib\\typing.py'> │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\ninja\orm\metaclass.py:78 in __new__ │
│ │
│ 75 │ │ │ │ and issubclass(base, ModelSchema) │
│ 76 │ │ │ │ and base == ModelSchema │
│ 77 │ │ │ ): │
│ ❱ 78 │ │ │ │ meta_conf = MetaConf.from_schema_class(name, namespace) │
│ 79 │ │ │ │ │
│ 80 │ │ │ │ custom_fields = [] │
│ 81 │ │ │ │ annotations = namespace.get("__annotations__", {}) │
│ │
│ ╭──────────────────────────────────── locals ────────────────────────────────────╮ │
│ │ bases = (<class 'ninja.orm.metaclass.ModelSchema'>,) │ │
│ │ kwargs = {} │ │
│ │ name = 'UserOut' │ │
│ │ namespace = { │ │
│ │ │ '__module__': 'trackingserver_auth.schema', │ │
│ │ │ '__qualname__': 'UserOut', │ │
│ │ │ '__firstlineno__': 11, │ │
│ │ │ 'Config': <class 'trackingserver_auth.schema.UserOut.Config'>, │ │
│ │ │ '__static_attributes__': (), │ │
│ │ │ 'model_config': { │ │
│ │ │ │ 'from_attributes': True, │ │
│ │ │ │ 'model': <class 'trackingserver_auth.models.User'>, │ │
│ │ │ │ 'model_fields': [ │ │
│ │ │ │ │ 'id', │ │
│ │ │ │ │ 'email', │ │
│ │ │ │ │ 'first_name', │ │
│ │ │ │ │ 'last_name' │ │
│ │ │ │ ] │ │
│ │ │ }, │ │
│ │ │ '__class_vars__': set(), │ │
│ │ │ '__private_attributes__': {} │ │
│ │ } │ │
│ ╰────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\Daan\web-projects\experimental_projects\my_hamilton_project\.venv\Lib\site-packages\ninja\orm\metaclass.py:23 in from_schema_class │
│ │
│ 20 │ @staticmethod │
│ 21 │ def from_schema_class(name: str, namespace: dict) -> "MetaConf": │
│ 22 │ │ if "Config" in namespace: │
│ ❱ 23 │ │ │ raise ConfigError( # pragma: no cover │
│ 24 │ │ │ │ "The use of `Config` class is removed for ModelSchema, use 'Meta' instea │
│ 25 │ │ │ ) │
│ 26 │ │ if "Meta" in namespace: │
│ │
│ ╭──────────────────────────────────── locals ────────────────────────────────────╮ │
│ │ name = 'UserOut' │ │
│ │ namespace = { │ │
│ │ │ '__module__': 'trackingserver_auth.schema', │ │
│ │ │ '__qualname__': 'UserOut', │ │
│ │ │ '__firstlineno__': 11, │ │
│ │ │ 'Config': <class 'trackingserver_auth.schema.UserOut.Config'>, │ │
│ │ │ '__static_attributes__': (), │ │
│ │ │ 'model_config': { │ │
│ │ │ │ 'from_attributes': True, │ │
│ │ │ │ 'model': <class 'trackingserver_auth.models.User'>, │ │
│ │ │ │ 'model_fields': [ │ │
│ │ │ │ │ 'id', │ │
│ │ │ │ │ 'email', │ │
│ │ │ │ │ 'first_name', │ │
│ │ │ │ │ 'last_name' │ │
│ │ │ │ ] │ │
│ │ │ }, │ │
│ │ │ '__class_vars__': set(), │ │
│ │ │ '__private_attributes__': {} │ │
│ │ } │ │
│ ╰────────────────────────────────────────────────────────────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
ConfigError: The use of `Config` class is removed for ModelSchema, use 'Meta' instead
Screenshots
(If applicable)
Steps to replicate behavior
uv init my_hamilton_projectcd my_hamilton_projectuv add "sf-hamilton[sdk,ui]>=1.89.0"- activate venv
hamilton uioruv run hamilton ui
Library & System Information
- Hamilton 1.89.0
- uv 0.9.8 (85c5d3228 2025-11-07)
- python 3.13
Expected behavior
For the UI service to run
Additional context
Same problem when using pip with venv. Here is a little Dockerfile which reproduces the error
FROM python:3.13
WORKDIR /usr/local/app
RUN pip install "sf-hamilton[ui,sdk]==1.89.0"
EXPOSE 8080
CMD ["hamilton", "ui", "--port", "8080"]Metadata
Metadata
Assignees
Labels
UIRelated to the Hamilton UIRelated to the Hamilton UIbugSomething isn't workingSomething isn't workinghelp wantedExtra attention is neededExtra attention is needed