簡體   English   中英

使用 request.post() 從 PHP controller 調用 python 腳本永遠不會返回。 為什么?

[英]Calling python script with request.post() from PHP controller never returns. Why?

我正在嘗試從 Laravel 8 應用程序執行 python 腳本。 python 腳本使用 Laravel 應用程序的 REST API,因此它必須進行身份驗證。

如果 python 腳本在命令行運行(開發平台是 Windows 10),它自己運行得很好,但如果通過 shell_exec() 或 exec() 或 symfony/process() 運行,它會關閉 Laravel 應用程序到我需要在不同的端口上重新啟動應用程序,或者在控制台 laravel 日志中沒有錯誤的情況下重新啟動。

如果我從 python 腳本中取出 'requests.post()' 並將其替換為 print("Hello World") 它與 shell_exec() 一起工作正常

問題:有人看到可能發生的事情嗎? 這似乎是一個權限問題,但我不確定。

腳注:我嘗試了 Symfony,但收到許多其他人報告的錯誤“無法獲取隨機數以初始化 Python 運行時”這似乎是 windows 開發箱上的常見問題。 想通了這個問題,但結果是一樣的。 對於以后看到此 python 初始化錯誤的任何人:在 windows 構建環境中,您需要添加環境變量 SystemRoot,如下所示: $process = new Process([$python, $process_path, $argument1, $argument2], null, ['SystemRoot' => 'C:\WINDOWS']);

Controller

    public function startprocess(Request $request)
    {

        $python = "C:/Users/dev/AppData/Local/Programs/Python/Python38/python.exe";
        $process_path = "C:/Apache24/htdocs/project/resources/python/lambda/test.py";
        $complete_path = $python." ".$process_path;
        $output = [];
        $return_var = "";

//        exec($complete_path, $output, $return_var);
        $process = new Process([$python, $process_path], null, ['SystemRoot' => 'C:\WINDOWS']);
        $process->run();

        return view('admin.scheduledtasks_data', compact('output', 'return_var', 'complete_path'))->render();
    }

Python 代碼

import sys
import requests
from requests.exceptions import HTTPError
import re

url_login = 'http://127.0.0.1:8089/api/apilogin'

data = {
    'email': 'myemail@email.com',
    'password': 'password'}

returned_data = requests.post(url_login, data=data)  #<<THIS TAKES DOWN THE SERVER

這是 API 解決的問題

   public function APIlogin(Request $request)
    {

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response([
                'message' => ['Please submit a valid email address and password combination.']
            ], 404);
        }

        $token = $user->createToken('user-token')->plainTextToken;

        $response = [
            'user' => $user,
            'token' => $token
        ];

        return response($response, 201);
    }

這是從命令行發出的一個好的請求的樣子

send: b'POST /api/apilogin HTTP/1.1 
Host: 127.0.0.1:8098 
User-Agent: python-requests/2.23.0 
Accept-Encoding: gzip, deflate 
Accept: */* 
Connection: keep-alive 
Content-Length: 48 
Content-Type: application/x-www-form-urlencoded'
send: b'email= (deleted) &password= (deleted)'
reply: 'HTTP/1.1 201 Created'
header: Host: 127.0.0.1:8098
header: Date: Fri, 13 Nov 2020 19:07:10 GMT
header: Connection: close
header: X-Powered-By: PHP/7.4.2
header: Cache-Control: no-cache, private
header: Date: Fri, 13 Nov 2020 19:07:10 GMT
header: Content-Type: application/json
header: X-RateLimit-Limit: 60
header: X-RateLimit-Remaining: 59

這是當我使用 requests.post(url_login, data=data, timeout=3) 從 laravel 應用程序調用它並添加“超時”但登錄從未發生時的響應。 沒有超時,請求永遠不會返回並且服務器停機

HTTP/1.1 200 OK
Host: 127.0.0.1:8102
Date: Fri, 13 Nov 2020 23:05:38 GMT
Connection: close
X-Powered-By: PHP/7.4.2
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, private
Date: Fri, 13 Nov 2020 23:05:38 GMT
Set-Cookie: XSRF-TOKEN= (deleted); 
    expires=Sat, 14-Nov-2020 01:05:38 GMT; 
    Max-Age=7200; 
    path=/
Set-Cookie: icollect_session=(deleted); 
    expires=Sat, 14-Nov-2020 01:05:38 GMT; 
    Max-Age=7200; 
    path=/; 
    httponly
<td>
<textarea class="form-control" id="FormControlTextarea" rows="10" cols="300">
send: b&#039;POST /api/apilogin HTTP/1.1\r\n
Host: 127.0.0.1:8102\r\n
User-Agent: python-requests/2.23.0\r\n
Accept-Encoding: gzip, deflate\r\n
Accept: */*\r\n
Connection: keep-alive\r\n
Content-Length: 48\r\n
Content-Type: application/x-www-form-urlencoded\r\n\r\n&#039;
send: b&#039;email=(deleted)&amp;password=(deleted);
</textarea>
</td>

更新:帖子永遠不會點擊 api.php 所以問題一定與 python 腳本有關,無法回發到它被調用的應用程序......但為什么呢?

更新:我正在使用 JS ajax 調用生成 python 腳本的 PHP controller。 如果我使用PHP symfony process()在controller中調用process()來撥打python腳本包含ajax的8827654043488腳本。和作品。 現在只是為了了解為什么以及如何重新設計這個......

{message: "Maximum execution time of 60 seconds exceeded",…}
exception: "Symfony\Component\ErrorHandler\Error\FatalError"
file: "C:\Apache24\htdocs\laravel\vendor\symfony\process\Pipes\WindowsPipes.php"
line: 145
message: "Maximum execution time of 60 seconds exceeded"
trace: []

擺脫了 Symfony process() 並更改為此。 發生的事情是 laravel 應用程序阻止 request.post 完成,因此服務器鎖定...

在這里找到——謝謝@LucaM

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM