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) subpackage

      • and within that is where the files live, referenced next

    • target model.py should contain ToTarget importer base class

      • also 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 has ToPoserHandler, ToPoser and per-model base importers

  • poser.importing.foo has FromFooToPoser plus final importers

Poser → Foo export (aka. “Foo imports from Poser”)

  • poser.foo.importing.model has ToFooHandler, ToFoo and per-model base importer

  • poser.foo.importing.poser has FromPoserToFoo plus final importers