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

Add FastAPI routes for tours #11089

Merged
merged 15 commits into from
Jan 13, 2021
Merged

Conversation

jdavcs
Copy link
Member

@jdavcs jdavcs commented Jan 11, 2021

Ref #10889

@mvdbeek, @davelopez: please take a look - here's my first attempt.

Note: A pydantic TourList model (as opposed to List[Tour]) was necessary for correct serialization in web/framework/decorators.py. Even though we can modify this logic to recognize a list of pydantic models, such a list cannot be serialized using the [model].json() method.

Pydantic models (currently added to tours) require explicit
specification of model fields. Having an "id" field as required seems
right from a design standpoint.

However, if there is a reason for an "id" value to be included in the
galaxy_ui tour but not in the other tours, this field can be made
optional: `id: Optional[str] = None`
- Do not call tour_loader() twice
- Do not return a value from a function that modifies the value of its
  argument in place
- Rename function to reflect what it does
Copy link
Contributor

@davelopez davelopez left a comment

Choose a reason for hiding this comment

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

Looking great!

lib/galaxy/webapps/galaxy/api/tours.py Outdated Show resolved Hide resolved
lib/galaxy/schema/__init__.py Outdated Show resolved Hide resolved
lib/galaxy/schema/__init__.py Outdated Show resolved Hide resolved
Field not used. See code review discussion here:
galaxyproject#11089 (comment)
Address comments in code review
Model is revised due to change in Tour model spec:
- Id field is no longer part of the yaml file spec;
- However, an id is generated and added to the tour data returned as a
list
- As a result, in a list, a tour item must have an id, whereas in tour
details, a tour item must not have an id.
I've factored out "core tour" data into its own model to solve this.
@jdavcs jdavcs force-pushed the dev_fastapi_tours branch from c4549d9 to 75ed305 Compare January 11, 2021 20:35
@jdavcs jdavcs force-pushed the dev_fastapi_tours branch from 732cab1 to f1274c2 Compare January 11, 2021 22:53
@jdavcs
Copy link
Member Author

jdavcs commented Jan 11, 2021

The latest commit addresses this comment in the code review.

However, this turned out to be a good excuse to get rid of the concrete ToursRegistry class in the api module and replace it with an interface. This follows this comment; @jmchilton - does this look like the approach you were describing?

@jdavcs
Copy link
Member Author

jdavcs commented Jan 11, 2021

Note about naming the abstract class: I struggled with the naming; with ToursRegistry as the concrete class, there was nothing that felt right for the abstract class: it's a virtual class, it's not inherited, so calling it ToursRegistryBase made no sense. Besides, I don't want to "signal" to the client module that it's an abstract class (even more so for names like IToursRegistry). Yes, "abc" shadows the standard library "abc" package, but, still, I think it makes sense to have foo.Foo and foo.abc.Foo just like we now might have foo.schema.Foo. But I'm, of course, by completely open to other suggestions.

@jmchilton
Copy link
Member

I love the abc approach. In terms of naming stuff my suggestion would be to...

  • Refactorlib/galaxy/tours/__init__.py::ToursRegistry -> lib/galaxy/tours/_impl.py::ToursRegistryImpl
  • Add a def build_tours_registry(config_dir: str) -> ToursRegistry factory to _impl.py.
  • Refactor lib/galaxy/tours/abc/__init__.py::ToursRegistry -> lib/galaxy/tours/interface.py::ToursRegistry
  • Make lib/galaxy/tours/__init__.py a file that just imports ._impl.py::build_tours_registry, .schema.py::(TourStep,Tour,TourDetails,etc..), and .interface.py::ToursRegistry and re-exports the whole module's interface.

At that point I would even consider renaming schema.py and interface.py to _schema.py and _interface.py to make it clear the interface is the stuff that is exported from galaxy.tours 's root __init__.py.

Copy link
Contributor

@davelopez davelopez left a comment

Choose a reason for hiding this comment

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

Cool! I like your approach of using an ABC for the ToursRegistry :)

lib/galaxy/webapps/galaxy/api/__init__.py Outdated Show resolved Hide resolved
@mvdbeek mvdbeek modified the milestones: 21.01, 21.05 Jan 12, 2021
@jdavcs jdavcs removed the status/WIP label Jan 13, 2021
@jdavcs
Copy link
Member Author

jdavcs commented Jan 13, 2021

I love the abc approach. In terms of naming stuff my suggestion would be to...

@jmchilton thank you for the detailed suggestions - I think this makes the tours interface much cleaner.

The factory function does not have a return type annotation - that's intentional; it's related to mypy not handling ABC.register - I'll open an issue shortly.

EDIT: no need for a separate issue, here's the gist. The previous commit caused a mypy error which was due to mypy not handling virtual subsclasses. References:
python/mypy#1459
python/mypy#2922
https://docs.python.org/3/library/abc.html#abc.ABCMeta

This is (again!) ready for review.

from ._schema import TourCore # noqa
from ._schema import TourStep # noqa
from ._schema import TourDetails # noqa
from ._schema import TourList # noqa
Copy link
Member

Choose a reason for hiding this comment

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

Instead of #noqa please use __all___ at the end of the file.

__all__ = ("build_tours_registry", "Tour", ...)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

Copy link
Member

@jmchilton jmchilton left a comment

Choose a reason for hiding this comment

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

Amazing! Thanks for the deep dive into this.

@jdavcs jdavcs merged commit 882ad63 into galaxyproject:dev Jan 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants