Managing user defined types across files

Viewed 53

Is there a general rule of thumb to follow with creating custom types to use across different files?

I'm currently trying to use my custom types across different modules. I would much rather have a single source of truth for custom types that need to be re-used.

Use case

I'm integrating with multiple webservices from the same provider for our item management system.

The catch here is that some of the webservices use shared properties like a (store number, service area, action code etc.). I've made custom types to restrict entries of invalid property values. ie:

ActionCodes = typing.Union[
   typing.Literal["Add", "Update", "Delete"]
]

Which would be used like this in a pydantic model

class ItemInfo(pydantic.BaseModel):
    ActionCode: ActionCodes = "Update"
    OrgUnitNum: int = 0
    ItemNum: int
    PluNum: int
    PluDescription: str
    ServiceAreaNum: ServiceAreaNumber

Edits

"I keep ending up in this senario where I want to use a type but that type is already imported to a previous file (causing a circular import)."

As I've seen asked yes I have to import modules into my types.py file. Specifically from my models/ directory.

An example would be in need types.py in entity_models.py but also need types.py in entity_models.py and other files like update_prices.py.

types.py

# models
import models.models as models
import models.entity_models as entity_models

# typing
import typing


# freshiq list definitions
FreshIQPriceList = typing.List[entity_models.FreshIQPrices]
FreshIQPluList = typing.List[entity_models.FreshIQScalePlus]
FreshIQItemList = typing.List[entity_models.FreshIQItem]

# freshiq dict definitions
FreshIQPluDict = typing.Dict[str, entity_models.FreshIQScalePlus]

update_prices.py

# config
from config.databases import SALES
from config import mail as mail_config
from config import freshiq

# classes
from classes.do_entity_search import DoEntitySearch

# utility functions
from utils.job_runner import job_runner
from utils import mail
from utils import types as T

# models
from models import entity_models
from models import models

# python modyules
from datetime import date, timedelta
import logging

entity_models.py

# config
from config import freshiq
from config import env

# types
from utils import types as T

# pydantic
from pydantic import BaseModel, validator

# python modules
from datetime import datetime
from typing import Dict, List, Optional, Union, Literal, Any

Working directory

 - classes/
   - do_entity_search.py (uses types)
   - webservice.py (uses types)
   - item_webservice.py (uses types)
 - config/
   - databases.py
   - env.py
   - webservice_config.py (uses types)
 - models/
   - entity_models.py (uses types)
   - item_models.py (uses types)
 - utils/
   - types.py (custom types)
 - update_prices.py (runnable script)
 - import_items.py (runnable script)

Error Message

Traceback (most recent call last):
  File "C:\Users\janrico\Documents\GitHub\FreshIQ\jobs\update_prices.py", line 7, in <module>
    from classes.do_entity_search import DoEntitySearch
  File "C:\Users\janrico\Documents\GitHub\FreshIQ\jobs\classes\do_entity_search.py", line 6, in <module>
    from utils.functools import update_item, insert_item, create_itemcode_map
  File "C:\Users\janrico\Documents\GitHub\FreshIQ\jobs\utils\functools.py", line 7, in <module>
    from models import entity_models
  File "C:\Users\janrico\Documents\GitHub\FreshIQ\jobs\models\entity_models.py", line 6, in <module>
    from utils import types as T
  File "C:\Users\janrico\Documents\GitHub\FreshIQ\jobs\utils\types.py", line 10, in <module>
    FreshIQPriceList = typing.List[entity_models.FreshIQPrices]
AttributeError: partially initialized module 'models.entity_models' has no attribute 'FreshIQPrices' (most likely due to a circular import)

My Solution (although not preferred)

I ended up moving relevant types that used enity_models into the entity_models.py file. This seems to work as expected but it defeats the purpose of having a single source of truth for types.

0 Answers
Related