cog
6079d981 - Add cog-dataclass: pydantic-free Cog SDK implementation (#2645)

Commit
32 days ago
Add cog-dataclass: pydantic-free Cog SDK implementation (#2645) * cog-dataclass: add SDK core types (Phase 1) Implements the user-facing API for the new pydantic-less Cog SDK: - types.py: Path, Secret, File, URLFile, URLPath, iterators - predictor.py: BasePredictor - model.py: BaseModel with __init_subclass__ auto-dataclass - input.py: Input(), FieldInfo with mutable default handling - coder.py + coders/: Coder system for custom type encoding 50 passing tests covering all core functionality. * cog-dataclass: add internal machinery (Phase 2) Add ADT types, inspector, and schema generation: - _adt.py: PrimitiveType, FieldType, Repetition, OutputKind, InputField, OutputType, PredictorInfo - _inspector.py: create_predictor(), check_input(), type introspection - _schemas.py: OpenAPI JSON schema generation - test_adt.py, test_inspector.py: 105 tests passing * cog-dataclass: add server adaptation (Phase 3) Server files adapted from cog-pydantic: - eventtypes.py: attrs -> dataclasses - scope.py: attrs.frozen -> @dataclass(frozen=True), evolve -> replace - helpers.py: removed pydantic OpenAPI fixup code - webhook.py: removed PYDANTIC_V2 branches - runner.py: @define -> @dataclass, removed pydantic model_dump - worker.py: attrs -> dataclasses, removed PYDANTIC_V2 blocks - http.py: removed PYDANTIC_V2/ValidationError/unwrap_pydantic_serialization_iterators New supporting modules: - schema.py: PredictionRequest/Response as dataclasses with .dict() method - config.py: simplified Config class for reading cog.yaml - json.py, files.py, errors.py, logging.py, mode.py: copied/adapted predictor.py additions: - load_predictor_from_ref, get_predict, get_train - has_setup_weights, extract_setup_weights, wait_for_env 105 tests passing. * Add COG_WHEEL=cog-dataclass support Adds 'cog-dataclass' as a magic keyword for wheel selection, enabling the pydantic-less cog SDK to be used via: COG_WHEEL=cog-dataclass cog build Changes: - pkg/wheels/wheels.go: Add WheelSourceCogDataclass, ReadCogDataclassWheel(), update ParseCogWheel() and go:generate directives - pkg/dockerfile/standard_generator.go: Add installEmbeddedCogDataclassWheel() which installs the wheel WITHOUT pydantic dependency - cog-dataclass/pyproject.toml: Rename package to 'cog-dataclass' so wheel is named cog_dataclass-*.whl (avoids conflict with cog-*.whl) * cog-dataclass: Phase 4 - Integration & wiring Server now fully functional: - python -m cog.server.http starts and runs predictions - OpenAPI schema properly generated with Input/Output types - Predictor loading via spec_from_file_location (like original cog) Changes: - predictor.py: Fix load_predictor_from_ref to use importlib.util - schema.py: Add missing fields to PredictionResponse (context, webhook, etc) - http.py: Remove response_model params (dataclasses work differently), inject Input/Output schemas into OpenAPI via custom_openapi() - _inspector.py: Handle raw default values in _create_input_field Tested end-to-end: setup runs, predictions work, OpenAPI reflects inputs. * cog-dataclass: Phase 5 compatibility + fix Go schema panic Python changes: - Add command modules (openapi_schema, call_graph) for build validation - Fix OpenAPI schema to include PredictionResponse and update response refs - Handle raw default values in _inspector._create_input_field() Go changes: - Fix nil pointer panic in predict.go when schema missing output definition - Add predict_test.go with tests for malformed schema handling Tested: cog build and cog predict work with COG_WHEEL=cog-dataclass * cog-dataclass: add input validation with check_input() - Call _inspector.check_input() to validate and normalize inputs before prediction - Validates constraints: ge/le, min_length/max_length, regex, choices - Returns proper 422 validation error format for Go CLI compatibility - Defaults now properly extracted from FieldInfo objects * cog-dataclass: wire up integration tests CI changes: - Add cog-dataclass to integration test matrix - Propagate COG_WHEEL env var to cog serve in test harness - Add cog_dataclass condition for skipping tests - Fix server cleanup to kill Docker containers by port cog-dataclass fixes: - Add input validation with check_input() and proper error format - Fix evolve_scope to handle 'tag' -> '_tag' mapping (attrs compat) - Handle string-to-int coercion in normalize() - Convert URL/data URI strings to URLPath in worker Skip Python <3.10 and monobase tests for cog-dataclass * integration-tests: skip monobase tests for cog-dataclass * cog-dataclass: fix training support - Handle function trainers (not just class-based) in load_predictor_from_ref - Add module to sys.modules for pickle compatibility - Fix get_predict/get_train to handle function predictors - Add /trainings endpoint schema to OpenAPI * cog-dataclass: add File type, fix validation, add pydantic dep - Add File type support to _adt.py for list[File] inputs - Fix Type import in types.py for pydantic schema support - Re-raise errors during build (is_build=True) so validation errors like invalid defaults are properly reported - Add pydantic>=2.7.0 dependency (required by fastapi) - Fix error messages for ge/le constraint violations - Skip predict_pipeline test (base image pydantic v1 issue) * cog-dataclass: support future_annotations and graceful import failures - Use typing.get_type_hints() to resolve string annotations from 'from __future__ import annotations' - Remove the explicit check that rejected future annotations - Handle import errors gracefully during build - continue with placeholder schemas instead of failing (allows builds when predictor has missing dependencies like replicate) - Distinguish between import errors (graceful fallback) and validation errors (fail build) during schema generation * integration-tests: skip monobase tests for cog-dataclass These tests use fast: true which requires monobase. Skip for cog-dataclass until monobase support is added. * integration-tests: skip complex_output for cog-dataclass This test uses pydantic.BaseModel as output type which is not supported by cog-dataclass (intentionally pydantic-free). * Correct CI issue Build the cog-dataclass wheel * cog-dataclass: address code review feedback Address valid Copilot review comments: - Fix resource leak in suppress_output.py (use nested context managers) - Add security clarification comments to noqa: S310 suppressions - Remove unused imports (sys, Type, BasePredictor, Any, Field, PredictorNotSet) False positives not addressed: - Mixed import styles are intentional where both module and names are used - Type errors for Input(default_factory=...) and predict() signatures are incorrect - "Unused" test class variables are testing exception-raising behavior * cog-dataclass: fix input validation error format and security issue Address CodeQL security warning about information exposure through exceptions: 1. Changed all ValueError messages in check_input() to use "{field}: {message}" format 2. Removed user input values (v!r) from all error messages 3. Added wrapper around normalize() to reformat errors consistently 4. Updated normalize() to not include user input values Error messages now look like: - "prompt: Value must be >= 1" - "text: Length must be <= 100" - "format: Value must be one of ['json', 'yaml']" Instead of the old format that exposed user values: - "invalid input value: prompt='<user input>' fails constraint >= 1" This: - Preserves API compatibility (errors still structured as FastAPI/Pydantic format) - Fixes the parsing bug in http.py (messages now match "{field}: {msg}" pattern) - Prevents information leakage through user input echo - Maintains good UX with clear, actionable error messages * Skip ITs that coglet alpha does not support Coglet Alpha is now being tested properly across the board. A number of these tests were not properly run for coglet alpha due to missing propagation of the `COG_WHEEL` env to the build process.
Author
Parents
Loading