Функция Azure повреждена в модулях? Работает в одном приложении-функции (разработчике), не работает в другом (клиенте).Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Функция Azure повреждена в модулях? Работает в одном приложении-функции (разработчике), не работает в другом (клиенте).

Сообщение Anonymous »

Итак, у меня есть функциональное приложение Python v2 для CMS, которое работает со следующими пакетами (requirements.txt) -

Код: Выделить всё

azure-storage-blob
pytz
python-dotenv
azure-search-documents
azure-storage-file-share
aiohttp
requests
beautifulsoup4
С помощью function_app.py –

Код: Выделить всё

import logging
import azure.functions as func
from dotenv import load_dotenv
import requests
from data_process import delete_article_given_guid, index_all, process_contact_and_about, published_a_new_article
from share_function import sync_deleted_content, transfer_files
from azure.storage.fileshare import ShareClient
from azure.storage.blob import BlobServiceClient
import os

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

load_dotenv()

logging.basicConfig(level=logging.INFO)

@app.route(route="remove_article_by_id")
def remove_article_by_id(req: func.HttpRequest) -> func.HttpResponse:
logging.info(f"Remove article by ID function processed a request with with params: {req.params}")

guid = req.params.get("guid")
language = req.params.get("language")
api_method = req.params.get("api_method")
new_guid = f"{api_method}-{guid}"
if not guid or not language or not api_method:
return func.HttpResponse(
"Please pass a guid and a language in the query string.", status_code=400
)

# Call the function to delete the article by GUID
logging.info(f"Removing {api_method} article in {language}, with guid {new_guid}.")
status_code = delete_article_given_guid(new_guid,api_method, language)
if status_code != 200:
return func.HttpResponse(
f"Article with guid {guid} not found.", status_code=status_code
)
else:
return func.HttpResponse(f"Article with guid {guid} removed successfully.")

@app.route(route="publish_new_article")
def publish_new_article(req: func.HttpRequest) -> func.HttpResponse:
logging.info(
f"Publish new article function received a request with params: {req.params}"
)
published = req.params.get("published", "false").lower() in ["true", "1", "yes"]
api_method = req.params.get("api_method", "")
language = req.params.get("language", "")
id =req.params.get("id", "")
createdDate=req.params.get("createdDate", "")
name=req.params.get("name", "")

if published and api_method and language:
result = published_a_new_article(api_method=api_method, language=language, Article_id=id,createdDate=createdDate,name=name)

if result == "done":
logging.info("A new article published successfully.")
return func.HttpResponse("New articles have been published successfully.")
elif result == "noData":
return func.HttpResponse(
"No new articles found to publish.", status_code=406
)
else:
logging.error(result)
return func.HttpResponse(result, status_code=400)
else:
logging.error(
"Publish action failed. Invalid paramters. Please provide valid published, api_method, and language params."
)
return func.HttpResponse(
"Publish action failed. Invalid paramters.  Please provide valid published, api_method, and language params.",
status_code=400,
)

@app.route(route="index_all", auth_level=func.AuthLevel.ANONYMOUS)
def index_all_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info("Processing request to index all content.")
try:
index_all()
logging.info("Indexing completed successfully.")
return func.HttpResponse("Indexing completed successfully.")
except Exception as e:
logging.error(f"Failed to index all content: {str(e)}")
return func.HttpResponse(
f"Failed to index all content: {str(e)}", status_code=500
)

@app.function_name(name="index_contact_and_about")
@app.timer_trigger(schedule="0 0 0 * * *", arg_name="mytimer", run_on_startup=False)
def index_contact_and_about(mytimer: func.TimerRequest) -> None:
logging.info('Contact Us and About Us indexing function started')

for language in ['fr-FR', 'de-DE', 'es-ES', 'ar-QA', 'en']:
try:
result = process_contact_and_about(language)
if result == "error":
logging.error(f"Failed to index Contact Us and About Us for language: {language}")
else:
logging.info(f"Successfully indexed Contact Us and About Us for language: {language}, {result}")
except Exception as e:
logging.error(f"Exception occurred while indexing Contact Us and About Us for language {language}: {e}")
С хостом.json как -

Код: Выделить всё

{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
Итак, проблема в том, что он работает в моей разработке, но тот же код не работает в производственной среде клиента. На стороне клиента мы используем конвейер Azure Devops (который отлично строится, когда я развернул артефакт в своей среде разработки, он работает). С приведенными ниже журналами развертывания от Kudus -

Код: Выделить всё

{"timestamp": "2024-11-11T06:39:16.093Z", "level": "Message", "containerName": "", "machineName": "", "message": "Updating submodules."}
{"timestamp": "2024-11-11T06:39:16.275Z", "level": "Message", "containerName": "", "machineName": "", "message": "Preparing deployment for commit id '2f415e91-a'."}
{"timestamp": "2024-11-11T06:39:16.808Z", "level": "Message", "containerName": "", "machineName": "", "message": "PreDeployment: context.CleanOutputPath False"}
{"timestamp": "2024-11-11T06:39:16.975Z", "level": "Message", "containerName": "", "machineName": "", "message": "PreDeployment: context.OutputPath /home/site/wwwroot"}
{"timestamp": "2024-11-11T06:39:17.175Z", "level": "Message", "containerName": "", "machineName": "", "message": "Skipping build. Project type: Run-From-Zip"}
{"timestamp": "2024-11-11T06:39:17.335Z", "level": "Message", "containerName": "", "machineName": "", "message": "Skipping post build.  Project type: Run-From-Zip"}
{"timestamp": "2024-11-11T06:39:17.568Z", "level": "Message", "containerName": "", "machineName": "", "message": "Triggering recycle (preview mode disabled)."}
{"timestamp": "2024-11-11T06:39:17.984Z", "level": "Message", "containerName": "", "machineName": "", "message": "Updating /home/data/SitePackages/packagename.txt with deployment 20241111063909.zip"}
{"timestamp": "2024-11-11T06:39:18.228Z", "level": "Message", "containerName": "", "machineName": "", "message": "Deployment successful. deployer = VSTS_ZIP_DEPLOY_FUNCTIONS_V2 deploymentPath = Functions App ZipDeploy. Run from package."}
.env и конфигурации практически идентичны. После недельной попытки отладить его, используя все подходы из https://github.com/Azure/azure-function ... ssues/1262, все сводилось к этому конкретному журналу ошибок: функции задания не найдены. Попробуйте сделать свои классы и методы заданий общедоступными.
Это очень расплывчато. Итак, попробовал загрузить простой шаблон скрипта, чтобы убедиться, что модули работают правильно -

Код: Выделить всё

import logging
import azure.functions as func
import sys
import os
from importlib.metadata import distributions
import json
import traceback

logging.basicConfig(level=logging.INFO)

# Initialize FunctionApp first
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

# Global tracking variables
services_initialized = False
initialization_error = None

# Try importing all your required services
try:
# Import your potentially problematic modules here
from azure.storage.blob import BlobServiceClient
from azure.storage.fileshare import ShareClient
from azure.search.documents import SearchClient
from dotenv import load_dotenv
# from data_process import _index_all, delete_article_given_guid, published_a_new_article
# from share_function import sync_deleted_content, transfer_files
import asyncio
import ssl
import aiohttp
import time
import uuid
import datetime
import requests
import pytz
import bs4

# Initialize your services
load_dotenv()

services_initialized = True
logging.info("All services initialized successfully")
except Exception as e:
initialization_error = str(e)
logging.error(f"Initialization error: {str(e)}")
# Don't raise the error - let functions register

@app.route(route="health", methods=["GET"])
def health(req: func.HttpRequest) -> func.HttpResponse:
try:
health_info = {
"status": "available",
"initialization": {
"services_initialized": services_initialized,
"initialization_error": initialization_error,
},
"environment": {
"python_version": sys.version,
"current_directory": os.getcwd(),
"python_path": sys.path,
"environment_variables": {
"PYTHONPATH": os.getenv("PYTHONPATH", "not set"),
"AzureWebJobsScriptRoot": os.getenv("AzureWebJobsScriptRoot", "not set"),
# Add other relevant environment variables
"AZURE_FUNCTIONS_ENVIRONMENT": os.getenv("AZURE_FUNCTIONS_ENVIRONMENT", "not set"),
"FUNCTIONS_WORKER_RUNTIME": os.getenv("FUNCTIONS_WORKER_RUNTIME", "not set"),
"FUNCTIONS_EXTENSION_VERSION": os.getenv("FUNCTIONS_EXTENSION_VERSION", "not set"),

# Storage settings
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "present"  if os.getenv("WEBSITE_CONTENTAZUREFILECONNECTIONSTRING") else "not set",
"WEBSITE_CONTENTSHARE": os.getenv("WEBSITE_CONTENTSHARE", "not set"),

# Search service settings
"SEARCH_SERVICE_ENDPOINT": os.getenv("SEARCH_SERVICE_ENDPOINT", "not set"),
"SEARCH_INDEX_VERSION": os.getenv("SEARCH_INDEX_VERSION", "not set"),
"SEARCH_API_VERSION": os.getenv("SEARCH_API_VERSION", "not set"),

# Reports settings
"REPORTS_SEARCH_SERVICE_ENDPOINT": os.getenv("REPORTS_SEARCH_SERVICE_ENDPOINT", "not set"),
"REPORTS_SEARCH_INDEX_VERSION": os.getenv("REPORTS_SEARCH_INDEX_VERSION", "not set"),

# Container settings
"REPORTS_SOURCE_CONTAINER_NAME": os.getenv("REPORTS_SOURCE_CONTAINER_NAME", "not set"),
"REPORTS_TARGET_CONTAINER_NAME": os.getenv("REPORTS_TARGET_CONTAINER_NAME", "not set"),

# API settings
"UMBRACO_API_URL": os.getenv("UMBRACO_API_URL", "not set"),
"MAX_CONCURRENT_REQUESTS": os.getenv("MAX_CONCURRENT_REQUESTS", "not set")
},
},
"azure_services": {
"blob_storage": "available" if "BlobServiceClient" in globals() else "not imported",
"file_share": "available" if "ShareClient" in globals() else "not imported",
"search_client": "available" if "SearchClient" in globals() else "not imported",
"data_process": {
"_index_all": "available" if "_index_all" in globals() else "not imported",
"delete_article": "available" if "delete_article_given_guid" in globals() else "not imported",
"publish_article": "available" if "published_a_new_article" in globals() else "not imported"
},
"share_function": {
"sync_deleted_content": "available" if "sync_deleted_content" in globals() else "not imported",
"transfer_files": "available" if "transfer_files" in globals() else "not imported"
}
},
"dependencies": {
"installed_packages": [f"{dist.metadata['Name']}=={dist.version}" for dist in distributions()]
}
}

return func.HttpResponse(
json.dumps(health_info, indent=2),
mimetype="application/json"
)
except Exception as e:
error_info = {
"status": "error",
"error_type": type(e).__name__,
"error_message": str(e),
"error_traceback": traceback.format_exc(),
}
logging.error(f"Health check failed: {str(e)}")
return func.HttpResponse(
json.dumps(error_info, indent=2),
status_code=500,
mimetype="application/json"
)
Это тоже не удалось. Это заставляет меня думать, что это связано с поврежденными модулями. Есть идеи, как решить эту проблему, поскольку клиент отказывается создавать другой ресурс? Как удалить старые поврежденные модули.
ПРИМЕЧАНИЕ № 1. Код работает в двух моих функциях Azure для разработчиков.
ПРИМЕЧАНИЕ № 2. Это показывает успешное развертывание, но в обзоре нет функций, а также файлы не видны.

Подробнее здесь: https://stackoverflow.com/questions/791 ... not-on-the
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»