--- title: "アプリケーションのコーディング" url: https://docs.catalyst.zoho.com/ja/tutorials/alien-city-appsail/python/code-app/ description: "Catalyst AppSailサービスとCatalyst Data Storeを使用して、都市でのエイリアン遭遇を報告・検索できるアプリケーションを作成し、Catalystでホストします。" last_updated: 2026-08-17T12:16:04Z service: All Services type: tutorial related_links: - name: "AppSail用Catalyst SDK" url: /ja/cli/v1/initialize-resources/introduction/ --- # アプリケーションのコーディング アプリケーションのコーディングを始めましょう。 以下のファイルとディレクトリを作成してコードを格納します: * プロジェクトのルートディレクトリ(`AlienCity/`)にPythonコードファイルを作成し、「**app.py**」と名付けます。このファイルにはアプリケーションのバックエンドロジックが含まれます。 * プロジェクトのルートディレクトリにフォルダを作成し、「**static**」と名付け、その中に以下のファイルを作成します(`AlienCity/static/`): - **index.html**:アプリケーションのフロントエンドのHTMLコードを含みます - **main.js**:アプリケーションのJavaScriptコードを含みます 以下は、*AlienCity*プロジェクトの最終的なフォルダ構造です: ![catalyst_alien_city_cli_appsail_py_complete_dir](https://catalyst-docs-development.zohostratus.in/images/tutorials/alien-city-appsail-express/catalyst_alien_city_cli_appsail_py_complete_dir.webp) `app.py`、`index.html`、および`main.js`ファイルをコーディングします。また、`app-config.json`ファイルも更新します。 > **Note:** このセクションのコードを確認し、内容を十分に理解してください。 以下のコードをコピーし、IDEを使用してプロジェクトの対応するファイルに貼り付けて保存してください。 **app.py** ```python import sys sys.path.insert(0, './lib') from flask import Flask, request, jsonify import os import zcatalyst_sdk import logging tableName = 'AlienCity' # Data Storeに作成したテーブル columnName = 'CityName' app = Flask(__name__) @app.route('/') def index(): return app.send_static_file('index.html') @app.route('/alien', methods=['POST']) def post_alien_encounter(): try: logger = logging.getLogger() capp = zcatalyst_sdk.initialize(req=request) req_data = request.get_json() name = req_data.get('city_name') rowid = getAlienCountFromCatalystDataStore(request,name) # Catalyst Data Storeテーブルにクエリを実行し、指定された都市の行が存在するか確認する if len(rowid) == 0: # 行が存在しない場合、新しい行を挿入する logger.info("Alien alert!") # ログに書き込まれます。このログはコンソールのMonitorセクションにあるLogsから確認できます datastore_service = capp.datastore() table_service = datastore_service.table(tableName) row_data = { columnName:name } table_service.insert_row(row_data) # Catalyst Data Storeテーブルに都市名を行として挿入する return jsonify({ "message":"Thanks for reporting!!!" }),200 else: return jsonify({ "message": "Looks like you are not the first person to encounter aliens in this city! Someone has already reported an alien encounter here!" }), 200 except Exception as e: # 行が存在する場合、重複を示すメッセージを送信する print(e) return jsonify({ "message": "Internal server error" }), 500 @app.route('/alien', methods=['GET']) def get_alien_encounter(): try: name = request.args.get('city_name') rowid = getAlienCountFromCatalystDataStore(request,name) # Catalyst Data Storeテーブルにクエリを実行し、指定された都市の行が存在するか確認する if len(rowid) == 0: return jsonify({ "message": "Hurray! No alien encounters in this city yet!", "signal": "negative" }), 200 else: return jsonify({ "message": "Uh oh! Looks like there are aliens in this city!", "signal": "positive" }), 200 except Exception as e: print(e) return jsonify({ "message": "Internal server error" }), 500 def getAlienCountFromCatalystDataStore(request,cityname): # Data Storeテーブルにクエリを実行し、指定された都市のエイリアン遭遇が既に報告されているか確認する capp = zcatalyst_sdk.initialize(req=request) zcql_service = capp.zcql() query = f"SELECT * FROM {tableName} WHERE {columnName} = '{cityname}'" output = zcql_service.execute_query(query) return output if __name__ == '__main__': port = int(os.environ.get('X_ZOHO_CATALYST_LISTEN_PORT', 9000)) app.run(host='0.0.0.0', port=port) ``` **index.html** ```xml <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AlientCityAppClient</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="static/main.js"> </script> </head> <body> <br> <br> <center> <h1>ALIEN CITY</h1> </center> <div class="container"> <ul class="nav nav-tabs" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true">Check My City</a> </li> <li class="nav-item"> <a class="nav-link" id="report-tab" data-toggle="tab" href="#report" role="tab" aria-controls="report" aria-selected="false">Report Alien Encounter</a> </li> </ul> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"> <br> <br> <form> <div class="form-group"> <label for="city-get-input"> <b>Check if your city has aliens:</b> </label> <input type="text" class="form-control" id="city-get-input" aria-describedby="checkCity" placeholder="Enter City Name"> </div> <button type="submit" class="btn btn-primary" onclick="getAlienEncounter();return false;">Check</button> </form> <br> <br> <div id="result-container"> <div id="result-text"> </div> <br> <div id="result-image"> </div> </div> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </div> <div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"> <br> <br> <form> <div class="form-group"> <div class="city-post-input"> <label for="exampleInputEmail1"> <b>Enter the name of the city where you encountered an alien:</b> </label> <input type="text" class="form-control" id="city-post-input" aria-describedby="cityPost" placeholder="Enter City Name"> </div> </div> <button type="submit" class="btn btn-primary" onclick="postAlienEncounter();return false;">Report</button> </form> </div> </div> </div> </body> </html> ``` **main.js** ```javascript function postAlienEncounter() { debugger; var city = $("#city-post-input").val(); $.ajax({ url: "/alien", type: "post", contentType: "application/json", data: JSON.stringify({ "city_name": city }), success: function (data) { alert(data.message); }, error: function (error) { alert(error.message); } }); } function getAlienEncounter() { debugger showLoader(); var positive = "https://media.giphy.com/media/Y1GYiLui9NHcxVKhdo/giphy.gif"; var negative = "https://media.giphy.com/media/fsPcMdeXPxSP6zKxCA/giphy.gif"; var city = $("#city-get-input").val(); $.ajax({ url: "/alien?city_name=" + city, type: "get", success: function (data) { console.log(data); $("#result-text").text(""); $("#result-text").text(data.message); var imagesrc = negative; if (data.signal == 'positive') { imagesrc = positive; } $("#result-image").html(""); $("#result-image").html("<img src='" + imagesrc + "' />"); hideLoader(); }, error: function (error) { alert(error.message); } }); } function showLoader() { $("#result-container").hide(); $("#loader").show(); } function hideLoader() { $("#loader").hide(); $("#result-container").show(); } ``` `app-config.json`ファイルのキー`command`の値を「**python3 app.py**」に更新します。これは、このプログラミングスタックとフレームワーク固有の[起動コマンド](https://docs.catalyst.zoho.com/ja/serverless/help/appsail/key-concepts/appsail-execution/#startup-commands)です。 **app-config.json** ```json { "command": "python3 app.py", "buildPath": "/Users/amelia-426/Catalyst/Alien City", // ビルドパスを指定してください "stack": "python_3_9", "env_variables": {}, "memory": 256, "scripts": {} } ``` アプリケーションの動作を簡単に確認しましょう: 1. **GETオペレーション** * アプリケーションで都市名を入力して過去のエイリアン遭遇の記録を確認すると、`index.html`の**Check**ボタンのonClickイベントが`main.js`で定義された`getAlienEncounter()`関数をトリガーします。 * これにより、関数で定義されたURLルートにAjaxコールが発行されます。`app.py`で定義された`GET` APIが`getAlienCountFromCatalystDataStore()`関数を呼び出し、リクエストクエリを渡します。 * この関数は、ZCQLクエリを実行してData Storeの*AlienCity*テーブル内のデータを検索します。 * テーブルで都市名に一致する記録が見つかった場合、レスポンスとして*positive*シグナルが送信されます。見つからない場合は、*negative*シグナルが送信されます。 * アプリケーションはレスポンスに対応するメッセージを表示します。`main.js`で定義されたレスポンスに対応するGIFも表示されます。 2. **POSTオペレーション** * アプリケーションで都市名を入力してエイリアン遭遇を報告すると、`index.html`の**Report**ボタンのonClickイベントが`main.js`で定義された`postAlienEncounter()`関数をトリガーします。 * これにより、関数で定義されたURLルートにAjaxコールが発行されます。`app.py`で定義された`POST` APIが`getAlienCountFromCatalystDataStore()`関数を呼び出し、同じ都市名の記録が既に存在するかどうかを確認するリクエストクエリを渡します。 * この関数は、ZCQLクエリを実行してData Storeの*AlienCity*テーブル内のデータを検索します。記録が既に存在する場合、レスポンスが送信され、クライアントはユーザーに適切なメッセージを表示します。 * 都市名の記録がない場合、ユーザーが入力した都市名で*AlienCity*テーブルに新しい行が作成されます。クライアントにポップアップボックスが表示され、Data Storeへの記録の挿入が確認されます。適切なメッセージもログにプッシュされ、コンソールの*DevOps*サービスセクションの*Monitor*セクション内にある[Catalyst DevOps](https://docs.catalyst.zoho.com/ja/devops/getting-started/introduction/)コンポーネントの[Logs](https://docs.catalyst.zoho.com/ja/devops/help/logs/introduction/)から確認できます。