Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hayhooks fails to deploy Pipeline with input/output type having Optional Fields #25

Open
advin4603 opened this issue Jun 4, 2024 · 4 comments · May be fixed by #31
Open

Hayhooks fails to deploy Pipeline with input/output type having Optional Fields #25

advin4603 opened this issue Jun 4, 2024 · 4 comments · May be fixed by #31
Assignees
Labels

Comments

@advin4603
Copy link

Hayhooks fails to deploy a pipeline which contains a component which has as its input (or output) a type which uses Optional from typing. Here's an example:

@dataclass
class Numbers:
    num_1: float
    num_2: Optional[float]


@component
class Adder:
    @component.output_types(result=float)
    def run(self, numbers: Numbers):
        return {"result": numbers.num_1 + numbers.num_2 if numbers.num_2 else 0}

pipeline = Pipeline()
pipeline.add_component("adder", Adder())
print(pipeline.inputs())
print(pipeline.run({"adder": {"numbers": Numbers(1, 2)}}))

with open("pipelines/simple_test.yaml", "w") as f:
    pipeline.dump(f)

This creates a serialised component:

components:
  adder:
    init_parameters: {}
    type: adder.Adder
connections: []
max_loops_allowed: 100
metadata: {}

Upon trying to deploy this hayhooks, the server errors with the following trace:


INFO:     Pipelines dir set to: pipelines.d
INFO:     Started server process [31222]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http:https://localhost:1416 (Press CTRL+C to quit)
INFO:     ::1:52754 - "POST /deploy HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 399, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/starlette/routing.py", line 72, in app
    response = await func(request)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/fastapi/routing.py", line 278, in app
    raw_response = await run_endpoint_function(
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
    return await dependant.call(**values)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/hayhooks/server/handlers/deploy.py", line 7, in deploy
    return deploy_pipeline_def(app, pipeline_def)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/hayhooks/server/utils/deploy_utils.py", line 20, in deploy_pipeline_def
    PipelineRunRequest = get_request_model(pipeline_def.name, pipe.inputs())
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/hayhooks/server/pipelines/models.py", line 29, in get_request_model
    input_type = handle_unsupported_types(typedef["type"], {DataFrame: dict})
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/hayhooks/server/utils/create_valid_type.py", line 39, in handle_unsupported_types
    return TypedDict(type_.__name__, new_type)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/typing_extensions.py", line 1042, in TypedDict
    td = _TypedDictMeta(typename, (), ns, total=total, closed=closed)
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/typing_extensions.py", line 873, in __new__
    own_annotations = {
  File "/home/advin4603/rag_qa/venv/lib/python3.10/site-packages/typing_extensions.py", line 874, in <dictcomp>
    n: typing._type_check(tp, msg, module=tp_dict.__module__)
  File "/usr/lib/python3.10/typing.py", line 171, in _type_check
    raise TypeError(f"Plain {arg} is not valid as type argument")
TypeError: Plain typing.Union[float, NoneType] is not valid as type argument

Looks like hayhooks is having trouble during introspection where it fails to create a TypedDict for the Numbers dataclass as it has an optional field while trying to create a valid type.

This affects GoogleAIGeminiGenerator and QdrantEmbeddingRetriever as they both use classes with optional fields as inputs.

@karbasia
Copy link

Are you still having these issues? I haven't had any problems with optional parameters (including QdrantEmbeddingRetriever) in my pipelines with Hayhooks.

@Rusteam
Copy link

Rusteam commented Jun 28, 2024

I'm having a similar issue even for an indexing pipeline with QdrantDocumentStore

@Rusteam Rusteam linked a pull request Jun 28, 2024 that will close this issue
@karbasia
Copy link

karbasia commented Jul 2, 2024

Can you share your pipeline? I'm using QdrantDocumentStore and have not had any of these issues.

@Rusteam
Copy link

Rusteam commented Jul 3, 2024

The issue came from another component that was using optional data type. I've fixed it with the PR above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants