OT - at least a bit - application package/folder structure

It is really a python question, but I hope people won't mind if I post it.

Starting a new project (actually redoing an old one) I like to get rid of some of my hacks and structure things a lot better etc.

First thing I did is define a new package/folder structure, and here is were I hit a problem.

How to structure it and use absolute imports (which I believe is recommend) and be able to run/use ui.textctrl.py by itself and also from within e.g. adialog.

Here is the relevant package/folder structure I like to use:

app
- __init__.py
- ui
-- __init__.py
-- textctrl.py
- mypub.py
- adialog.py

In ui.textctrl.py I have the import "from mypub import pub" to setup pubsub, now if I use ui.textctrl inside e.g. adialog.py I am fine, but if I like to have e.g. some testcode in ui.textctrl then I get an import error on "mypub".

Doing quit a bit of googling I didn't find an answer which gave a nice solution.

Do I really have to do something like this in ui.textctrl.py to be able to use it both ways or I am totally missing something?

try:
     from mypub import pub
except:
     sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
     from mypub import pub

Werner

How to structure it and use absolute imports (which I believe is
recommend) and be able to run/use ui.textctrl.py by itself and also from
within e.g. adialog.

It seemed that the new relative import system should have made this easier, but it hasn't for me.

However, I have come up with a system I like. The key is the setuptools' "develop" mode.

Here is the relevant package/folder structure I like to use:

app
- __init__.py
- ui
-- __init__.py
-- textctrl.py
- mypub.py
- adialog.py

so here I would create a setup.py that defines a package, perhaps an "app" packages, with a "ui" subpackage. (though I wouldn't use the name, "app").

then you do:

python setup.py develop

what that does is install the package with links to the source code, rather than copies in site-packages. So you can now do:

from app.ui import textctrl

(or whatever).

But when you update textctrl.py, you see the update without having to re-install.

-Chris

···

On 8/29/11 4:15 AM, werner wrote:

In ui.textctrl.py I have the import "from mypub import pub" to setup
pubsub, now if I use ui.textctrl inside e.g. adialog.py I am fine, but
if I like to have e.g. some testcode in ui.textctrl then I get an import
error on "mypub".

Doing quit a bit of googling I didn't find an answer which gave a nice
solution.

Do I really have to do something like this in ui.textctrl.py to be able
to use it both ways or I am totally missing something?

try:
from mypub import pub
except:
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..'))
from mypub import pub

Werner

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi Chris,

How to structure it and use absolute imports (which I believe is
recommend) and be able to run/use ui.textctrl.py by itself and also from
within e.g. adialog.

It seemed that the new relative import system should have made this easier, but it hasn't for me.

I started with using relative import but run into other import problems.

However, I have come up with a system I like. The key is the setuptools' "develop" mode.

That sounds interesting, had a quick "google" but what I found so far isn't that clear, although the post in the following link looks as if one just uses a standard "setup.py", i.e. I don't see anything special in that setup.py with regards to the "develop" mode.

http://www.5dollarwhitebox.org/drupal/node/75

Will do some more searching and do some tests with this in the next couple of days.

Here is the relevant package/folder structure I like to use:

app
- __init__.py
- ui
-- __init__.py
-- textctrl.py
- mypub.py
- adialog.py

so here I would create a setup.py that defines a package, perhaps an "app" packages, with a "ui" subpackage. (though I wouldn't use the name, "app").

Yes, "app" should probably be called something else. Maybe "source" or whatever, it will basically contain all the scripts/modules which make up the application with sub-packages for such things as the SQLAlchemy models, ui base widgets and so on.

"defines a package"? Not sure what you mean by that, my use/knowledge of setup.py is limited to py2exe, for that I define scripts to have py2exe'd and tell it which packages to include.

I guess I will have to read the setuptools documentation in more detail.

then you do:

python setup.py develop

what that does is install the package with links to the source code, rather than copies in site-packages. So you can now do:

from app.ui import textctrl

(or whatever).

But when you update textctrl.py, you see the update without having to re-install.

Thanks for the tip
Werner

···

On 08/29/2011 06:31 PM, Chris.Barker wrote:

On 8/29/11 4:15 AM, werner wrote:

pubsub, now if I use ui.textctrl inside e.g. adialog.py I am fine, but
if I like to have e.g. some testcode in ui.textctrl then I get an import
error on "mypub".

Doing quit a bit of googling I didn't find an answer which gave a nice
solution.

Do I really have to do something like this in ui.textctrl.py to be able
to use it both ways or I am totally missing something?

try:
from mypub import pub
except:
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..'))
from mypub import pub

Werner

In ui.textctrl.py I have the import "from mypub import pub" to setup

You probably at least need to import setup from setuptools instead of from distutils. That will add a bunch more commands and functionality. There is also the distribute package which is a clone/fork of setuptools which I've been using recently, and it seems a bit better in some difficult to quantify ways.

···

On 8/29/11 11:41 AM, werner wrote:

Hi Chris,

On 08/29/2011 06:31 PM, Chris.Barker wrote:

On 8/29/11 4:15 AM, werner wrote:

How to structure it and use absolute imports (which I believe is
recommend) and be able to run/use ui.textctrl.py by itself and also from
within e.g. adialog.

It seemed that the new relative import system should have made this
easier, but it hasn't for me.

I started with using relative import but run into other import problems.

However, I have come up with a system I like. The key is the
setuptools' "develop" mode.

That sounds interesting, had a quick "google" but what I found so far
isn't that clear, although the post in the following link looks as if
one just uses a standard "setup.py", i.e. I don't see anything special
in that setup.py with regards to the "develop" mode.

--
Robin Dunn
Software Craftsman

···

On 8/29/11 11:58 AM, Robin Dunn wrote:

On 8/29/11 11:41 AM, werner wrote:

Hi Chris,

On 08/29/2011 06:31 PM, Chris.Barker wrote:

On 8/29/11 4:15 AM, werner wrote:

How to structure it and use absolute imports (which I believe is
recommend) and be able to run/use ui.textctrl.py by itself and also
from
within e.g. adialog.

It seemed that the new relative import system should have made this
easier, but it hasn't for me.

I started with using relative import but run into other import problems.

However, I have come up with a system I like. The key is the
setuptools' "develop" mode.

That sounds interesting, had a quick "google" but what I found so far
isn't that clear, although the post in the following link looks as if
one just uses a standard "setup.py", i.e. I don't see anything special
in that setup.py with regards to the "develop" mode.

You probably at least need to import setup from setuptools instead of
from distutils. That will add a bunch more commands and functionality.
There is also the distribute package which is a clone/fork of setuptools
which I've been using recently, and it seems a bit better in some
difficult to quantify ways.

--
Robin Dunn
Software Craftsman

That sounds interesting, had a quick "google" but what I found so far
isn't that clear, although the post in the following link looks as if
one just uses a standard "setup.py", i.e. I don't see anything special
in that setup.py with regards to the "develop" mode.

You probably at least need to import setup from setuptools instead of
from distutils.

yup -- that's it.

http://pypi.python.org/pypi/distribute/

thanks for the link, I'll need to check that out. I've had issues with setuptools being poorly supported, maybe this is a more "live" project.

For Werner: It looks liek distribute is a fork of setuptools that is maintianing the API, so this should apply ti either:

All you "need" to do is use setuptools, rathet than the stock distutils "setup". Then you define your package. here is a simple example from a simple package of mine:

#!/usr/bin/env python

from setuptools import setup

# This setup is suitable for "python setup.py develop".
setup(
     name = "weathertools",
     version = "0.1.1",
     description='Tools for working with Wind data',
     author='Chris Barker',
     author_email='Chris.Barker@noaa.gov',
     packages = ["weathertools"],
     )

In your case, you'd put "app" in where I put "weathertools"

That's all there is to it.

note that you don't need to call these scripts "setup.py", so you can have a "setup_lib.py" for the library, a "setup_exe.py" for the py2exe setup, etc.

-Chris

···

On 8/29/11 12:00 PM, Robin Dunn wrote:

On 8/29/11 11:58 AM, Robin Dunn wrote:

On 8/29/11 11:41 AM, werner wrote:

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Chris and Robin,

···

On 08/29/2011 10:16 PM, Chris.Barker wrote:

On 8/29/11 12:00 PM, Robin Dunn wrote:

On 8/29/11 11:58 AM, Robin Dunn wrote:

On 8/29/11 11:41 AM, werner wrote:

That sounds interesting, had a quick "google" but what I found so far
isn't that clear, although the post in the following link looks as if
one just uses a standard "setup.py", i.e. I don't see anything special
in that setup.py with regards to the "develop" mode.

You probably at least need to import setup from setuptools instead of
from distutils.

yup -- that's it.

http://pypi.python.org/pypi/distribute/

thanks for the link, I'll need to check that out. I've had issues with setuptools being poorly supported, maybe this is a more "live" project.

For Werner: It looks liek distribute is a fork of setuptools that is maintianing the API, so this should apply ti either:

All you "need" to do is use setuptools, rathet than the stock distutils "setup". Then you define your package. here is a simple example from a simple package of mine:

#!/usr/bin/env python

from setuptools import setup

# This setup is suitable for "python setup.py develop".
setup(
    name = "weathertools",
    version = "0.1.1",
    description='Tools for working with Wind data',
    author='Chris Barker',
    author_email='Chris.Barker@noaa.gov',
    packages = ["weathertools"],
    )

In your case, you'd put "app" in where I put "weathertools"

That's all there is to it.

note that you don't need to call these scripts "setup.py", so you can have a "setup_lib.py" for the library, a "setup_exe.py" for the py2exe setup, etc.

Thanks for all this information, hopefully this is enough to get me going.

Werner

Chris, Robin,

Nearly there, but running into a problem with wx.lib.pubsub

Adapted the setup.py provided by Chris, reorganized the folder structure to:

appsource
__init__.py
- libui
-- __init__.py
-- textctrl.py
mypub.py
mypub_topics.py
dialogtest.py

Run python setup.py develop

Running:
- dialogtest.py runs o.k. without mypub
- textctrl.py runs o.k. without mypub
- mypub.py runs o.k. and it imports mypub_topics doing this "pub.importTopicTree("mypub_topics")"

If I activate mypub in the textctrl and run it then I get this exception:

Traceback (most recent call last):
   File "textctrl.py", line 11, in <module>
     from appsource.mypub import pub
   File "c:\devprojectswv\twcbv4\appsource\mypub.py", line 29, in <module>
     pub.importTopicTree("mypub_topics")
   File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\pub.py", line 186, in importTopicTree
     provider = TopicDefnProvider(source, format)
   File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\core\topicdefnprovider.py", line 338, in __init__
     provider = providerClassObj(source)
   File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\core\topicdefnprovider.py", line 219, in __init__
     fp, pathname, description = imp.find_module(moduleName, searchPath)
ImportError: No module named mypub_topics

If I change "pub.importTopicTree("mypub_topics")" to an absolute import e.g. "pub.importTopicTree("appsource.mypub_topics")" I still get the above exception mentioning the new string.

Is this a problem with wx.lib.pubsub not supporting an absolute import?

Werner

pubsub uses imp.find_module(moduleName, searchPath)

If searchPath not given (which would be the case given your post), the sys.path is used. I believe textctrl.py will not see modules one folder layer above since not in sys.path. You could try extending the sys.path with “…” or such, or try running from parent folder python appsource/txtctrl.py and see if that fixes problem. Please let us know if it does.

Oliver

···

On Tue, Aug 30, 2011 at 12:37 PM, werner wbruhin@free.fr wrote:

Chris, Robin,

Nearly there, but running into a problem with wx.lib.pubsub

Adapted the setup.py provided by Chris, reorganized the folder structure to:

appsource

init.py

  • libui

init.py

– textctrl.py

mypub.py

mypub_topics.py

dialogtest.py

Run python setup.py develop

Running:

  • dialogtest.py runs o.k. without mypub

  • textctrl.py runs o.k. without mypub

  • mypub.py runs o.k. and it imports mypub_topics doing this “pub.importTopicTree(“mypub_topics”)”

If I activate mypub in the textctrl and run it then I get this exception:

pubsub uses imp.find_module(moduleName, searchPath)

If searchPath not given (which would be the case given your post), the
sys.path is used.

but in his example, the module in question was in sys.path -- at least when it was qualified:

pub.importTopicTree("appsource.mypub_topics")

i.e. the appsource package is on sys.path.

It sure seems that it should be able to find anything that you can find with an import.

I believe textctrl.py will not see modules one folder
layer above since not in sys.path.

not even if they are in a package? (or subpackage).

Unless I mis-understand, this seems to be a key missing feature.

After all, "namespaces are one honking great idea"

-Chris

PS:

Werner, as a really painful kludge, it looks like you could do something like:

import appsource.mypub_topics

p = os.path.dirname(appsource.mypub_topics.__file__)

pub.importTopicTree("mypub_topics", searchPath=p)

(untested)

  You could try extending the sys.path

···

On 8/30/11 2:19 PM, oliver wrote:

with ".." or such, or try running from parent folder python
appsource/txtctrl.py and see if that fixes problem. Please let us know
if it does.

Oliver

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Oliver,

I can do in shell:

import appsource
import appsource.mypub_topics

but not:
import appsource.mypub

Following the shell output using Editra with the exception for the last line above.

import appsource
dir(appsource)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
import appsource.mypub_topics
import appsource.mypub
Traceback (most recent call last):
   File "<input>", line 1, in <module>
   File "c:\users\wbruhin\appdata\roaming\editra\plugins\pystudio-0.2-py2.7.egg\rpdb2.py", line 13490, in rpdb2_import_wrapper
     m = g_import(*args, **kwargs)
   File "c:\devprojectswv\twcbv4\appsource\mypub.py", line 29, in <module>
     pub.importTopicTree("mypub_topics")
   File "C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\pub.py", line 186, in importTopicTree
     provider = TopicDefnProvider(source, format)
   File "C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py", line 338, in __init__
     provider = providerClassObj(source)
   File "C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py", line 219, in __init__
     fp, pathname, description = imp.find_module(moduleName, searchPath)
ImportError: No module named mypub_topics

Changing:
pub.importTopicTree("mypub_topics", searchPath=p)

to:
pub.importTopicTree("appsource.mypub_topics")

Gives same exception.

Trying the suggestion from Chris to force the search path, gives me:
TypeError: importTopicTree() got an unexpected keyword argument 'searchPath'

All this testing is done on:
Python 2.7.2
wxPython 2.9.2.1 (msw-unicode)
using pubsub from above wxPython

Werner

BTW, would it be worse to create a wiki entry about all this import stuff? Searching on the net I find only pretty basic explanations (one of the better ones are: http://docs.python.org/tutorial/modules.html or http://diveintopython.org/xml_processing/packages.html but they doen't cover my problem below unless I just don't see/understand it). Or is it just me who is dense on this?

Another one I am not sure about.

The package/folder structure for this one is basically the same, but the problem is with a import of the package from within itself.

appsource
- __init__.py
--model
---__init__.py
---m_masterdata.py

The model package above is SQLAlchemy declarative based and most of it is done as e.g. TurboGears 2.x uses SA, with the exception that I don't want to use e.g. "from sqlalchemy import Table, ForeignKey, Column" instead I do "import sqlalchemy as sa" and then do "sa.Table" etc.

This works but there is one thing I don't understand why my way doesn't work.

In e.g. m_masterdata.py I would like to do:

import appsource.model as db

and then use it like this db.DeclarativeBase

That gives me an exception (just the end here):

import appsource.model as db
AttributeError: 'module' object has no attribute 'model'

But I can do this (which is how TurboGears does it too for importing the package "model" in a module contained in that package:
from appsource.model import DeclarativeBase

Werner

Doing a wiki entry sounds like a good idea to me. I may use it for the basis of a blog post too.

  • Mike

Werner (and whoever else interested in helping), I suggest we move this to pubsub forum (groups.google.com/group/pypubsub) as it is not wxpython specific; we can post the final solution to wxpython-users when we find it. Cheers,

Oliver

···

On Wed, Aug 31, 2011 at 3:56 AM, werner wbruhin@free.fr wrote:

Oliver,

I can do in shell:

import appsource

import appsource.mypub_topics

but not:

import appsource.mypub

Following the shell output using Editra with the exception for the last line above.

import appsource

dir(appsource)

[‘builtins’, ‘doc’, ‘file’, ‘name’, ‘package’, ‘path’]

import appsource.mypub_topics

import appsource.mypub

Traceback (most recent call last):

File “”, line 1, in

File “c:\users\wbruhin\appdata\roaming\editra\plugins\pystudio-0.2-py2.7.egg\rpdb2.py”, line 13490, in rpdb2_import_wrapper

m = g_import(*args, **kwargs)

File “c:\devprojectswv\twcbv4\appsource\mypub.py”, line 29, in

pub.importTopicTree("mypub_topics")

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\pub.py”, line 186, in importTopicTree

provider = TopicDefnProvider(source, format)

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py”, line 338, in init

provider = providerClassObj(source)

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py”, line 219, in init

fp, pathname, description = imp.find_module(moduleName, searchPath)

ImportError: No module named mypub_topics

Changing:

pub.importTopicTree(“mypub_topics”, searchPath=p)

to:

pub.importTopicTree(“appsource.mypub_topics”)

Gives same exception.

Trying the suggestion from Chris to force the search path, gives me:

TypeError: importTopicTree() got an unexpected keyword argument ‘searchPath’

All this testing is done on:

Python 2.7.2

wxPython 2.9.2.1 (msw-unicode)

using pubsub from above wxPython

Werner

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

(please follow-up, if at all, on pypubsub@googlegroups.com)

pubsub uses imp.find_module(moduleName, searchPath)

If searchPath not given (which would be the case given your post), the

sys.path is used.

but in his example, the module in question was in sys.path – at least when it was qualified:

pub.importTopicTree(“appsource.mypub_topics”)

i.e. the appsource package is on sys.path.

yes but mypub*.py are not in appsource.

pub.importTopicTree(“mypub_topics”, searchPath=p)

there is currently no such arg accepted by importTopicTree (not that it would be hard to patch – I’ll add to todo list).

Oliver

···

On Wed, Aug 31, 2011 at 12:45 AM, Chris Barker Chris.Barker@noaa.gov wrote:

On 8/30/11 2:19 PM, oliver wrote:

OK so the solution ended up really simple: imp.find_module, which pubsub currently uses, does not support hierarchical modules names (names with a dot in them). Turns out that Python 2.7’s importlib does, AND it is available as a separate download on cheeseshop for versions <= 2.6. Wermer patched his version of pubsub to use this (next release of pubsub will contain a patch that supports hierarchical module names – to the extent that importlib does). Cheers,
Oliver

···

On Wed, Aug 31, 2011 at 3:56 AM, werner wbruhin@free.fr wrote:

Oliver,

I can do in shell:

import appsource

import appsource.mypub_topics

but not:

import appsource.mypub

Following the shell output using Editra with the exception for the last line above.

import appsource

dir(appsource)

[‘builtins’, ‘doc’, ‘file’, ‘name’, ‘package’, ‘path’]

import appsource.mypub_topics

import appsource.mypub

Traceback (most recent call last):

File “”, line 1, in

File “c:\users\wbruhin\appdata\roaming\editra\plugins\pystudio-0.2-py2.7.egg\rpdb2.py”, line 13490, in rpdb2_import_wrapper

m = g_import(*args, **kwargs)

File “c:\devprojectswv\twcbv4\appsource\mypub.py”, line 29, in

pub.importTopicTree("mypub_topics")

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\pub.py”, line 186, in importTopicTree

provider = TopicDefnProvider(source, format)

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py”, line 338, in init

provider = providerClassObj(source)

File “C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\lib\pubsub\core\topicdefnprovider.py”, line 219, in init

fp, pathname, description = imp.find_module(moduleName, searchPath)

ImportError: No module named mypub_topics

Werner

Mike,

···

On 08/31/2011 03:17 PM, Mike Driscoll wrote:

Doing a wiki entry sounds like a good idea to me. I may use it for the basis of a blog post too.

I have started it and will complete it over the next days/weeks whenever I "fall over" something while testing it in my app.

Werner

For the archive, here it is:

http://wiki.wxpython.org/Folder_structure_for_an_application

···

On 9/2/11 5:34 AM, werner wrote:

Mike,

On 08/31/2011 03:17 PM, Mike Driscoll wrote:

Doing a wiki entry sounds like a good idea to me. I may use it for the
basis of a blog post too.

I have started it and will complete it over the next days/weeks whenever
I "fall over" something while testing it in my app.

--
Robin Dunn
Software Craftsman

Oops.

Thanks Robin
Werner

···

On 09/03/2011 03:20 AM, Robin Dunn wrote:

On 9/2/11 5:34 AM, werner wrote:

Mike,

On 08/31/2011 03:17 PM, Mike Driscoll wrote:

Doing a wiki entry sounds like a good idea to me. I may use it for the
basis of a blog post too.

I have started it and will complete it over the next days/weeks whenever
I "fall over" something while testing it in my app.

For the archive, here it is:

http://wiki.wxpython.org/Folder_structure_for_an_application

That shortcut doesn’t work for me. I did find one here though: http://wiki.wxpython.org/Import%20and%20folder%20structure%20for%20appplication

  • Mike