-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Migrate a part of the users API to Fast API #16341
Conversation
@mvdbeek But the show operation also handles the Also it is hard to remove the legacy routes, because there are multiple routes handled by the following legacy route: All of the following routes are handeled by it: So should migrate them all? |
Yes, that would be great! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Some minor comments, just around consistency, all the rest looks pretty good!
21650f2
to
6683719
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
galaxy/lib/galaxy/webapps/galaxy/api/users.py
Line 700 in 3d258db
def create(self, trans: GalaxyWebTransaction, payload: dict, **kwd): |
This endpoint uses the following method:
galaxy/lib/galaxy/webapps/base/webapp.py
Line 757 in 7842619
def get_or_create_remote_user(self, remote_user_email): |
The method uses the
environ
attribute of the GalaxyWebTransaction
class two times as follows:
if "webapp" not in self.environ or self.environ["webapp"] != "tool_shed":
I do not know how to access the environ
attribute outside of the GalaxyWebTransaction
class.
Are these if-conditions necessary?
Because if I can ignore them I could copy the method to UserService or Manager and then migrate this endpoint to FastAPI.
Could anyone help me with this one?
is a weird way to ensure we're in Galaxy
I suppose you could check if the associated app or request is Galaxy-specific. This brings me to something important though, it would be good that we don't duplicate logic between the tool shed and Galaxy. UserManager is also used in the tool shed, so there you'd do something like diff --git a/lib/tool_shed/webapp/app.py b/lib/tool_shed/webapp/app.py
index 3a9e0fe273..3f27d5bcca 100644
--- a/lib/tool_shed/webapp/app.py
+++ b/lib/tool_shed/webapp/app.py
@@ -80,7 +80,7 @@ class UniverseApplication(ToolShedApp, SentryClientMixin, HaltableContainer):
self._register_singleton(SharedModelMapping, model)
self._register_singleton(mapping.ToolShedModelMapping, model)
self._register_singleton(scoped_session, self.model.context)
- self.user_manager = self._register_singleton(UserManager, UserManager)
+ self.user_manager = self._register_singleton(UserManager, UserManager(app_type="tool_shed"))
self.api_keys_manager = self._register_singleton(ApiKeyManager)
# initialize the Tool Shed tag handler.
self.tag_handler = CommunityTagHandler(self) (also Or you could create a app-specific class hierarchy for UserManager and eliminate the if completely. That seems like more work for marginal gains, I'll let you decide on that. |
I have done it this way. In addition to the app_type i also passed self to the UserManager: galaxy/lib/tool_shed/webapp/app.py Line 83 in a947282
However, I am not sure how to create a test that uses the get_or_create_remote_user method, so I just tested it manually. Can somebody write a test for this? |
lib/galaxy/schema/schema.py
Outdated
@@ -338,6 +342,15 @@ class DetailedUserModel(BaseUserModel, AnonUserModel): | |||
tags_used: List[str] = Field(default=Required, title="Tags used", description="Tags used by the user") | |||
|
|||
|
|||
class UserCreationPayload(Model): | |||
password: str = Field(default=Required, title="user_password", description="The password of the user.") | |||
remote_user_email: Optional[str] = Field( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be the only required field when use_remote_user
is set in the Galaxy config, see https://bioblend.readthedocs.io/en/latest/api_docs/galaxy/all.html#bioblend.galaxy.users.UserClient.create_local_user and https://bioblend.readthedocs.io/en/latest/api_docs/galaxy/all.html#bioblend.galaxy.users.UserClient.create_remote_user
I would separate this into two alternative models and then create a union for valid payloads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made the suggested changes.
Do you mind pulling in e775edf ? That should fix the client build tests. |
Great work @heisner-tillman! |
lib/galaxy/schema/schema.py
Outdated
|
||
# TODO Add descriptions | ||
class CustomBuildCreationPayload(CustomBuildBaseModel): | ||
len_type: str = Field( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make this an enum of possible values, I think that's file
, fasta
and text
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made the suggested changes.
Excellent work, thanks so much @heisner-tillman! Are you interested in taking this work and updating the client to use the new schema models you've created here ? Or are you looking for a next route to port ? |
Congratulations @heisner-tillman! :) |
Right now I am working on writing my thesis, so I won't have any time or capacity to do something else in the next month. It was fun learning new things and I felt that I contributed to something important, which also feels good :) I don't know what the future will bring, but if I can find the time, I am interested to keep contributing to the project.
That sounds interesting and I am always eager to learn something new :)
As I had fun porting those routes, that is another thing I am interested in. I would also like to thank @davelopez for always being available to answer my questions and for helping me out when I was stuck. |
This is a part of #10889.
Routes
/api/users/{id}/custom_builds
-->/api/users/{user_id}/custom_builds
/api/users/deleted
-->/api/users/deleted
/api/users/deleted/{id}
-->/api/users/deleted/{user_id}
/api/users
-->/api/users
/api/users/{id}
-->/api/users/{user_id}
/api/users/{id}/custom_builds/{key}
-->/api/users/{user_id}/custom_builds/{key}
/api/users/{id}/favorites/{object_type}
-->/api/users/{user_id}/favorites/{object_type}
/api/users/{id}/theme/{theme}
-->/api/users/{user_id}/theme/{theme}
/api/users/{id}
-->/api/users/{user_id}
/api/users/deleted/{id}/undelete
-->/api/users/deleted/{user_id}/undelete
/api/users
/api/users/{id}/custom_builds/{key}
-->/api/users/{user_id}/custom_builds/{key}
/api/users/{id}/favorites/{object_type}/{object_id}
-->/api/users/{user_id}/favorites/{object_type}/{object_id}
/api/users/{id}
-->/api/users/{user_id}
Summary
How to test the changes?
You can find the interactive API documentation here: http://127.0.0.1:8080/api/docs#/users
License