Skip to content

Make django_idom an installable app #3

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

Merged
merged 36 commits into from
Aug 19, 2021
Merged

Make django_idom an installable app #3

merged 36 commits into from
Aug 19, 2021

Conversation

rmorshea
Copy link
Contributor

No description provided.

@Archmonger
Copy link
Contributor

Archmonger commented Jul 26, 2021

Hey @rmorshea
I think we might be creating a bit of a misnomer by calling the main IDOM element def root(). It feels strange to me to potentially have 20 "roots".

Ideas:

  • main
  • main_component
  • base_component

main still feels weird to have multiple mains though. Worth a discussion IMO.

@rmorshea
Copy link
Contributor Author

@Archmonger so I came up with a simpler idea, we'll look for a module <app>.idom and in that module it must have an __all__ attribute (this is a standard attribute for modules). Anything declared in __all__ is expected to be a component constructor.

With this my_app.idom could look like this:

import idom

__all__ = ["MyComponent"]

@idom.component
def MyComponent():
    ...

or it could look like this:

from .my_component import MyComponent
from .my_other_component import MyOtherComponent

__all__ = ["MyComponent", "MyOtherComponent", ...]

No need for a standardized naming convention. Just list your component in the __all__ attribute of your idom module.

@rmorshea
Copy link
Contributor Author

Managed to get the test_app to run via python tests/manage.py runserver but something's wrong in the test suite.

@Archmonger
Copy link
Contributor

Archmonger commented Jul 26, 2021

Utilizing __all__ isn't very Django.

An alternative could just be a named array. For example, for HTTP views Django uses urlpatterns = []. We could create a components = [] variable and enforce it's declaration in a specific file.

For example, instead of using our app/components/ folder, we can be folder agnostic and instead just have an app/idom.py that will check for the declaration of components = [ demo_1, demo_2 ], which should be an array of IDOM components.

If we aren't targeting auto discovery, then this would be the next option that fits the Django design style.

@rmorshea
Copy link
Contributor Author

rmorshea commented Jul 28, 2021

The problem with components = [ Demo1, Demo2 ] is that components would need to be declared at the end of the file in order to reference all the defined components, which feels a bit awkward:

@component
def Demo1():
    ...

@component
def Demo2():
    ...

components = [Demo1, Demo2]

To avoid this, the components would need to be referenced by name instead of by value. Meaning, it would have to be strings components = ["Demo1", "Demo2"]. Given that I thought it would be nice to kill two birds with one stone, by just leveraging __all__ instead of coming up with a new variable name. After all, if one wanted to define __all__ in the module you'd end up having to do:

components = ["x", "y", ...]
__all__ = components

Let me know your thoughts on this reasoning though, I'm open to using something like components instead of __all__ if that would be easier for the Django community to wrap their heads around.

@rmorshea
Copy link
Contributor Author

Also, just to clarify, taking this approach does not preclude the possibility of a myapp/idom/*.py folder. It would just look like this instead:

myapp/
  idom/
    __init__.py
    my_component.py
    my_other_component.py

Where __init__.py would look like:

from .my_component import MyComponent
from .my_other_component import MyOtherComponent

__all__ = ["MyComponent", "MyOtherComponent"]

@Archmonger
Copy link
Contributor

Archmonger commented Jul 28, 2021

We wouldn't actually need to define components at the end of the file. Take a look at the Django design patterns and using views.py and urls.py as an example.

The user could define their IDOM components in any file they want. I personally would argue we tell the user to reuse Django's own views.py, or create a custom components.py. Truthfully they could even make a separate folder /components/demo_1.py, similar to Django users subfolder their views on larger projects.

User should import from .views import my_component into a components = [ my_component, ... ] to follow the same schema as urls.py.

Using __all__ within __init__.py will definitely feel foreign to any Django users, so I would highly suggest against it.

@rmorshea
Copy link
Contributor Author

rmorshea commented Jul 28, 2021

I'm not sure we'll ever need idom.py to do anything other than declare what components are available, so I'm hesitant to require the user to create a whole file that will only every contain:

from .my_component import MyComponent
from .my_other_component import MyOtherComponent
...

components = [MyComponent, MyOtherComponent, ...]

Do other projects do this sort of thing? That is, require users to create top-level config files?

@rmorshea rmorshea marked this pull request as ready for review July 28, 2021 08:18
@Archmonger
Copy link
Contributor

Archmonger commented Jul 28, 2021

That's pretty much what Django's urls.py is. The only other project I know of that works outside the framework to "extend" django's core functionality is Django Channels. As you may know, that project extends Django to support websockets. The paradigm they followed is all websockets that have been created need to be imported and placed within one central asgi.py.

So I suppose by the notion of Channels, then kind of. But channels doesn't rely on any particular file being within each Django sub-app though.

@rmorshea
Copy link
Contributor Author

I guess you're right, this is pretty much just a different form of urls.py. I think you've convinced me, but let me read a bit more on how that works

@Archmonger
Copy link
Contributor

I think appropriate filenames for us could potentially be

  • idom.py
  • components.py

And for the array could be

  • components = []
  • parts = []
  • idom = []
  • idom_components = []

Also, we have the option of mandating tuples within the array, if there's some other piece of information you'd like to pass through. For example, components = [ ('/endpoint/url/', my_component) , ... ]. I don't think we need this though? Just food for thought.

In the occasion we need more than two pieces of information, we could create a class component() and mandate that classtype is within the array.

@Archmonger
Copy link
Contributor

Archmonger commented Jul 28, 2021

Also on the note of urls.py, Django has a history of forcing the user to create small files with little information in it.

For example, check out apps.py.

Django is from 2005 which hasn't changed it's design syntax since. Some design decisions can feel weird due to that.

@rmorshea
Copy link
Contributor Author

I like idom.py as a file name - components.py is generic enough that it could clash with something in an existing project. Given that, the name idom_components feels repetitive since it'll already be in a file called idom. With all that in mind, I think requiring a components attribute to be present in myapp.idom seems appropriate. I'll make those changes now.

@Archmonger
Copy link
Contributor

Archmonger commented Jul 28, 2021

I just had an idea while thinking about Django Channels.

We could mandate the user to centralize all components into one file similar to how Channels does it.

Basically, in settings.py have a setting called IDOM_COMPONENTS, which is an importable path to the IDOM config file.

For example: IDOM_COMPONENTS = "conreq.core.idom"

Then idom.py file will have one giant components = [], and we mandate the user to import all components into this one array. Less points of failure for us.

Thinking about it, Django's root urls.py follows a similar paradigm.

@rmorshea
Copy link
Contributor Author

So basically, the file where the components need to be declared would be configurable?

@Archmonger
Copy link
Contributor

Archmonger commented Jul 28, 2021

Yeah, configurable but it's all centralized to one file.

For us, that would be far less annoying than checking each individual app.

@rmorshea
Copy link
Contributor Author

rmorshea commented Jul 28, 2021

Ah, I see. I think that might break things since in the template you have to reference the component via idom_view "my_app.MyComponent" - having a central place of declaration would mean the components would need to have globally unique names .

@rmorshea
Copy link
Contributor Author

Checking each app for an idom module isn't that bad anyway given that the list of apps is always available via INSTALLED_APPS.

Copy link
Contributor

@Archmonger Archmonger left a comment

Choose a reason for hiding this comment

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

Looks good!

@rmorshea rmorshea requested a review from Archmonger August 19, 2021 01:24
@rmorshea
Copy link
Contributor Author

Weird, your review doesn't satisfy the merge requirements. Lemme see what's going on there...

@Archmonger
Copy link
Contributor

Archmonger commented Aug 19, 2021

It's because I don't have write access to the repo.

"At least 1 approving review is required by reviewers with write access."

@rmorshea
Copy link
Contributor Author

I'll give that to you.

@rmorshea
Copy link
Contributor Author

And we're all green finally!

@rmorshea rmorshea merged commit 90db8d9 into main Aug 19, 2021
@rmorshea
Copy link
Contributor Author

I'll make a release later this evening.

@rmorshea
Copy link
Contributor Author

Released!

@Archmonger
Copy link
Contributor

👍🍻

I'll begin Conreq integration soon.

Would you have time to discuss Conreq design decisions this weekend? I want to make sure it's well aligned with IDOM for interoperability.

@rmorshea
Copy link
Contributor Author

I'll be away from my computer, but I may be able to just voice chat. I'd be able to do a normal video chat Friday afternoon or next week.

@rmorshea rmorshea deleted the installable-app branch August 19, 2021 06:17
@Archmonger
Copy link
Contributor

Friday afternoon works with me. I don't have anything scheduled for Friday so I'll add something on your calendar.

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

Successfully merging this pull request may close these issues.

2 participants