Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: How to access application context from another python module?

  1. #1
    Join Date
    Jan 2011
    Location
    Spain
    Posts
    14

    Default How to access application context from another python module?

    Hello

    I'm using ApplicationContextAware to access application context from another module, but 'app_context' is always evaluated to None. Here is my code:

    class ApplicationContextProvider(ApplicationContextAware ):

    global_app_ctx = None

    def set_app_context(self, app_context):
    global_app_ctx = app_context

    Then I declare the object in the application context.

    Accessing ApplicationContextProvider.global_app_ctx, gives 'None'.

    What's wrong here?

    Thanks

  2. #2
    Join Date
    Aug 2006
    Posts
    382

    Default

    This assumes that an instance of ApplicationContextProvider is being created inside your application context. Can you post either your PythonConfig, YAML config, or XML config file?
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

  3. #3
    Join Date
    Jan 2011
    Location
    Spain
    Posts
    14

    Default

    Sure, ApplicationContextProvider is being created inside my application context:

    <!-- Context -->
    <object class="test.context.ApplicationContextProvider"></object>
    <!-- End Context -->

    In the main module, I create an instace of a container, and then I can see set_app_ctx is invoked:

    container = ApplicationContext(XMLConfig(config_location=IOUti ls.parse_app_ctx_path()))

    But referencing Accessing ApplicationContextProvider.global_app_ctx from another module, fails

  4. #4
    Join Date
    Aug 2006
    Posts
    382

    Default

    Duhh! I now see where you posted that. I'm going to take a crack at coding the same thing, and trying to unravel why it's breaking. Perhaps shed some light on another bug.
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

  5. #5
    Join Date
    Aug 2006
    Posts
    382

    Default

    Okay, I see the problem. It is one of the gotcha's when you use Python's class-level variables. I thought this might be the issue. When you refer to global_app_context inside the set_app_context method, you need to prefix it with the class name, or it will treat it like a local variable.

    Here is my sample where everything is running correctly.

    main.py
    Code:
    from springpython.context import ApplicationContext
    from springpython.config import XMLConfig
    
    from context import ApplicationContextProvider
    import logging
    
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
    
    logger = logging.getLogger("springpython")
    logger.setLevel(logging.DEBUG)
    logger.addHandler(ch)
    
    my_logger = logging.getLogger("app_context_aware")
    my_logger.setLevel(logging.DEBUG)
    my_logger.addHandler(ch)
    
    container = ApplicationContext(XMLConfig("app-context.xml"))
    service = container.get_object("ApplicationContextProvider")
    
    my_logger.debug("Service = %s" % service)
    my_logger.debug("Application context = %s" % ApplicationContextProvider.global_app_context)
    
    my_own_instance = ApplicationContextProvider()
    my_logger.debug("Creating my own instance of ApplicationContextProvider => %s" % my_own_instance)
    my_logger.debug("It should have the same app context: %s" % my_own_instance.global_app_context)
    context.py
    Code:
    from springpython.context import ApplicationContextAware
    
    import logging
    
    logger = logging.getLogger("app_context_aware.ApplicationContextProvider")
    
    class ApplicationContextProvider(ApplicationContextAware):
        global_app_context = None
    
        def set_app_context(self, app_context):
            logger.debug("Updating global_app_context to %s" % app_context)
            ApplicationContextProvider.global_app_context = app_context
    
    And my app-context.xml file:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <objects xmlns="http://www.springframework.org/springpython/schema/objects/1.1"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/springpython/schema/objects/1.1
                   http://springpython.webfactional.com/schema/context/spring-python-context-1.1.xsd">
    
    	<object id="ApplicationContextProvider"  class="context.ApplicationContextProvider"/>
    
    </objects>
    Here is the output:
    Code:
    (sp)gturnquist-mbp:app_context_aware gturnquist$ python main.py
    2011-10-27 12:23:00,449 - springpython.container.ObjectContainer - DEBUG - === Scanning configuration <springpython.config._xml_config.XMLConfig object at 0x10064f310> for object definitions ===
    2011-10-27 12:23:00,449 - springpython.config.XMLConfig - DEBUG - ==============================================================
    2011-10-27 12:23:00,450 - springpython.config.XMLConfig - DEBUG - * Parsing app-context.xml
    2011-10-27 12:23:00,452 - springpython.config.XMLConfig - DEBUG - object: props = []
    2011-10-27 12:23:00,453 - springpython.config.XMLConfig - DEBUG - object: There are 0 props
    2011-10-27 12:23:00,453 - springpython.config.XMLConfig - DEBUG - ==============================================================
    2011-10-27 12:23:00,453 - springpython.config.XMLConfig - DEBUG - Parsed id=ApplicationContextProvider props=[] scope=scope.SINGLETON factory=ReflectiveObjectFactory(context.ApplicationContextProvider)
    2011-10-27 12:23:00,453 - springpython.container.ObjectContainer - DEBUG - ApplicationContextProvider object definition does not exist. Adding to list of definitions.
    2011-10-27 12:23:00,453 - springpython.container.ObjectContainer - DEBUG - === Done reading object definitions. ===
    2011-10-27 12:23:00,453 - springpython.context.ApplicationContext - DEBUG - Eagerly fetching ApplicationContextProvider
    2011-10-27 12:23:00,453 - springpython.context.ApplicationContext - DEBUG - Did NOT find object 'ApplicationContextProvider' in the singleton storage.
    2011-10-27 12:23:00,453 - springpython.context.ApplicationContext - DEBUG - Creating an instance of id=ApplicationContextProvider props=[] scope=scope.SINGLETON factory=ReflectiveObjectFactory(context.ApplicationContextProvider)
    2011-10-27 12:23:00,453 - springpython.factory.ReflectiveObjectFactory - DEBUG - Creating an instance of context.ApplicationContextProvider
    2011-10-27 12:23:00,453 - springpython.context.ApplicationContext - DEBUG - Stored object 'ApplicationContextProvider' in container's singleton storage
    2011-10-27 12:23:00,454 - app_context_aware.ApplicationContextProvider - DEBUG - Updating global_app_context to <springpython.context.ApplicationContext object at 0x10064f390>
    2011-10-27 12:23:00,454 - app_context_aware - DEBUG - Service = <context.ApplicationContextProvider object at 0x10064f490>
    2011-10-27 12:23:00,454 - app_context_aware - DEBUG - Application context = <springpython.context.ApplicationContext object at 0x10064f390>
    2011-10-27 12:23:00,454 - app_context_aware - DEBUG - Creating my own instance of ApplicationContextProvider => <context.ApplicationContextProvider object at 0x10064ff10>
    2011-10-27 12:23:00,454 - app_context_aware - DEBUG - It should have the same app context: <springpython.context.ApplicationContext object at 0x10064f390>
    2011-10-27 12:23:00,454 - springpython.context.ApplicationContext - DEBUG - Invoking the destroy_method on registered objects
    2011-10-27 12:23:00,454 - springpython.context.ApplicationContext - DEBUG - Successfully invoked the destroy_method on registered objects
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

  6. #6
    Join Date
    Jan 2011
    Location
    Spain
    Posts
    14

    Default

    Did you try to use ApplicationContextProvider inside another module, (ex. test.py)? Hope prefixing the variable with a class name won't raise NoneType error, when trying to get global_app_context (ApplicationContextProvider.global_app_context).

    Thanks : )

  7. #7
    Join Date
    Aug 2006
    Posts
    382

    Default

    Tweaking things a bit, it seems to still work. If there is some use case I'm not getting, then please elaborate.

    Code:
    my_own_instance = ApplicationContextProvider()
    my_logger.debug("Creating my own instance of ApplicationContextProvider => %s" % my_own_instance)
    my_logger.debug("It should have the same app context: %s" % my_own_instance.global_app_context)
    my_logger.debug("Globally %s" % ApplicationContextProvider.global_app_context)
    
    my_logger.debug("What about calling another module? %s" % module.testit())
    module.py
    Code:
    from context import ApplicationContextProvider
    
    import logging
    
    def testit():
        my_logger = logging.getLogger("app_context_aware.module")
    
        my_logger.debug("ApplicationContextProvider import = %s" % ApplicationContextProvider)
    
        my_own_instance = ApplicationContextProvider()
        my_logger.debug("Creating my own instance of ApplicationContextProvider => %s" % my_own_instance)
        my_logger.debug("It should have the same app context: %s" % my_own_instance.global_app_context)
    
        my_logger.debug("Modularly %s" % ApplicationContextProvider.global_app_context)
    
        return ApplicationContextProvider.global_app_context
    output
    Code:
    2011-10-27 15:05:47,703 - app_context_aware - DEBUG - Creating my own instance of ApplicationContextProvider => <context.ApplicationContextProvider object at 0x10064ff50>
    2011-10-27 15:05:47,703 - app_context_aware - DEBUG - It should have the same app context: <springpython.context.ApplicationContext object at 0x10064f3d0>
    2011-10-27 15:05:47,703 - app_context_aware - DEBUG - Globally <springpython.context.ApplicationContext object at 0x10064f3d0>
    2011-10-27 15:05:47,703 - app_context_aware.module - DEBUG - ApplicationContextProvider import = <class 'context.ApplicationContextProvider'>
    2011-10-27 15:05:47,703 - app_context_aware.module - DEBUG - Creating my own instance of ApplicationContextProvider => <context.ApplicationContextProvider object at 0x10064ffd0>
    2011-10-27 15:05:47,703 - app_context_aware.module - DEBUG - It should have the same app context: <springpython.context.ApplicationContext object at 0x10064f3d0>
    2011-10-27 15:05:47,703 - app_context_aware.module - DEBUG - Modularly <springpython.context.ApplicationContext object at 0x10064f3d0>
    2011-10-27 15:05:47,703 - app_context_aware - DEBUG - What about calling another module? <springpython.context.ApplicationContext object at 0x10064f3d0>
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

  8. #8
    Join Date
    Aug 2006
    Posts
    382

    Default

    Regarding NoneType error, if you do an import to get your class into whatever module you are working, it should be available, as long as the application context has had time to be created.
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

  9. #9
    Join Date
    Jan 2011
    Location
    Spain
    Posts
    14

    Default

    Well, your solution is working because you are calling "testit()" method from the same module where container is being created. I want to have global access to application context from any point of my app, after main module had been executed. Is that possible?

  10. #10
    Join Date
    Aug 2006
    Posts
    382

    Default

    I guess I need a use case where this is happening. Are you talking about something like a web container, where one part is the app context, but another part is your module?
    Greg L. Turnquist (@gregturn), SpringSource/VMware
    Project Lead: Spring Python and author of Spring Python 1.1 and Python Testing Cookbook.
    Listen to Pond Jumpers, the international podcast for open source developers.
    These comments are my own personal opinions, and do not reflect those of my company.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •