Conventions¶
Below are recommended conventions for structuring and naming the files in your project relating to import/export.
The intention for these rules is that they are “intuitive” based on the fact that all data flows from source to target and therefore can be thought of as “importing” in virtually all cases.
But there are a lot of edge cases out there so YMMV.
“The Rules”¶
There are exceptions to these of course, but in general:
regarding how to think about these conventions:
always look at it from target’s perspective
always look at it as an import, not export
“final” logic is always a combo of:
“base” logic for how target data read/write happens generally
“specific” logic for how that happens using a particular data source
targets each get their own subpackage within project
and within that, also an
importing
(nested) subpackageand within that is where the files live, referenced next
target
model.py
should containToTarget
importer base classalso may have misc. per-model base classes, e.g.
WidgetImporter
also may have
ToTargetHandler
base class if applicable
sources each get their own module, named after the source
should contain the “final” handler class, e.g.
FromSourceToTarget
also contains “final” importer classes needed by handler (e.g.
WidgetImporter
)
Example¶
That’s a lot of rules so let’s see it. Here we assume a Wutta-based app named Poser and it integrates with a Foo API in the cloud. Data should flow both ways so we will be thinking of this as:
Foo → Poser import
Poser → Foo export
Here is the suggested file layout:
poser/
├── foo/
│ ├── __init__.py
│ ├── api.py
│ └── importing/
│ ├── __init__.py
│ ├── model.py
│ └── poser.py
└── importing/
├── __init__.py
├── foo.py
└── model.py
And the module breakdown:
poser.foo.api
has e.g.FooAPI
interface logic
Foo → Poser import (aka. “Poser imports from Foo”)
poser.importing.model
hasToPoserHandler
,ToPoser
and per-model base importersposer.importing.foo
hasFromFooToPoser
plus final importers
Poser → Foo export (aka. “Foo imports from Poser”)
poser.foo.importing.model
hasToFooHandler
,ToFoo
and per-model base importerposer.foo.importing.poser
hasFromPoserToFoo
plus final importers