Skip to content

Functions draft, dontmerge ✨ 🗃️ #7539

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

wvangeit
Copy link
Contributor

@wvangeit wvangeit commented Apr 16, 2025

This a RFC for the functions API. Mostly to get feedback from Mads/Pedro.
I'm aware that there are still quite a few things to be improved/fixed in this branch.
Examples of the most obvious:

  • reusing the model/schemas at several layers should be split, i did it this way for now to make refactoring easier.
  • add tests
  • functions are just projects atm, but i will add solvers etc
  • ...

What do these changes do?

This introduces the Functions API.
Functions are objects that can be in the backend: projects, solvers, python code, etc ...
Users can create their own functions from the relevant objects.
They accept parameters and return results.
Each function run creates a function job. These function job can also act as a cache to prevent rerunning a function with the same parameters.

Related issue/s

#7506

How to test

TBD
A high-level functional test script is here:
https://github.com/wvangeit/osparc-functions-api-test/blob/master/test.py

Dev-ops checklist

@wvangeit wvangeit added a:api framework api, data schemas, Feedback labels Apr 16, 2025
@wvangeit wvangeit added this to the Pauwel Kwak milestone Apr 16, 2025
@wvangeit wvangeit requested a review from bisgaard-itis April 16, 2025 10:19
@wvangeit wvangeit self-assigned this Apr 16, 2025
Copy link

codecov bot commented Apr 16, 2025

Codecov Report

Attention: Patch coverage is 58.64811% with 208 lines in your changes missing coverage. Please review.

Project coverage is 87.16%. Comparing base (301f34c) to head (080e4fb).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7539      +/-   ##
==========================================
- Coverage   87.48%   87.16%   -0.33%     
==========================================
  Files        1742     1678      -64     
  Lines       67432    65991    -1441     
  Branches     1144     1048      -96     
==========================================
- Hits        58990    57518    -1472     
- Misses       8121     8174      +53     
+ Partials      321      299      -22     
Flag Coverage Δ
integrationtests 65.10% <32.27%> (-0.12%) ⬇️
unittests 86.31% <58.64%> (-0.35%) ⬇️
Components Coverage Δ
api ∅ <ø> (∅)
pkg_aws_library ∅ <ø> (∅)
pkg_dask_task_models_library ∅ <ø> (∅)
pkg_models_library 92.13% <100.00%> (+0.14%) ⬆️
pkg_notifications_library 85.26% <ø> (ø)
pkg_postgres_database 88.24% <100.00%> (+0.05%) ⬆️
pkg_service_integration 70.03% <ø> (ø)
pkg_service_library 72.19% <0.00%> (-0.46%) ⬇️
pkg_settings_library ∅ <ø> (∅)
pkg_simcore_sdk 85.40% <ø> (ø)
agent 96.46% <ø> (ø)
api_server 89.24% <71.80%> (-1.02%) ⬇️
autoscaling 96.08% <ø> (ø)
catalog 92.52% <ø> (ø)
clusters_keeper 99.24% <ø> (ø)
dask_sidecar 91.29% <ø> (ø)
datcore_adapter 98.12% <ø> (ø)
director 76.87% <ø> (ø)
director_v2 91.25% <ø> (-0.05%) ⬇️
dynamic_scheduler 97.40% <ø> (ø)
dynamic_sidecar 90.11% <ø> (ø)
efs_guardian 89.79% <ø> (ø)
invitations 93.28% <ø> (ø)
payments 92.66% <ø> (ø)
resource_usage_tracker 89.12% <ø> (+0.10%) ⬆️
storage 87.59% <ø> (+0.03%) ⬆️
webclient ∅ <ø> (∅)
webserver 85.55% <32.91%> (-0.44%) ⬇️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 301f34c...080e4fb. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@bisgaard-itis bisgaard-itis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the great effort Werner! It looks very cool.
I suggest several minor changes, but I have one big request and that concerns running the function. I think it is crucial that that happens asyncronously and in one of our dedicated celery workers. This call (in the case of studies) was exactly what was blocking us last time we did the metamodeling. We are in a better position now because we have a job scheduling framework for handling "internal long running tasks". We should use it! 😁

)
else: # noqa: RET505
msg = f"Unsupported function class: [{function.function_class}]"
raise TypeError(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one too

)
else: # noqa: RET505
msg = f"Unsupported function class: [{returned_function_job.function_class}]"
raise TypeError(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one too

)
else: # noqa: RET505
msg = f"Unsupported function class: [{returned_function_job.function_class}]"
raise TypeError(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this error should probably be propagated to the api-server

@wvangeit
Copy link
Contributor Author

Thanks a lot for the great effort Werner! It looks very cool. I suggest several minor changes, but I have one big request and that concerns running the function. I think it is crucial that that happens asyncronously and in one of our dedicated celery workers. This call (in the case of studies) was exactly what was blocking us last time we did the metamodeling. We are in a better position now because we have a job scheduling framework for handling "internal long running tasks". We should use it! 😁

Yeah, sure makes sense. I'm basically calling the study_job api. It's probably best to implement the celery changes there? (it they're not there yet)

Copy link
Contributor

@bisgaard-itis bisgaard-itis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the changes. I had another look and provided some more feedback. I think it is quite critical that we sort out the run function so that creating it becomes a long running task in a celery worker somewhere.

description: str | None = None
input_schema: FunctionInputSchema | None = None
output_schema: FunctionOutputSchema | None = None

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrt the nullable uuid I suggest the following change:

class Function(BaseModel):
    title: str
    description: str
    input_schema: FunctionInputSchema
    output_schema: FunctionOutputSchema

class RegisteredFunction(Function):
    uuid: UUID

description: str | None = None
input_schema: FunctionInputSchema | None = None
output_schema: FunctionOutputSchema | None = None

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically it pays off in the long run to go for non-nullable fields, so unless there really is a good reason for them not to be there it is best to require them. At least that's my opinion

function_uid: FunctionID
inputs: FunctionInputs | None
outputs: FunctionOutputs | None

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you just need to inherit from the ApiServerInputSchema and it will give you the correct formatting of the schema. I don't see why that doesn't give you the flexibility you want?


if row is None:
msg = "No row was returned from the database after creating function."
raise ValueError(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, an assert could also make sense here. In that case, remember to append # nosec so we can disable those in production some day in case we want to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:api framework api, data schemas, Feedback
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants