run-python-docker-demo.ps1 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. param(
  2. [string]$SampleDir,
  3. [string]$OutDir,
  4. [string]$BaseUrl = "http://127.0.0.1:18000",
  5. [int]$TimeoutSeconds = 300,
  6. [int]$MaxRetries = 3,
  7. [switch]$IncludeImages
  8. )
  9. $ErrorActionPreference = "Stop"
  10. $OutputEncoding = [System.Text.Encoding]::UTF8
  11. [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
  12. [Console]::InputEncoding = [System.Text.Encoding]::UTF8
  13. $TestFilesName = "$([char]0x6D4B)$([char]0x8BD5)$([char]0x6587)$([char]0x4EF6)"
  14. $CompareName = "$([char]0x5BF9)$([char]0x6BD4)$([char]0x7ED3)$([char]0x679C)"
  15. if ([string]::IsNullOrWhiteSpace($SampleDir)) { $SampleDir = Join-Path $PSScriptRoot $TestFilesName }
  16. if ([string]::IsNullOrWhiteSpace($OutDir)) { $OutDir = Join-Path $PSScriptRoot (Join-Path $CompareName "python-docker") }
  17. function Write-Log {
  18. param([string]$Message)
  19. Write-Host ("[{0:yyyy-MM-dd HH:mm:ss}] {1}" -f (Get-Date), $Message)
  20. }
  21. function Invoke-ConvertWithRetry {
  22. param(
  23. [System.IO.FileInfo]$File,
  24. [string]$OutputFile,
  25. [string]$ErrorFile
  26. )
  27. $tempFile = "$OutputFile.tmp"
  28. if (Test-Path $tempFile) { Remove-Item $tempFile -Force }
  29. if (Test-Path $OutputFile) { Remove-Item $OutputFile -Force }
  30. if (Test-Path $ErrorFile) { Remove-Item $ErrorFile -Force }
  31. for ($attempt = 1; $attempt -le $MaxRetries; $attempt++) {
  32. Write-Log ("{0}: attempt {1}/{2}, timeout={3}s" -f $File.Name, $attempt, $MaxRetries, $TimeoutSeconds)
  33. $includeImagesValue = $IncludeImages.IsPresent.ToString().ToLower()
  34. $curlArgs = @(
  35. "-sS",
  36. "--max-time", "$TimeoutSeconds",
  37. "-X", "POST",
  38. "$BaseUrl/convert",
  39. "-F", "file=@$($File.FullName)",
  40. "-F", "include_images=$includeImagesValue",
  41. "-o", "$tempFile",
  42. "-w", "%{http_code}"
  43. )
  44. $httpCode = & curl.exe @curlArgs 2>&1
  45. $curlExit = $LASTEXITCODE
  46. $httpCodeText = ($httpCode | Select-Object -Last 1).ToString().Trim()
  47. Write-Log ("{0}: curl_exit={1}, http={2}" -f $File.Name, $curlExit, $httpCodeText)
  48. if ($curlExit -eq 0 -and $httpCodeText -eq "200" -and (Test-Path $tempFile)) {
  49. Move-Item $tempFile $OutputFile -Force
  50. return @{ Status = "OK"; Message = ""; Bytes = (Get-Item $OutputFile).Length; Output = [System.IO.Path]::GetFileName($OutputFile) }
  51. }
  52. $errorBody = ""
  53. if (Test-Path $tempFile) { $errorBody = Get-Content $tempFile -Raw -Encoding UTF8 }
  54. $message = "attempt=$attempt curl_exit=$curlExit http=$httpCodeText body=$errorBody"
  55. $message | Out-File -FilePath $ErrorFile -Encoding UTF8
  56. if ($attempt -lt $MaxRetries) {
  57. $sleepSeconds = 5 * $attempt
  58. Write-Log ("{0}: sleep {1}s before retry" -f $File.Name, $sleepSeconds)
  59. Start-Sleep -Seconds $sleepSeconds
  60. }
  61. }
  62. if (Test-Path $tempFile) { Remove-Item $tempFile -Force }
  63. return @{ Status = "FAIL"; Message = (Get-Content $ErrorFile -Raw -Encoding UTF8); Bytes = (Get-Item $ErrorFile).Length; Output = [System.IO.Path]::GetFileName($ErrorFile) }
  64. }
  65. function Write-Summary {
  66. param([array]$Rows)
  67. $Rows | ConvertTo-Json -Depth 4 | Out-File -FilePath (Join-Path $OutDir "summary.json") -Encoding UTF8
  68. $lines = @("# Python Docker Result", "", "| File | Status | Output | Bytes | Message |", "| --- | --- | --- | ---: | --- |")
  69. foreach ($row in $Rows) {
  70. $message = ($row.Message -replace "\|", "\\|" -replace "`r?`n", " ")
  71. $lines += "| $($row.File) | $($row.Status) | $($row.Output) | $($row.Bytes) | $message |"
  72. }
  73. $lines | Out-File -FilePath (Join-Path $OutDir "summary.md") -Encoding UTF8
  74. }
  75. if (Test-Path $OutDir) { Remove-Item $OutDir -Recurse -Force }
  76. New-Item -ItemType Directory -Force $OutDir | Out-Null
  77. $LogFile = Join-Path $OutDir "run.log"
  78. Start-Transcript -Path $LogFile | Out-Null
  79. try {
  80. Write-Log "Python Docker demo started"
  81. Write-Log "SampleDir=$SampleDir"
  82. Write-Log "OutDir=$OutDir"
  83. Write-Log "BaseUrl=$BaseUrl"
  84. Write-Log "TimeoutSeconds=$TimeoutSeconds"
  85. Write-Log "MaxRetries=$MaxRetries"
  86. Write-Log "IncludeImages=$($IncludeImages.IsPresent)"
  87. if (!(Test-Path $SampleDir)) { throw "SampleDir not found: $SampleDir" }
  88. Write-Log "Warmup /openapi.json"
  89. for ($i = 1; $i -le $MaxRetries; $i++) {
  90. $warmup = & curl.exe -sS --max-time 30 -o NUL -w "%{http_code}" "$BaseUrl/openapi.json" 2>&1
  91. $warmupExit = $LASTEXITCODE
  92. Write-Log ("warmup {0}/{1}: curl_exit={2}, http={3}" -f $i, $MaxRetries, $warmupExit, $warmup)
  93. if ($warmupExit -eq 0 -and "$warmup" -eq "200") { break }
  94. Start-Sleep -Seconds (5 * $i)
  95. }
  96. $rows = @()
  97. $files = Get-ChildItem -Path $SampleDir -File | Sort-Object Name
  98. foreach ($file in $files) {
  99. $stem = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
  100. $outputFile = Join-Path $OutDir "$stem.md"
  101. $errorFile = Join-Path $OutDir "$stem.error.txt"
  102. $result = Invoke-ConvertWithRetry -File $file -OutputFile $outputFile -ErrorFile $errorFile
  103. $rows += [pscustomobject]@{ File = $file.Name; Status = $result.Status; Output = $result.Output; Bytes = $result.Bytes; Message = $result.Message }
  104. Write-Log ("{0} {1} -> {2}" -f $result.Status, $file.Name, $result.Output)
  105. }
  106. Write-Summary -Rows $rows
  107. Write-Log "Python Docker demo finished"
  108. } catch {
  109. Write-Log ("Failed: {0}" -f $_.Exception.Message)
  110. throw
  111. } finally {
  112. Stop-Transcript | Out-Null
  113. }