序章

多くの開発者には、アプリケーションのインフラストラクチャをセットアップおよび管理するための時間や経験がありません。 期限に遅れずにコストを削減するには、開発者は、コードの記述と顧客への新機能の提供に集中するために、アプリをできるだけ迅速かつ効率的にクラウドにデプロイできるソリューションを見つける必要があります。 DigitalOceanのAppPlatformFaunaが一緒になってその機能を提供します。

DigitalOcean App Platformは、アプリを実行するインフラストラクチャを抽象化するPlatform-as-a-Service(PaaS)です。 また、コードをGitブランチにプッシュすることでアプリケーションをデプロイすることもできます。

動物相は、あらゆるサイズのアプリケーション向けの強力なデータレイヤーです。 このチュートリアルでわかるように、Faunaを使用すると、データベースの操作を気にすることなく、データベースをすばやく起動して実行できます。

これら2つのソリューションを組み合わせることで、インフラストラクチャを管理するのではなく、アプリケーションに集中できます。

このチュートリアルでは、 Flaskフレームワークを使用して最小限のRESTAPIを記述し、FaunaをPythonと統合します。 次に、GitリポジトリからDigitalOceanのAppPlatformにAPIをデプロイします。APIは次のもので構成されます。

  • パブリック /signup でユーザーを作成するためのPOSTエンドポイント Users コレクション。
  • パブリック /login 内のドキュメントで認証するためのPOSTエンドポイント Users コレクション。
  • プライベート /things 動物相ドキュメントのリストをからフェッチするためのGETエンドポイント Things コレクション。

完成したPythonプロジェクトは、このGithubリポジトリで入手できます。

前提条件

このチュートリアルを開始する前に、次のものが必要です。

ステップ1—動物相データベースの設定

最初のステップでは、動物相データベースを構成し、APIのコレクションを作成します。 動物相は、従来のテーブルベースのリレーショナルデータベースではなく、ドキュメントベースのデータベースです。 動物相は、ドキュメントのグループであるドキュメントとコレクションにデータを保存します。

コレクションを作成するには、Faunaのネイティブクエリ言語であるFQLを使用してクエリを実行します。 FQLは、表現力豊かで強力なクエリ言語であり、Faunaの全機能にアクセスできます。

開始するには、動物相のダッシュボードにログインします。 ログイン後、上部のデータベース作成ボタンをクリックしてください。

新しいデータベースフォームで、 PYTHON_API データベース名の場合:

デモデータの事前入力のチェックを外したままにします。 保存ボタンを押します。

データベースを作成すると、データベースのホームセクションが表示されます。

次に、2つのコレクションを作成します。

  • The Users 認証情報を含むドキュメントを保存するコレクション。
  • The Things APIをテストするための模擬データを保存するためのコレクション。

これらのコレクションを作成するには、ダッシュボードのシェルでいくつかのFQLクエリを実行します。 左側のメインダッシュボードメニューからシェルにアクセスします。

シェルの下部パネルに次のFQLクエリを記述して、というコレクションを作成します。 Things CreateCollection 関数を使用して:

CreateCollection({name: "Things"})

RUNQUERYボタンを押します。 シェルのトップパネルに次のような結果が表示されます。

{
  ref: Collection("Things"),
  ts: 1614805457170000,
  history_days: 30,
  name: "Things"
}

結果は4つのフィールドを示しています。

  • ref コレクション自体への参照です。
  • ts 作成のタイムスタンプ(マイクロ秒単位)です。
  • history_days 動物相がドキュメントの変更に対する変更を保持する期間です。
  • name コレクション名です。

次に、を作成します Users 次のクエリを使用したコレクション:

CreateCollection({name: "Users"})

両方のコレクションが配置されたので、最初のドキュメントを作成します。

動物相のドキュメントは、JSONオブジェクトにいくぶん似ています。 ドキュメントには文字列、数値、配列を格納できますが、動物相データ型を使用することもできます。 一般的な動物相のタイプはRefで、コレクション内のドキュメントへの参照を表します。

Create 関数は、指定されたコレクションに新しいドキュメントを作成します。 次のクエリを実行して、 Things 2つのフィールドを持つコレクション:

Create(
  Collection("Things"),
  {
    data: {
      name: "Banana",
      color: "Yellow"
    }
  }
)

そのクエリを実行した後、Faunaは作成されたドキュメントを返します。

{
  ref: Ref(Collection("Things"), "292079274901373446"),
  ts: 1614807352895000,
  data: {
    name: "Banana",
    color: "Yellow"
  }
}

結果には、次のフィールドが表示されます。

  • ref タイプの Ref のこのドキュメントへの参照です Things IDのコレクション 292079274901373446. ドキュメントのIDは異なることに注意してください。
  • ts 作成のタイムスタンプ(マイクロ秒単位)です。
  • data ドキュメントの実際のコンテンツです。

この結果は、コレクションを作成したときに得られた結果と似ています。 これは、Faunaのすべてのエンティティ(コレクション、インデックス、ロールなど)が実際にはドキュメントとして保存されているためです。

ドキュメントを読み取るには、ドキュメントの参照を受け入れるGet関数を使用します。 を実行します Get ドキュメントの参照を使用してクエリを実行します。

Get(Ref(Collection("Things"), "292079274901373446"))

結果は完全なドキュメントです:

{
  ref: Ref(Collection("Things"), "292079274901373446"),
  ts: 1614807352895000,
  data: {
    name: "Banana",
    color: "Yellow"
  }
}

コレクションに保存されているドキュメントのすべての参照を取得するには、Documents関数とPaginate関数を使用します。

Paginate(Documents(Collection("Things")))

このクエリは、参照の配列を含むページを返します。

{
  data: [Ref(Collection("Things"), "292079274901373446")]
}

参照の代わりに実際のドキュメントを取得するには、Mapを使用して参照を繰り返し処理します。 次に、 Lambda (無名関数)を使用して、参照の配列を反復処理し、 Get 各参照:

Map(
  Paginate(Documents(Collection("Things"))),
  Lambda("ref", Get(Var("ref")))
)

結果は、完全なドキュメントを含む配列です。

{
  data: [
    {
      ref: Ref(Collection("Things"), "292079274901373446"),
      ts: 1614807352895000,
      data: {
        name: "Banana",
        color: "Yellow"
      }
    }
  ]
}

次に、を作成します Users_by_username 索引。 通常、Faunaでインデックスを使用してデータをカタログ化、フィルタリング、および並べ替えますが、一意の制約を適用するなどの他の目的にも使用できます。

The Users_by_username インデックスはユーザーを検索します username、また、2つのドキュメントが同じになるのを防ぐために一意の制約を適用します username.

シェルで次のコードを実行して、インデックスを作成します。

CreateIndex({
  name: "Users_by_username",
  source: Collection("Users"),
  terms: [{ field: ["data", "username"] }],
  unique: true
})

CreateIndex 関数は、構成された設定でインデックスを作成します。

  • name インデックスの名前です。
  • source インデックスがデータのインデックスを作成する1つまたは複数のコレクションです。
  • terms は、ドキュメントを検索するためにこのインデックスを使用するときにこのインデックスに渡す検索/フィルター用語です。
  • unique インデックス付けされた値が一意になることを意味します。 この例では、 username のドキュメントのプロパティ Users コレクションは一意として適用されます。

インデックスをテストするには、内部に新しいドキュメントを作成します Users 動物相シェルで次のコードを実行してコレクションを作成します。

Create(
  Collection("Users"),
  {
    data: {
      username: "sammy"
    }
  }
)

次のような結果が表示されます。

{
  ref: Ref(Collection("Users"), "292085174927098368"),
  ts: 1614812979580000,
  data: {
    username: "sammy"
  }
}

次に、同じドキュメントを作成してみます username 価値:

Create(
  Collection("Users"),
  {
    data: {
      username: "sammy"
    }
  }
)

今すぐエラーが表示されます:

Error: [
  {
    "position": [
      "create"
    ],
    "code": "instance not unique",
    "description": "document is not unique."
  }
]

インデックスが作成されたので、インデックスをクエリして1つのドキュメントをフェッチできます。 シェルでこのコードを実行して、 sammy インデックスを使用するユーザー:

Get(
  Match(
    Index("Users_by_username"),
    "sammy"
  )
)

仕組みは次のとおりです。

  • Index は、への参照を返します Users_by_username 索引。
  • Match は、一致したドキュメント( username の値で sammy).
  • Get によって返された参照を取ります Match、実際のドキュメントを取得します。

このクエリの結果は次のようになります。

{
  ref: Ref(Collection("Users"), "292085174927098368"),
  ts: 1614812979580000,
  data: {
    username: "sammy"
  }
}

Delete 関数への参照を渡して、このテストドキュメントを削除します。

Delete(Ref(Collection("Users"), "292085174927098368"))

次に、Faunaのセキュリティ設定を構成して、コードからFaunaに接続できるようにします。

ステップ2—サーバーキーと承認ルールの構成

このステップでは、PythonアプリケーションがFaunaとの通信に使用するサーバーキーを作成します。 次に、アクセス許可を構成します。

キーを作成するには、左側のメインメニューを使用して、動物相ダッシュボードのセキュリティセクションに移動します。 そこに着いたら:

  1. 新しいキーボタンを押します。
  2. サーバーの役割を選択します。
  3. 保存を押します。

保存後、ダッシュボードにキーの秘密が表示されます。 シークレットを安全な場所に保存し、Gitリポジトリにコミットしないでください。

警告サーバーの役割は全能であり、この秘密を持っている人は誰でもデータベースに完全にアクセスできます。 その名前が示すように、これは信頼できるサーバーアプリケーションで通常使用される役割ですが、特権が制限されたカスタム役割でキーを作成することもできます。 本番アプリケーションを作成するときは、より制限的な役割を作成する必要があります。

デフォルトでは、Faunaのすべてが非公開であるため、ログインしたユーザーがからドキュメントを読み取れるようにするための新しい役割を作成します。 Things コレクション。

ダッシュボードのセキュリティセクションで、ロールに移動し、名前を使用して新しいカスタムロールを作成します User.

コレクションドロップダウンで、 Things 収集し、読み取り権限を押して、緑色のチェックマークを表示します。

役割を保存する前に、メンバーシップタブに移動して、 Users 役割へのコレクション:

これで保存できます User 保存ボタンを押してカスタムロール。

これで、 Users コレクションは、から任意のドキュメントを読み取ることができます Things コレクション。

認証と承認が整ったら、Faunaと通信するPythonAPIを作成しましょう。

ステップ3—Pythonアプリケーションの構築

このステップでは、Flaskフレームワークを使用して小さなREST APIを構築し、PythonでFQLクエリを記述し、Faunaドライバーを使用してFaunaデータベースに接続します。

開始するには、プロジェクトフォルダを作成し、ターミナルからアクセスします。

最初にFlaskをインストールします。

  1. pip install flask

次に、FaunaPythonドライバーを次のコマンドでインストールします。

  1. pip install faunadb

プロジェクトフォルダにファイルを作成します main.py 次のコードをファイルに追加します。これにより、必要なインポートが追加されます。 FAUNA_SECRET 環境変数、およびFlaskアプリケーションの基本構成:

main.py
import os
FAUNA_SECRET = os.environ.get('FAUNA_SECRET')

import flask
from flask import request

import faunadb
from faunadb import query as q
from faunadb.client import FaunaClient

app = flask.Flask(__name__)
app.config["DEBUG"] = True

The FAUNA_SECRET 環境変数は、前に作成したサーバーシークレットを保持します。 このアプリケーションをローカルまたはクラウドで実行できるようにするには、この変数を挿入する必要があります。 これがないと、アプリケーションは動物相に接続できません。 アプリを起動するときに、この環境変数を指定します。

次に、を追加します /signup へのルート main.py ファイル。 これにより、に新しいドキュメントが作成されます Users コレクション:

main.py
@app.route('/signup', methods=['POST'])
def signup():

    body = request.json
    client = FaunaClient(secret=FAUNA_SECRET)

    try:
        result = client.query(
            q.create(
                q.collection("Users"),
                {
                    "data": {
                        "username": body["username"]
                    },
                    "credentials": {
                        "password": body["password"]
                    }
                }
            )
        )

        return {
            "userId": result['ref'].id()
        }

    except faunadb.errors.BadRequest as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 409

Faunaクライアントは、サーバーシークレットを使用してすべてのリクエストでインスタンス化されていることに注意してください。

main.py
...
client = FaunaClient(secret=FAUNA_SECRET)
...

ユーザーがログインすると、APIは異なるシークレットを使用して各ユーザーに代わってクエリを実行します。そのため、リクエストごとにクライアントをインスタンス化するのが理にかなっています。

他のデータベースとは異なり、Faunaクライアントは永続的な接続を維持しません。 外の世界から見ると、FaunaはAPIのように動作します。 すべてのクエリは単一のHTTPリクエストです。

クライアントの準備ができたら、FQLクエリが実行され、新しいドキュメントが作成されます。 Users コレクション。 各Faunaドライバーは、慣用的な構文をFQLステートメントに変換します。 このルートでは、次のクエリを追加しました。

main.py
...
q.create(
    q.collection("Users"),
    {
        "data": {
            "user": json["user"]
        },
        "credentials": {
            "password": json["password"]
        }
    }
)
...

これは、このクエリがネイティブFQLでどのように表示されるかを示しています。

Create(
    Collection("Users"),
    {
        "data": {
            "user": "sammy"
        },
        "credentials": {
            "password": "secretpassword"
        }
    }
)

ドキュメントデータに加えて、 credentials ユーザーのパスワードを使用した構成。 ドキュメントのこの部分は完全に非公開です。 その後、ドキュメントのクレデンシャルを読み取ることはできなくなります。 動物相の認証システムを使用する場合、ユーザーのパスワードを誤って公開することはできません。

最後に、同じユーザー名のユーザーがすでにいる場合は、 faunadb.errors.BadRequest 例外が発生し、 409 エラー情報を含む応答がクライアントに返されます。

次に、 /login のルート main.py ユーザーとパスワードを認証するためのファイル。 これは、前の例と同様のパターンに従います。 動物相接続を使用してクエリを実行し、認証が失敗した場合は、 faunadb.errors.BadRequest 例外と戻り値aa 401 エラー情報で応答します。 このコードをに追加します main.py:

main.py
@app.route('/login', methods=['POST'])
def login():

    body = request.json
    client = FaunaClient(secret=FAUNA_SECRET)

    try:
        result = client.query(
            q.login(
                q.match(
                    q.index("Users_by_username"),
                    body["username"]
                ),
                {"password": body["password"]}
            )
        )

        return {
            "secret": result['secret']
        }

    except faunadb.errors.BadRequest as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 401

これは、Faunaでユーザーを認証するために使用されるFQLクエリです。

main.py
q.login(
    q.match(
        q.index("Users_by_username"),
        body["username"]
    ),
    {"password": body["password"]}
)

これは、このクエリがネイティブFQLでどのように表示されるかを示しています。

Login(
    Match(
        Index("Users_by_username"),
        "sammy"
    ),
    {"password": "secretpassword"}
)

Match を使用してドキュメントへの参照を返します Users_by_username 以前に作成したインデックス。

提供されたパスワードが参照されたドキュメントと一致する場合、 Login 新しいトークンを作成し、次のキーを持つ辞書を返します。

  • ref 新しいドキュメントのトークンを参照します。
  • ts トランザクションのタイムスタンプ付き。
  • instance 認証を行うために使用されたドキュメントへの参照。
  • secret 動物相へのさらなるクエリを行うために使用されるトークンの秘密を持ちます。

そのFQLクエリをFaunaダッシュボードのシェルに実行すると、次のようなものが表示されます。

{
  ref: Ref(Ref("tokens"), "292001047221633538"),
  ts: 1614732749110000,
  instance: Ref(Collection("Users"), "291901454585692675"),
  secret: "fnEEDWVnxbACAgQNBIxMIAIIKq1E5xvPPdGwQ_zUFH4F5Dl0neg"
}

プロジェクトのセキュリティ要件に応じて、トークンのシークレットを処理する方法を決定する必要があります。 このAPIがブラウザーによって使用されることを意図している場合は、安全なCookieまたは暗号化されたJSON Webトークン(JWT)内にシークレットを返すことができます。 または、Redisインスタンスなど、別の場所にセッションデータとして保存することもできます。 このデモの目的のために、HTTP応答の本文でそれを返します。

最後に、このコードをに追加します main.py、Flaskアプリケーションを起動します。

main.py
app.run(host=os.getenv('IP', '0.0.0.0'), port=int(os.getenv('PORT', 8080)))

を指定することが重要です 0.0.0.0 住所。 クラウドにデプロイされると、このアプリケーションはDockerコンテナで実行されます。 で実行されている場合、リモートクライアントからのリクエストを受信することはできません 127.0.0.1、Flaskアプリケーションのデフォルトアドレスです。

これは完全です main.py これまでのファイル:

main.py
import os
FAUNA_SECRET = os.environ.get('FAUNA_SECRET')

import flask
from flask import request

import faunadb
from faunadb import query as q
from faunadb.client import FaunaClient

app = flask.Flask(__name__)
app.config["DEBUG"] = True

@app.route('/signup', methods=['POST'])
def signup():

    body = request.json
    client = FaunaClient(secret=FAUNA_SECRET)

    try:
        result = client.query(
            q.create(
                q.collection("Users"),
                {
                    "data": {
                        "username": body["username"]
                    },
                    "credentials": {
                        "password": body["password"]
                    }
                }
            )
        )

        return {
            "userId": result['ref'].id()
        }

    except faunadb.errors.BadRequest as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 409

@app.route('/login', methods=['POST'])
def login():

    body = request.json
    client = FaunaClient(secret=FAUNA_SECRET)

    try:
        result = client.query(
            q.login(
                q.match(
                    q.index("Users_by_username"),
                    body["username"]
                ),
                {"password": body["password"]}
            )
        )

        return {
            "secret": result['secret']
        }

    except faunadb.errors.BadRequest as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 401

app.run(host=os.getenv('IP', '0.0.0.0'), port=int(os.getenv('PORT', 8080)))

ファイルを保存します。

ターミナルからこのサーバーをローカルで起動するには、次のコマンドを使用して FAUNA_SECRET サーバーキーの作成時に取得したシークレットを持つ環境変数:

  1. FAUNA_SECRET=your_fauna_server_secret python main.py

そのコマンドをトリガーした後、Flaskは開発WSGIサーバーで実行されていることを通知する警告を表示します。 このデモではこれで問題ないため、この警告は無視してかまいません。

を使用してHTTPリクエストを作成し、APIをテストします curl 指図。 新しいターミナルウィンドウを開き、次のコマンドを実行します。

次のコマンドでユーザーを作成します。

  1. curl -i -d '{"user":"sammy", "password": "secretpassword"}' -H 'Content-Type: application/json' -X POST http://0.0.0.0:8080/signup

ユーザーの作成が成功したことを示す次の応答が表示されます。

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 37
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Thu, 04 Mar 2021 01:00:47 GMT

{
  "userId": "292092166117786112"
}

次に、次のコマンドでそのユーザーを認証します。

  1. curl -i -d '{"user":"sammy", "password": "secretpassword"}' -H 'Content-Type: application/json' -X POST http://0.0.0.0:8080/login

この成功した応答が得られます:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 70
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Thu, 04 Mar 2021 01:01:19 GMT

{
  "secret": "fnEEDbhO3jACAAQNBIxMIAIIOlDxujk-VJShnnhkZkCUPKIHxbc"
}

実行したターミナルウィンドウを閉じます curl コマンドを実行し、Pythonサーバーが実行されているターミナルに戻ります。 を押してサーバーを停止します CTRL+C.

アプリケーションが機能するようになったので、ユーザーの認証を必要とするプライベートエンドポイントを追加します。

ステップ4—プライベートエンドポイントを追加する

このステップでは、APIにプライベートエンドポイントを追加します。これには、最初にユーザーを認証する必要があります。

まず、で新しいルートを作成します main.py ファイル。 このルートはに応答します /things 終点。 サーバーを起動する行の上に配置します。 app.run() 方法:

main.py
@app.route('/things', methods=['GET'])
def things():

次に、 /things ルート、動物相クライアントをインスタンス化します。

main.py
    userSecret = request.headers.get('fauna-user-secret')
    client = FaunaClient(secret=userSecret)

このルートでは、サーバーシークレットを使用する代わりに、 fauna-user-secret Faunaクライアントをインスタンス化するために使用されるHTTPヘッダー。 サーバーシークレットの代わりにユーザーシークレットを使用することにより、FQLクエリは、ダッシュボードで以前に構成した承認ルールの対象になります。

次にこれを追加します try クエリを実行するルートにブロックします。

main.py
    try:
        result = client.query(
            q.map_(
                q.lambda_("ref", q.get(q.var("ref"))),
                q.paginate(q.documents(q.collection("Things")))
            )
        )

        things = map(
            lambda doc: {
                "id": doc["ref"].id(),
                "name": doc["data"]["name"],
                "color": doc["data"]["color"]
            },
            result["data"]
        )

        return {
            "things": list(things)
        }

これにより、FQLクエリが実行され、Fauna応答がシリアル化可能な型に解析され、HTTP応答の本文でJSON文字列として返されます。

最後に、これを追加します except ルートへのブロック:

main.py
    except faunadb.errors.Unauthorized as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 401

リクエストに有効なシークレットが含まれていない場合、 faunadb.errors.Unauthorized 例外が発生し、エラー情報を含む401応答が返されます。

これはの完全なコードです /things ルート:

main.py
@app.route('/things', methods=['GET'])
def things():

    userSecret = request.headers.get('fauna-user-secret')
    client = FaunaClient(secret=userSecret)

    try:
        result = client.query(
            q.map_(
                q.lambda_("ref", q.get(q.var("ref"))),
                q.paginate(q.documents(q.collection("Things")))
            )
        )

        things = map(
            lambda doc: {
                "id": doc["ref"].id(),
                "name": doc["data"]["name"],
                "color": doc["data"]["color"]
            },
            result["data"]
        )

        return {
            "things": list(things)
        }

    except faunadb.errors.Unauthorized as exception:
        error = exception.errors[0]
        return {
            "code": error.code,
            "description": error.description
        }, 401

ファイルを保存して、サーバーを再度実行します。

  1. FAUNA_SECRET=your_fauna_server_secret python main.py

このエンドポイントをテストするには、最初に有効な資格情報で認証してシークレットを取得します。 新しいターミナルウィンドウを開き、これを実行します curl 指図:

  1. curl -i -d '{"username":"sammy", "password": "secretpassword"}' -H 'Content-Type: application/json' -X POST http://0.0.0.0:8080/login

このコマンドは成功した応答を返しますが、 secret 異なります:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 70
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Thu, 04 Mar 2021 01:01:19 GMT

{
  "secret": "fnEEDb...."
}

今、雌鶏はGETリクエストを行います /things 秘密を使用して:

curl -i -H 'fauna-user-secret: fnEEDb...' -X GET http://0.0.0.0:8080/things

別の成功した応答が得られます:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 118
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Thu, 04 Mar 2021 01:14:49 GMT

{
  "things": [
    {
      "color": "Yellow",
      "id": "292079274901373446",
      "name": "Banana"
    }
  ]
}

を実行したターミナルウィンドウを閉じます curl コマンド。 サーバーが実行されているウィンドウに戻り、サーバーを停止します。 CTRL+C.

動作するアプリができたので、それをデプロイする準備が整いました。

ステップ4—DigitalOceanへのデプロイ

このチュートリアルの最後のステップでは、App Platformでアプリを作成し、GitHubリポジトリからデプロイします。

プロジェクトをGitリポジトリにプッシュする前に、プロジェクトのフォルダーで次のコマンドを実行してください。

  1. pip freeze > requirements.txt

これにより、 requirements.txt アプリケーションのデプロイ後にインストールする必要のある依存関係のリストを含むファイル。

次に、プロジェクトディレクトリをGitリポジトリとして初期化します。

  1. git init

次に、次のコマンドを実行して、リポジトリにファイルを追加します。

  1. git add .

これにより、現在のディレクトリ内のすべてのファイルが追加されます。

ファイルを追加したら、最初のコミットを行います。

  1. git commit -m "Initial version of the site"

ファイルがコミットされます。

ブラウザを開いてGitHubに移動し、プロファイルを使用してログインし、という新しいリポジトリを作成します。 sharkopedia. なしで空のリポジトリを作成する README またはライセンスファイル。

リポジトリを作成したら、コマンドラインに戻ってローカルファイルをGitHubにプッシュします。

まず、GitHubをリモートリポジトリとして追加します。

  1. git remote add origin https://github.com/your_username/sharkopedia

次に、デフォルトのブランチの名前を変更します main、GitHubが期待するものと一致させるために:

  1. git branch -M main

最後に、 main GitHubへのブランチ main ブランチ:

  1. git push -u origin main

ファイルが転送されます。 これで、アプリをデプロイする準備が整いました。

:App Platformでアプリを作成できるようにするには、最初にDigitalOceanアカウントに支払い方法を追加する必要があります。

アプリケーションは月額5ドルのコンテナで実行されますが、テストに必要なのはわずか数セントです。 完了したら、アプリケーションを削除することを忘れないでください。削除しないと、引き続き課金されます。

DigitalOceanダッシュボードのAppsセクションに移動し、 Launch YourAppをクリックします。

展開するソースを選択します。 Githubリポジトリを読み取るには、DigitalOceanを承認する必要があります。 アクセスを承認したら、Pythonプロジェクトと、デプロイするアプリのバージョンを含むブランチを含むリポジトリを選択します。

この時点で、App PlatformはプロジェクトがPythonを使用していると判断し、いくつかのアプリケーションオプションを構成できるようにします。

次のオプションを設定します

  • タイプWebサービスであることを確認してください。
  • 作成するFAUNA_SECRET サーバーシークレットを持つ環境変数。
  • コマンドの実行をに設定します python main.py.
  • HTTPポートをに設定します 8080.

次に、アプリの名前を入力し、デプロイリージョンを選択します。

次に、ベーシックプランとベーシックサイズを選択します。料金は月額5ドルです。

その後、下にスクロールしてアプリの起動をクリックします。

アプリの構成が完了すると、コンテナーが作成され、アプリケーションとともにデプロイされます。 この最初の初期化には数分かかりますが、その後のデプロイははるかに高速になります。

アプリのダッシュボードに、デプロイプロセスが正常に終了したことを示す緑色のチェックマークが表示されます。

これで、提供されたアプリドメインに対してHTTPリクエストを実行できるようになります。 代わりに、端末で次のコマンドを実行します your_app_name 実際のアプリ名を使用して、の新しいシークレットを返します sammy ユーザー:

  1. curl -i -d '{"user":"sammy", "password": "secretpassword"}' -H 'Content-Type: application/json' -X POST https://your_app_name.ondigitalocean.app/login

次のような応答が返されます。

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 70
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Thu, 04 Mar 2021 01:01:19 GMT

{
  "secret": "fnAADbhO3jACEEQNBIxMIAOOIlDxujk-VJShnnhkZkCUPKIskdjfh"
}

これで、アプリケーションがDigitalOceanで稼働します。

結論

このチュートリアルでは、Faunaをデータレイヤーとして使用してPython REST APIを作成し、それをDigitalOceanAppPlatformにデプロイしました。

動物相について学び続け、FQLをさらに深く掘り下げるには、動物相のドキュメントを確認してください。