remi icon indicating copy to clipboard operation
remi copied to clipboard

naive question

Open jefmud opened this issue 6 years ago • 16 comments

I am impressed with the work you have done so far. To me, it seems you are very close to a new concept web framework (stand-alone web applets).

That being said...

I couldn't quite pick this up from my cursory reading of your code. Is there support for child-apps? And/or routing to said child-apps (e.g. on same port, but different path).

jefmud avatar Oct 09 '18 12:10 jefmud

Hello @jefmud ! What you need to do exactly?

Using the same port you can point to a single specific application, but however the same application can have multiple views. Such views are not separate App processes, but can be considered different context to the user point of view.

Using web technology (and specifically iframe tag) we can teorically embed one application into another. I never tested it, but however should be feasible.

What you need to do? Maybe I can suggest you the right solution

dddomodossola avatar Oct 09 '18 13:10 dddomodossola

Thanks for indulging my question-- I think I am understanding your intent. I was thinking about something just a little different, along the lines of Bottle or Flask framework.

I see some interesting possibilities in using this for mobile apps.

Here's what I was thinking about:

  1. assume: the main method encapsulated in MyApp services the top-level route.
  2. is it possible to design another entirely different view as a method on MyApp or to register another class-based view or maybe even an api that pushes/pulls data into the app? (e.g. view2, view3, api etc.)

localhost:8081/ (e.g. primary main view) localhost:8081/view2 localhost:8081/view3 localhost:8081/api (e.g. POST/GET, etc. data exchange api)

Thanks again for indulging these speculative questions.

jefmud avatar Oct 09 '18 14:10 jefmud

It's a pleasure to discuss about software :D

Here is an example about API: https://github.com/dddomodossola/remi/blob/master/examples/webAPI_app.py

Widgets methods are accessible by GET POST and WEBSOCKET "calls". Each widget is identified by its instance id. The example shows the possibility to "override" that id, setting up a fixed identifier, making it possible to address a specific widget method directly.

dddomodossola avatar Oct 09 '18 14:10 dddomodossola

Thanks! Keep up the good work!

jefmud avatar Oct 09 '18 15:10 jefmud

;-) have a good development

dddomodossola avatar Oct 09 '18 15:10 dddomodossola

Sorry for necromancing this thread - but I was wondering if the routing can be done within the app (as opposed to the api call in webAPI_app.py).

So for example in root_widget_change_app.py, I'd like http://127.0.0.1:42411/page1 and http://127.0.0.1:42411/page2 to be available, and route to that page accordingly, instead of being purely GUI-point-and-click-based. Is this available already or would it be hard to implement on the user side?

thanks for the great framework btw!

husnoo avatar Dec 19 '23 18:12 husnoo

Hello @husnoo , It should be feasible by a simple App class overloading. Of course it is out of the standard operating logic, but just for fun I will try to make you an example about this. I will write you in about 1 day ;-)

dddomodossola avatar Dec 19 '23 18:12 dddomodossola

Thank you so much! No hurry at all, happy to hack if you provide hints too! I tried it with the webApp example - instead of returning ok, I returned a wid=gui.VBox(), but that didn't go too well.

So ideally I'm looking for http://127.0.0.1:42411/ ----> main page, http://127.0.0.1:42411/page2?key=value&otherkey=somevalue, so I can use that information in the same way you do it in the webAPI example:

    def api_set_text(self, value1, value2):
        self.set_text('parameters: %s - %s' % (value1, value2))

husnoo avatar Dec 19 '23 18:12 husnoo

This seems relevant: https://github.com/rawpython/remi/issues/461 (where you basically say don't do it :P)

But I think that view would be throwing away a really useful part of the web, which is deep-linking into an app's views.

husnoo avatar Dec 19 '23 19:12 husnoo

I think a clean approach from the remi-using-developer perspective would be if the def main(self): could give the url as a string, for example, and then I'd choose to show one root widget or another?

husnoo avatar Dec 19 '23 19:12 husnoo

In remi "urls" are function calls composed by [object id]/[function name]. Changing this logic could be a problem.

dddomodossola avatar Dec 19 '23 19:12 dddomodossola

This is both cool and horrific! I can imagine one way of misusing it - calling the url sets a flag and then redirects to the main page, which looks at the flag and shows the right "page".

husnoo avatar Dec 19 '23 20:12 husnoo

@husnoo Here is an example for you, maybe not the most elegant solution, but an interesting hacking :-D

import remi.gui as gui
from remi import start, App


class PageManager(gui.Tag):
    app_instance = None
    page1_widget = None
    page2_widget = None

    def __init__(self, app_instance, **kwargs):
        super(PageManager, self).__init__(**kwargs)
        self.app_instance = app_instance

    def set_page1_widget(self, w):
        self.page1_widget = w

    def set_page2_widget(self, w):
        self.page2_widget = w

    # api function
    def page1(self):
        self.app_instance.set_root_widget(self.page1_widget)
        headers = {'Content-type': 'text/html'}
        #this is to redirect to the main URL
        return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]

    def page2(self):
        self.app_instance.set_root_widget(self.page2_widget)
        headers = {'Content-type': 'text/html'}
        #this is to redirect to the main URL
        return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]


class MyApp(App):
    def __init__(self, *args):
        super(MyApp, self).__init__(*args)

    def main(self):
        wid = gui.VBox()

        # the 'id' param allows to have an alias in the url to refer to the widget that will manage the call
        self.page_manager = PageManager(self, attributes={'id': 'page_manager'})
        self.page_manager.set_page1_widget(gui.Label('This is the PAGE1 type url "http://127.0.0.1:8082/page_manager/page2"'))
        self.page_manager.set_page2_widget(gui.Label("This is the PAGE2"))

        self.lbl = gui.Label('type url "http://127.0.0.1:8082/page_manager/page1" !')
        self.lbl.style['margin'] = 'auto'

        # appending a widget to another, the first argument is a string key
        wid.append(self.lbl)

        # returning the root widget
        return wid


if __name__ == "__main__":
    # starts the webserver
    # optional parameters
    # start(MyApp,address='127.0.0.1', port=8081, multiple_instance=False,enable_file_cache=True, update_interval=0.1,
    # start_browser=True)
    start(MyApp, debug=True, address='127.0.0.1', port=8082)

dddomodossola avatar Dec 19 '23 23:12 dddomodossola

That's really cool! Thanks! It does do what I had in mind. A bit ugly in terms of the url going back to the root, but much better than no url!

thanks again!

On Tue, 19 Dec 2023 at 23:12, Davide Rosa @.***> wrote:

@husnoo https://github.com/husnoo Here is an example for you, maybe not the most elegant solution, but an interesting hacking :-D

import remi.gui as guifrom remi import start, App

class PageManager(gui.Tag): app_instance = None page1_widget = None page2_widget = None

def __init__(self, app_instance, **kwargs):
    super(PageManager, self).__init__(**kwargs)
    self.app_instance = app_instance

def set_page1_widget(self, w):
    self.page1_widget = w

def set_page2_widget(self, w):
    self.page2_widget = w

# api function
def page1(self):
    self.app_instance.set_root_widget(self.page1_widget)
    headers = {'Content-type': 'text/html'}
    #this is to redirect to the main URL
    return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]

def page2(self):
    self.app_instance.set_root_widget(self.page2_widget)
    headers = {'Content-type': 'text/html'}
    #this is to redirect to the main URL
    return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]

class MyApp(App): def init(self, *args): super(MyApp, self).init(*args)

def main(self):
    wid = gui.VBox()

    # the 'id' param allows to have an alias in the url to refer to the widget that will manage the call
    self.page_manager = PageManager(self, attributes={'id': 'page_manager'})
    self.page_manager.set_page1_widget(gui.Label('This is the PAGE1 type url "http://127.0.0.1:8082/page_manager/page2"'))
    self.page_manager.set_page2_widget(gui.Label("This is the PAGE2"))

    self.lbl = gui.Label('type url "http://127.0.0.1:8082/page_manager/page1" !')
    self.lbl.style['margin'] = 'auto'

    # appending a widget to another, the first argument is a string key
    wid.append(self.lbl)

    # returning the root widget
    return wid

if name == "main": # starts the webserver # optional parameters # start(MyApp,address='127.0.0.1', port=8081, multiple_instance=False,enable_file_cache=True, update_interval=0.1, # start_browser=True) start(MyApp, debug=True, address='127.0.0.1', port=8082)

— Reply to this email directly, view it on GitHub https://github.com/rawpython/remi/issues/246#issuecomment-1863599469, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWJWSWTQ4ZFURYAJBJDL6TYKINOBAVCNFSM4F2M3IU2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBWGM2TSOJUGY4Q . You are receiving this because you were mentioned.Message ID: @.***>

husnoo avatar Dec 19 '23 23:12 husnoo

I even got the url parameters to work using the webAPI.py example: def page2(self,value1, value2): self.app_instance.set_root_widget(self.page2_widget) print('value1, value2:', value1, value2)

http://127.0.0.1:8082/page_manager/page2?value1=hello&value2=world

On Tue, 19 Dec 2023 at 23:46, Nawal Husnoo @.***> wrote:

That's really cool! Thanks! It does do what I had in mind. A bit ugly in terms of the url going back to the root, but much better than no url!

thanks again!

On Tue, 19 Dec 2023 at 23:12, Davide Rosa @.***> wrote:

@husnoo https://github.com/husnoo Here is an example for you, maybe not the most elegant solution, but an interesting hacking :-D

import remi.gui as guifrom remi import start, App

class PageManager(gui.Tag): app_instance = None page1_widget = None page2_widget = None

def __init__(self, app_instance, **kwargs):
    super(PageManager, self).__init__(**kwargs)
    self.app_instance = app_instance

def set_page1_widget(self, w):
    self.page1_widget = w

def set_page2_widget(self, w):
    self.page2_widget = w

# api function
def page1(self):
    self.app_instance.set_root_widget(self.page1_widget)
    headers = {'Content-type': 'text/html'}
    #this is to redirect to the main URL
    return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]

def page2(self):
    self.app_instance.set_root_widget(self.page2_widget)
    headers = {'Content-type': 'text/html'}
    #this is to redirect to the main URL
    return ['''<head><meta http-equiv="Refresh" content="0; URL=http://127.0.0.1:8082" /></head>''', headers]

class MyApp(App): def init(self, *args): super(MyApp, self).init(*args)

def main(self):
    wid = gui.VBox()

    # the 'id' param allows to have an alias in the url to refer to the widget that will manage the call
    self.page_manager = PageManager(self, attributes={'id': 'page_manager'})
    self.page_manager.set_page1_widget(gui.Label('This is the PAGE1 type url "http://127.0.0.1:8082/page_manager/page2"'))
    self.page_manager.set_page2_widget(gui.Label("This is the PAGE2"))

    self.lbl = gui.Label('type url "http://127.0.0.1:8082/page_manager/page1" !')
    self.lbl.style['margin'] = 'auto'

    # appending a widget to another, the first argument is a string key
    wid.append(self.lbl)

    # returning the root widget
    return wid

if name == "main": # starts the webserver # optional parameters # start(MyApp,address='127.0.0.1', port=8081, multiple_instance=False,enable_file_cache=True, update_interval=0.1, # start_browser=True) start(MyApp, debug=True, address='127.0.0.1', port=8082)

— Reply to this email directly, view it on GitHub https://github.com/rawpython/remi/issues/246#issuecomment-1863599469, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWJWSWTQ4ZFURYAJBJDL6TYKINOBAVCNFSM4F2M3IU2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBWGM2TSOJUGY4Q . You are receiving this because you were mentioned.Message ID: @.***>

husnoo avatar Dec 19 '23 23:12 husnoo

Yes, that's normal, because we haven't affected the Remi url use. ;-)

dddomodossola avatar Dec 20 '23 06:12 dddomodossola