Импорт ресурсов json внутри .pex (исполняемый файл Python (формат Twitter))

Я использую разработанный Twitter инструмент сборки pants для управления многими проектами в моем монорепозитории. Он выводит файлы .pex, когда я завершаю сборку, это двоичный файл, который упаковывает минимальные зависимости. Мне нужно для каждого проекта и делает их двоичными (на самом деле архив, который распаковывается во время выполнения), моя проблема заключается в том, что утилита, которую мой код использовал в течение длительного времени, не может обнаружить некоторые файлы .json (теперь, когда я использую штаны) Я сохранил в своей библиотеке сред. весь мой другой код работает нормально. Я почти уверен, что это связано с моей конфигурацией, возможно, я неправильно храню ресурсы, чтобы мой код мог их найти, хотя, когда я использую unzip my_app.pex, нужные мне ресурсы находятся в пакете и находятся в нужном месте (каталог ). Вот метод, который моя утилита использует для загрузки ресурсов json:

if test_env:
    file_name = "test_env.json"
elif os.environ["ENVIRONMENT_TYPE"] == "PROD":
    file_name = "prod_env.json"
else:
    file_name = "dev_env.json"
try:
    json_file = importlib.resources.read_text("my_apps.environments", file_name)
except FileNotFoundError:
    logger.error(f"my_apps.environments->{file_name} was not found")
    exit()
config = json.loads(json_file)

вот файл BUILD, который я сейчас использую для этих ресурсов:

python_library(
   dependencies=[
       ":dev_env",
       ":prod_env",
       ":test_env"
   ]
 )

resources(
   name="dev_env",
   sources=["dev_env.json"]
)

resources(
   name="prod_env",
   sources=["prod_env.json"]
)

resources(
   name="test_env",
   sources=["test_env.json"]
)

а вот файл BUILD для утилиты, которая вызывает эти ресурсы, код Python выше — это то, что вы видели:

python_library(
   name="environment_handler",
   sources=["environment_handler.py"],
   dependencies=[
       "my_apps/environments:dev_env",
       "my_apps/environments:prod_env",
       "my_apps/environments:test_env"
   ]
)

Я всегда получаю исключение FileNotFoundError, и я сбит с толку, потому что файлы доступны для среды выполнения, что делает эти файлы недоступными? и есть ли другой формат, в котором мне нужно настроить ресурсы JSON?

Также для контекста здесь находится распакованный файл .pex (на самом деле просто каталог исходного кода):

    ├── apps
│   ├── __init__.py
│   └── services
│       ├── charts
│       │   ├── crud
│       │   │   ├── __init__.py
│       │   │   └── patch.py
│       │   ├── __init__.py
│       │   └── main.py
│       └── __init__.py
├── environments
│   ├── dev_env.json
│   ├── prod_env.json
│   └── test_env.json
├── __init__.py
├── models
│   ├── charts
│   │   ├── base.py
│   │   └── __init__.py
│   └── __init__.py
└── utils
    ├── api_queries
    │   ├── common
    │   │   ├── connections.py
    │   │   └── __init__.py
    │   └── __init__.py
    ├── calculations
    │   ├── common
    │   │   ├── __init__.py
    │   │   └── merged_user_management.py
    │   └── __init__.py
    ├── environment_handler.py
    ├── __init__.py
    ├── json_response_toolset.py
    └── security_toolset.py

person Gideon Felt    schedule 04.01.2021    source источник


Ответы (1)


Я разобрался: я изменил способ доступа к файлам в библиотеке, и он отлично работает до и после сборки в формате .pex. Я использовал:

import pkgutil
#json_file = importlib.resources.read_text("my_apps.environments", file_name)
json_file = pkgutil.get_data("my_apps.environments", file_name).decode("utf-8")
person Gideon Felt    schedule 04.01.2021
comment
Я всегда рекомендую этот ответ: stackoverflow.com/a/58941536 - person sinoroc; 04.01.2021