質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Windowsサービス

Windowsサービスは、Windows NTベースの管理システム上のService Control Managerによって走るバックグラウンドサービス処理で、daemonやUNIXサービスに類似しています。

Q&A

解決済

1回答

998閲覧

FlaskアプリをWindowsサービスで稼働させたい

Natsuki902

総合スコア13

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Windowsサービス

Windowsサービスは、Windows NTベースの管理システム上のService Control Managerによって走るバックグラウンドサービス処理で、daemonやUNIXサービスに類似しています。

0グッド

0クリップ

投稿2023/08/20 03:20

実現したいこと

現在Pythonの勉強を進めており、Flaskアプリケーションの作成を試しているところです。
個別にスクリプトファイルをダブルクリックして起動するアプリは作れたので、次の段階として
「Windowsサービスで起動できるようにしたい」と考えています。

  • Flaskアプリケーション(Python製)をWindowsサービスから起動できるようにする

前提

Windows10 21H2
Python 3.11
pipで各種Libをインポート

発生している問題・エラーメッセージ

エラーメッセージなどは特に出ていない(あるいは出せていない)
呼び出し先Flaskアプリケーションが起動できていればアクセスできるページへアクセスできない
(サーバが起動できていないときのような「接続拒否」のエラーとなる)

該当のソースコード

service.py

1import win32serviceutil 2import sys 3import servicemanager 4import subprocess 5 6class SampleService(win32serviceutil.ServiceFramework): 7 _svc_name_ = 'SampleService' 8 _svc_display_name_ = 'Sample Service' 9 _svc_description_ = 'This is Sample service.' 10 11 def SvcDoRun(self): 12 self.run = True 13 while self.run: 14 # Write datetime.now() every second 15 import time, datetime 16 time.sleep(1) 17 open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('%s\n' % datetime.datetime.now()) 18 proc = subprocess.Popen('C:\pleiades\2022-12\workspace\HelloService\flaskApp.py',shell=True,stdout=subprocess.PIPE) 19 open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('%s\n' % str(proc.stdout)) 20 open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('Processing>%s\n' % datetime.datetime.now()) 21 killcmd = 'taskkill /F /PID {pid} /T'.format(pid=proc.pid) 22 subprocess.run(killcmd,shell=True) 23 open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('Stop>%s\n' % datetime.datetime.now()) 24 25 def SvcStop(self): 26 self.run = False 27 28#if __name__ == '__main__': 29# win32serviceutil.HandleCommandLine(SampleService) 30if __name__ == '__main__': 31 if len(sys.argv) == 1: 32 servicemanager.Initialize() 33 servicemanager.PrepareToHostSingle(SampleService) 34 servicemanager.StartServiceCtrlDispatcher() 35 else: 36 win32serviceutil.HandleCommandLine(SampleService)

flaskApp.py

1from flask import Flask,request,session, abort, redirect 2from datetime import timedelta 3import configparser 4import logging 5from logging import StreamHandler, FileHandler, Formatter 6from logging import INFO, DEBUG, NOTSET 7import os 8from datetime import datetime 9from flask.templating import render_template 10import base64 11import json 12 13from waitress import serve 14 15#Flaskクラスをインスタンス化する 16app = Flask(__name__) 17 18 19#URLと実行する関数をマッピングする 20#ルートへのアクセス時 21@app.route("/" , methods=["GET"]) 22def index(): 23 24 return render_template("toppage.html") 25 26#起動時のみの処理(簡易サーバ起動) 27if __name__ == '__main__': 28 logger = logging.getLogger(__name__) 29 #簡易サーバ起動(デバッグ中はこちらを有効化) 30 app.run(port='8081', debug=True

試したこと

上記のservice.pyの18行目について、runとPopenを変えてみる、指定方法を相対パス・絶対パスに変えてみるなどを
試してみました。
また、Popenのstdoutの内容をログに出そうとしてみましたが、今の時点でうまくいっていません(こちらはもう少し試してみたいこともあります)。

基本的なところで知識などの抜けがある可能性もある気がしており、「こういうことを確かめてみたか」というご指摘でもありがたいです。
また、最終的にやりたいことが「Pythonで書いたFlaskアプリをWindowsサービスで起動し、ログインユーザがログアウトした状態でも稼働できるようにしたい」というものなので、そもそものアプローチが間違っている場合、アプローチのヒントをいただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

[香車]東上☆あらし☆海美「

https://teratail.com/questions/ewl7gn6q80ufox
FlaskアプリをWindowsサービスで稼働させたい(ja)

https://zenn.dev/mryu/articles/d3aecf05496c8b
Python Flask の環境構築(Windows)(ja)

https://qiita.com/speedstar18fct/items/28851476d741f1fe1a2f
PythonとFlaskをインストールする(Windows10) - Qiita(ja)

https://www.kkaneko.jp/pro/webui/flask.html
Flask のインストール, 動作確認(ja)

https://shigeblog221.com/python-flask1/">
[Python]Flaskのインストールと実行 | しげっちBlog(ja)

上記の Web 頁(複数)では、flaskApp.py に相当するものを、

python flaskApp.py

のように、直接、実行しているようですが。

投稿2023/08/20 05:59

umimi

総合スコア241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Natsuki902

2023/08/20 09:03

>umimiさま 基本的なところの問題でした。。失礼いたしました。 踏まえてWindowsのイベントログビューアの内容も踏まえて以下のように作ってみたらうまくいったので、 後に似たようなことをお考えの方のためにも残しておきます。。 (そんなこと言うまでもないでしょう、ということでも自分への戒めとして書き落とします。) Windowsサービスとして動かす場合に留意しておくべき事項 ・普段のログインユーザやカレントディレクトリとは異なる状態で動く。 ・故に「ソースファイルからの相対パスでの記載」だとうまくリソースを読み込めない。 ・pipで「ユーザフォルダ配下」にインストールされた外部ライブラリは読み込めない(?)   ※厳密な検証は出来ていませんが、flaskが見つからない旨のエラーがApplicationイベントにあったことからの推測です。 ↓ 解決方法 ・呼び出される側のflaskApp.pyはPyinstallerでexe化して別PCでも動ける状態にしておき、それを呼び出す。 ・各種パスは全て絶対パスで記載する。(予期せぬエラーを招くため「r'(パス文字列)'」として「\」が特別な意味を持たないようにする必要もある) また、以下に解決したときのソースコードを最小構成で残します。(flaskApp.pyはPyinstallerでビルドする前の状態です。ビルドした後、htmlなどの外部リソースをビルド先の場所にコピーした上でサービスの再インストール及び起動をしたら動きました。) ```service.py import win32serviceutil import sys import servicemanager import subprocess #from flaskApp import * import os class SampleService(win32serviceutil.ServiceFramework): _svc_name_ = 'SampleService' _svc_display_name_ = 'Sample Service' _svc_description_ = 'This is Sample service.' def SvcDoRun(self): self.run = True startFlg = False while self.run: import time, datetime time.sleep(1) if not startFlg: currentdir = r'C:\pleiades\2022-12\workspace\HelloService\dist\flaskApp' cmd = currentdir + '\\flaskApp.exe' proc = subprocess.Popen(cmd,stdout=subprocess.PIPE) startFlg = True else: open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('flaskApp:started...\n') killcmd = 'taskkill /F /PID {pid} /T'.format(pid=proc.pid) subprocess.run(killcmd,shell=True) def SvcStop(self): self.run = False #if __name__ == '__main__': # win32serviceutil.HandleCommandLine(SampleService) if __name__ == '__main__': if len(sys.argv) == 1: servicemanager.Initialize() servicemanager.PrepareToHostSingle(SampleService) servicemanager.StartServiceCtrlDispatcher() else: win32serviceutil.HandleCommandLine(SampleService) ``` ```flaskApp.py from flask import Flask,request,session, abort, redirect from datetime import timedelta import configparser import logging from logging import StreamHandler, FileHandler, Formatter from logging import INFO, DEBUG, NOTSET import os from datetime import datetime from flask.templating import render_template import base64 import json from waitress import serve #Flaskクラスをインスタンス化する app = Flask(__name__) #URLと実行する関数をマッピングする #ルートへのアクセス時 @app.route("/" , methods=["GET"]) def index(): open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('flaskApp:index start\n') return render_template("toppage.html") #起動時のみの処理(簡易サーバ起動) if __name__ == '__main__': logger = logging.getLogger(__name__) open(r'C:\pleiades\2022-12\workspace\HelloService\logs\test.txt', 'a').write('flaskApp:start\n') #2022/10/08 mod end プロキシ設定強化 #簡易サーバ起動(デバッグ中はこちらを有効化) #app.run(port='8081', debug=True) #waitressサーバ起動(本番ビルド時はこちらを有効化)※但し、アクセスログ的なものも出なくなるため、ロガーをあちこちに仕込むこと(ToDo) serve(app,port='8081') ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問