TECH PLAY

Django

Djangoは、Pythonで開発されたオープンソースのWEBアプリケーションフレームワークです。Djangoは高い生産性と堅牢性を提供し、多くのプロジェクトで利用されています。

Djangoの主な特徴は以下の通りです。

MTVアーキテクチャ: Djangoはモデル(データベースの操作)、テンプレート(ユーザーインターフェースの処理)、ビュー(ビジネスロジックの処理)というMTV(モデル・テンプレート・ビュー)アーキテクチャを採用しています。このアーキテクチャにより、コードの再利用性と保守性が向上します。

ORM (Object-Relational Mapping): DjangoのORMはデータベースとのやり取りを簡単に行えるようにするためのツールです。SQLクエリの代わりにPythonのコードを使用してデータベースを操作できます。これにより、データベースに依存しない柔軟なアプリケーション開発が可能です。

豊富な機能セット: Djangoには多くの便利な機能が組み込まれています。ユーザー認証、セッション管理、URLルーティング、フォーム処理、管理者インターフェースなど、一般的なWEBアプリケーション開発に必要な機能を提供しています。

テンプレートエンジン: Djangoのテンプレートエンジンは、HTMLコードとPythonコードを組み合わせた柔軟なテンプレートを作成するためのものです。ビューから渡されたデータを動的に表示することができます。

スケーラビリティ: Djangoはスケーラビリティにも優れています。大規模なトラフィックや高負荷なアプリケーションにも対応できるように設計されており、キャッシング、非同期タスク、負荷分散などの機能を提供しています。

Djangoは豊富なドキュメントと活発なコミュニティがあり、多くの企業や開発者によって活用されています。シンプルな構造と高度な機能を兼ね備えたDjangoは、迅速かつ効率的なWEBアプリケーション開発において強力なツールとなっています。

Django

https://www.djangoproject.com/

イベント

該当するコンテンツが見つかりませんでした

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

ブログリレー 前回の記事 では、バックエンドのあれこれを齋藤さんが記事にしてくれましたが、本日はフロントエンド編ということで、AWSパラメータシート自動生成ツールのGUIをどのような技術を使用して実現したかをご紹介できればと思います! フロントエンド概要 フロントエンドは下記のような流れでバックエンド(パラメーターシート出力)に処理が引き継がれます。 上記処理のうち、本記事のフロントエンドは「GUI」と「GUIを提供するサーバー」部分を担当しています。 使用した技術 フロントエンド実現のために使用した主な技術とその役割は下記の通りです。 技術 役割 JavaScript クライアント側、サーバーサイド側のロジックを記述するために使用した言語 Node.js  JavaScriptの実行環境であり、アプリケーション全体の実行基盤 Express.js WebサーバーおよびREST APIなどのサーバーサイド側の機能を提供してくれるWebフレームワーク HTML5 + CSS3 画面構造とデザイン フロントエンドは、クライアント側、サーバーサイド側も一貫してJavaScriptを使用して実装しています。 サーバーサイド側の開発として、Ruby + Rails や Python + Django といった組み合わせもある中で、JavaScript + Node.js を使用した理由としては、以下の通りです。 案件で JavaScript を触る機会があり慣れている よく耳にする組み合わせでなんかかっこいい しかし、よくよく調べるとよく耳にする理由がありました。それについては以降で説明していきたいと思います。 Node.js Node.jsとは? そもそもNode.jsとは何者かというと、 JavaScriptをサーバー上で実行するための開発環境 です。 元々、JavaScriptという言語は他の言語と異なり、ブラウザ上で動作する言語であり、ローカル(OS上)環境では動作させることができない言語でした。 よって、ブラウザ上でしか動作しない JavaScript ではローカル環境にあるファイルを読みにいくことができないという問題がありました。 その制限を取っ払ってくれたのが、Node.jsという訳です。 Node.jsの登場のおかげで、 クライアント・サーバーサイドの両者を同一の言語で開発 することができるようになりました。 Node.jsの特徴 Node.jsの特徴としては、主に以下の3つが挙げられます。 1. ノンブロッキングI/O処理 前のタスクが完了していない状態でも次のタスクを開始でき、 非同期での処理を実現 している。 そのため、大量のアクセスがあっても対応が可能である。 2. シングルスレッドによる処理 プログラムを実行する際に、1つずつ処理を行う 。 一般的にシングルスレッドだと大量のアクセスがあった場合に制御することが難しくなるが、ノンブロッキングI/O処理によって、多くのアクセスがあってもリアルタイムでレスポンスが可能になる。 3. 豊富なライブラリ サーバーサイドアプリケーション、デスクトップアプリケーション、コマンドラインツールなどの幅広い用途で使用されるため、非常に多くのライブラリがある。 npmというパッケージ管理ツールを使用することにより、膨大なライブラリを簡単にインストール・管理することができる。 これらの特徴から、Node.js + JavaScript は 大量の同時処理をさばけ、なおかつ様々な目的で使用できる汎用的な技術基盤 として人気があるという訳です。 Express.js ここまでで、Node.jsを使用した理由や用途は理解できたかと思いますが、あくまでもNode.jsはサーバーサイド側でJavaScriptを実行できるようにした実行環境であり、ただの基盤です。 フロントエンドを作成する上では、基盤の上に実際の機能を作成してあげる必要があります。 その実際の機能は一から作る必要はなく、既に用意されたひな形から作成することができます。 それにあたるのが、Express.jsです。 Express.jsとは? Express.jsとは、 Node.jsのための軽量で柔軟なWebアプリケーションフレームワーク です。 フレームワークとはひな形とも言い換えることができ、様々なひな形が用意されています。 例えば、機能開発が簡単に実装できる以下のようなひな形が用意されています。 ルーティング機能 ユーザーが特定のURLにアクセスした際に、 どのようなレスポンス(応答)を返すかを定義 することができる。 例えば、ユーザが / にアクセスしたら、トップページを表示する、/download/file.xlsx にアクセスしたら、ファイルをダウンロードするなどがある。 REST API機能 フロントエンド(ブラウザ)からのリクエストを受け取り、 Web上でデータをやりとりするための操作を定義 することができる。その操作には以下のものがあり、これらを定義することができる。 HTTPメソッド 操作 GET リソースを取得する POST リソースを作成する PUT 指定したIDのリソースを更新する DELETE 指定したIDのリソースを削除する 静的ファイルの配信 静的ファイル(HTML、CSS、JavaScript、画像など)をユーザーに配信することができる。 また、HTTPヘッダーによるキャッシュ制御も可能で、同じファイルへの再リクエスト時のレスポンス時間を短縮できる。 どこに使用したの? では、フロントエンド実現にあたってどこに活用したのかというと下記の通りです。 機能 使用箇所 ルーティング機能 トップページの表示 ファイルのダウンロード REST API機能 AWSリソース一覧取得 Excel生成リクエスト(バックエンドへのトリガー) 静的ファイルの配信 HTML/CSS/JavaScriptファイルの配信 苦労した点 リソースごとに異なるJSONファイル フロントエンドでは、AWSのリソースの詳細情報を表示するために、AWS CLIコマンドを実行し、リソースの一覧を取得してきています。その一覧情報の構造が、リソースによって異なり、リソースごとに取得する情報を定義してあげることが苦労しました。 例: EC2インスタンスの場合: {   “Reservations”: [     {       “Instances”: [         { “InstanceId”: “i-xxxxx”, “State”: {…} }       ]     }   ] } S3バケットの場合: {   “Buckets”: [     { “Name”: “my-bucket”, “CreationDate”: “…” }   ] } このように、同じ「リソース一覧を取得する」という処理でも、項目名やJSONファイルのネスト構造の深さが異なります。そのため、すべてのリソースに対して、どのキーからデータを取り出すか、IDとして何を使うかを個別に定義する必要がありました。 一方で、共通化できる部分は共通化し、できるだけ同様のコードで詳細情報を取得できるようにしてあげました。やはりコードの最適化には、AIを使用してあげるのが効率よかったです。 特殊なリソースの取得フロー 一般的なリソースの場合、取得フローは下記のようになります。 サービス選択 ⇒ リソース一覧から出力したいリソースを選択 ⇒ プレビュー画面表示 ⇒ Excel 出力 しかし、サービスの中には一発で一覧を取得できないサービスがあります。 例えば、ELBのターゲットグループの場合、ELBに紐づくターゲットグループを取得する必要があるため、まず最初にELBの一覧を取得し、その後にターゲットグループを取得する必要があります。よって、一覧の取得フローとしては下記のようになります。 サービス選択(ELBターゲットグループ)⇒ リソース一覧から出力したいリソースを選択(ELB)⇒ リソース一覧から出力したいリソースを選択(ターゲットグループ)⇒ プレビュー画面表示 ⇒ Excel 出力 このようにサービスによっては、中間ステップが存在するものもあるため、コードを共通化することができず、苦労しました。 まとめ 本記事では、AWSパラメータシート自動生成ツールのGUIであるフロントエンドで使用した技術について簡単に紹介しました。 実は、この取り組みはフロントエンドのアプリケーションを作成するつもりはなく、バックエンドのJSONファイルをパラメータシートに変換するアプリケーションのみを構築予定でした。しかし、使用するユーザー目線で考えると、やはりGUIがほしいということになり、開発に取り組みました。 普段はインフラ構築を担当する部署のため、初めて触れる技術が多く、開発には3~4か月ほどかかってしまいましたが、この取り組みを経てアプリケーションの知識をつけることができ、フルスタックエンジニアへと一歩近づいた気がします。 皆さんもぜひ、息抜きもかねて普段とは異なる分野の技術に触れてみるのはいかがでしょうか? というわけで、私の投稿は以上です! 次回は、AWSパラメータシート自動生成ツールを使ってみたということで、藪内さんにバトンタッチしますので、ぜひそちらも閲覧いただければと思います。
この記事では、AzureMCPServerとStreamlitを組み合わせて、Azureリソースを対話的に操作するWebアプリケーションを構築する方法について説明します。 つまり以下のように「Azureのコレコレのリソースの情報取得して」とか「Azure Blob Storageのコンテナ作って」みたいにWebブラウザから対話的に指示すると、そのとおりにAzureリソースが出来上がるWebアプリをサクッと作ってしまおうという感じです。 説明はいいからサクッと動かしたいよーという方はソースコードと起動方法を以下のGitリポジトリで公開しているので、そちらを参照してください。 https://github.com/noriyukitakei/azure-mcp-server-webif Azure MCP Serverとは? Azure MCP Serverとは、Azureが提供しているMCPサーバーであり、Azureリソースの管理や操作を行うための機能を提供します。 https://learn.microsoft.com/ja-jp/azure/developer/azure-mcp-server/tools/ MCP(Model Context Protocl)に準拠しているので、MCPに対応しているクライアントであれば、Visual Studio CodeやCursor、Eclipse、IntelliJなど、様々な開発環境からAzureリソースを操作することができます。 今回構築するWebアプリケーションについて Visual Studio Code などから Azure MCP Server と連携する例は多く紹介されていますが、本記事では Streamlit を使って Web インターフェースを構築し、Azure MCP Server と連携する方法 を紹介します。これにより、ブラウザ上から Azure リソースを対話的に操作できるようになり、より多くのユーザーにとって使いやすいインターフェースを提供できます。 ただし、適切な権限管理を行わないと、意図しない Azure リソースの変更が発生する可能性があるため注意してください。 今回構築するアプリのソースコードは以下のGitHubリポジトリで公開しています。 https://github.com/noriyukitakei/azure-mcp-server-webif.git 構成 今回構築するシステムの構成は以下の通りです。 UIを提供するStreamlit、LLMによる思考を担うAIエージェント、MCPクライアント、Azure MCP Serverの4つのコンポーネントで構成されます。UI、AIエージェント、MCPクライアントは同一のWebアプリケーション(プロセス)内で動作し、Azure MCP Serverとの通信方式はSTDIO(標準入出力)を使用します。 UI Webアプリケーションのユーザーインターフェース部分です。Streamlitを使用して構築します。ユーザーからの入力を受け取り、結果を表示します。 Streamlitは、Pythonを使って簡単にインタラクティブなWebアプリケーションを作成できるオープンソースのフレームワークです。プログラミングの経験が少なくても、Pythonコードを書くだけで、データビジュアライゼーションやインターフェースを持つアプリをすぐに作ることができるのが特徴です。 従来、Webアプリケーションを作成するには、フロントエンド(HTML、CSS、JavaScript)とバックエンド(Python、Django、Flaskなど)の両方の技術を理解する必要がありました。しかし、Streamlitを使えば、Pythonだけでフロントエンドとバックエンドを同時に構築できるため、非常に手軽にアプリ開発に取り組めます。 たとえば、データサイエンティストがモデルの結果を共有したり、エンジニアがプロトタイプを素早く作成したりする場面でよく利用されています。 AIエージェント ユーザーからの指示を受け取り、適切なアクションを判断し、必要に応じてMCPサーバーにリクエストを送信します。 Function Callingを活用し、AIエージェントの思考と行動を実現します。Function Callingに対応したLLMを使用する必要があるため、今回は Azure OpenAI Serviceを利用しますが、他の対応LLMに置き換えることも可能です。 なお、AIエージェントは LangChainのようなAIエージェントフレームワークを用いて実装することもできます。しかし今回は学習を目的として、できるだけシンプルな独自実装で進めます。そのため、コードはやや冗長であり、実際のアプリケーションで使用するには最適化が必要な部分もありますが、基本的な仕組みを理解するには十分な内容になっています。 MCPクライアント MCPクライアントは、FastMCPを用いて実装しています。FastMCP は、MCPサーバーとMCPクライアントの両方の機能を提供するライブラリであり、ここではMCPクライアントとして使用します。 MCPサーバー Azure MCP Server本体になります。Azureリソースの管理や操作を行うための機能を提供します。npxやnpm、Dockerで起動する方法がありますが、今回はDockerで起動し、通信方式はSTDIO(標準入出力)を使用します。 処理の流れ 今回構築するWebアプリケーションの処理の流れは以下の通りです。 [ステップ1] ユーザーが指示を入力 ユーザーはWebアプリケーションのUIを通じて、Azureリソースに対する操作指示を入力します。例えば「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」と入力するとします。 その指示は、StreamlitによるUIを通じてAIエージェントに送信されます。 [ステップ2] MCPサーバーへの初期化要求 MCPクライアントは、initializeというメソッドで初期化メッセージを最初に送ります。これは、MCPクライアントがMCPサーバーに対して「自分の機能・情報・バージョンなどを伝えて、接続を初期化したい」とリクエストしているメッセージです。 [ステップ3] MCPサーバーからの初期化応答 MCPサーバーはinitializeリクエストを受け取り、初期化応答を返して、自身のプロトコルのバージョンなどをMCPクライアントに伝えます。 [ステップ4] 初期化完了通知の送信 MCPクライアントは、MCPサーバーからの初期化応答を受け取り、初期化が完了したことをMCPサーバーに通知します。 [ステップ5] ツールの一覧取得 MCPクライアントは、tools/listというメソッドでツールの一覧(そのMCPサーバーが持っている機能の一覧)をMCPサーバーにリクエストします。これにより、MCPサーバーが提供するツールの情報を取得します。 [ステップ6] ツール一覧の応答受信 MCPサーバーは、tools/listリクエストを受け取り、提供するツールの一覧をMCPクライアントに返します。ここではAzure MCP Serverが提供するツールの一覧(Azure Blob StorageやAzure AI Searchなどのリソースを操作するコマンド一覧)が返されます。 [ステップ7] LLMへのFunction Calling指示 AIエージェントは、MCPクライアントから渡されたツール一覧をもとに、LLMに対してFunction Callingを行うよう指示します。具体的には、ユーザーからのプロンプトを解析してどのツールを呼び出すべきかを判断し、そのツールを使うようLLMに指示します。 ここでは、ユーザーの質問である「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」とともに、tools/listで取得したツール一覧をLLMに渡します。 [ステップ8] LLMからの関数呼び出し応答 LLMは、AIエージェントからのFunction Calling指示を受け取り、適切な関数呼び出し応答を生成します。この応答には、呼び出す関数名とそのパラメータが含まれます。 ここでは、sotorageというツールをLLMが選択したことがわかります。これはAzure Blob Storageの情報を取得するためのツールであり、ユーザーの質問に対して適切な選択となります。 [ステップ9] MCPサーバーへの関数呼び出しリクエスト AIエージェントはLLMからの関数呼び出し応答を受け取り、MCPクライアントを介してMCPサーバーに関数呼び出しリクエストを送信します。これにより、MCPサーバーに対して指定された関数を実行させます。 [ステップ10] MCPサーバーからの関数呼び出し応答 MCPサーバーは、MCPクライアントからの関数呼び出しリクエストを受け取り、指定された関数を実行します。その結果をMCPクライアントに返します。 今回は、Azure Blob Storageのさらに細かいコマンド一覧が返されています。 つまり、1回目のツール一覧取得では大まかなツール一覧が返され、2回目の関数呼び出し応答では、さらに詳細なコマンド一覧が返される形となっています。 [ステップ11] LLMへの追加Function Calling指示 ステップ11で取得した詳細なコマンド一覧をもとに、AIエージェントはLLMに対して追加のFunction Callingを行うよう指示します。これにより、ユーザーの質問に対してさらに具体的な回答を生成するための情報を提供します。 [ステップ12] LLMからの関数呼び出し応答 LLMは、AIエージェントからの追加Function Calling指示を受け取り、適切な関数呼び出し応答を生成します。この応答には、呼び出す関数名とそのパラメータが含まれます。 以下のような応答が返され、Azure Blob Storageの特定のコンテナ内にあるファイルの詳細情報を取得するための関数呼び出しが示されています。 "function_call": {   "name": ”storage_blob_get",   "arguments": "{'account': 'ntakeiassets', 'container': 'images', 'blob': 'log4j.png'}" } つまりこれは、storage_blob_getというコマンドを用いて、ストレージアカウント ‘ntakeiassets’ のコンテナ ‘images’ 内の ‘log4j.png’ というファイルの詳細情報を取得するための関数呼び出しを意味しています。 [ステップ13] MCPサーバーへの関数呼び出しリクエスト AIエージェントはLLMからの関数呼び出し応答を受け取り、MCPクライアントを介してMCPサーバーに関数呼び出しリクエストを送信します。これにより、MCPサーバーに対して指定された関数を実行させます。 [ステップ14] Azure Resource ManagerへのAPIリクエスト MCPサーバーは、MCPクライアントからの関数呼び出しリクエストを受け取り、そのコマンドをAzure Resource Manager (ARM) へのAPIリクエストに変換して実行します。これにより、Azureリソースに対する操作が行われます。 [ステップ15] MCPサーバーからの関数呼び出し応答 MCPサーバーは、Azure Resource ManagerからのAPIレスポンスを受け取り、その結果をMCPクライアントに返します。 今回は、指定されたストレージアカウント、コンテナ、ファイルに関する詳細情報が返されます。これには、ファイルのサイズ、作成日時、更新日時、コンテンツタイプなどのメタデータが含まれています。 [ステップ16] LLMへの最終Function Calling指示 AIエージェントはMCPクライアントからの関数呼び出し応答を受け取り、LLMに対して最終的なFunction Callingを行うよう指示します。これにより、ユーザーの質問に対する最終的な回答を生成するための情報を提供します。 [ステップ17] LLMからの最終応答 LLMは、AIエージェントからの最終Function Calling指示を受け取り、ユーザーの質問に対する最終的な応答を生成します。この応答には、Azureリソースに関する詳細情報が含まれています。 そして、AIエージェントはこの最終応答をWebアプリケーションのUIに返します。 起動方法 処理の流れをご理解いただけたところで、実際にアプリケーションを起動して動作させてみましょう。以下の手順で進めてください。 [ステップ1] リポジトリのクローン まず、GitHubリポジトリをクローンします。ターミナルを開き、以下のコマンドを実行してください。 $ git clone https://github.com/your-repository-url.git $ cd your-repository-directory [ステップ2] 環境変数の設定 次に、必要な環境変数を設定します。 `.env.example` ファイルをコピーして `.env` ファイルを作成し、必要な値を設定してください。 $ cp .env.example .env .env ファイル内で設定する主な環境変数は以下の通りです。 AZURE_OPENAI_ENDPOINT : Azure OpenAI ServiceのエンドポイントURL AZURE_OPENAI_API_KEY : Azure OpenAI ServiceのAPIキー AZURE_OPENAI_API_VERSION : 使用するAPIバージョン (例: 2024-06-01) AZURE_OPENAI_CHAT_DEPLOYMENT : 使用するチャットモデルのデプロイメント名 (例: gpt-4)` MAX_STEPS : AIエージェントが実行する最大ステップ数 (例: 5) AZURE_TENANT_ID : AzureテナントID AZURE_SUBSCRIPTION_ID : AzureサブスクリプションID AZURE_CLIENT_ID : AzureクライアントID AZURE_CLIENT_SECRET : Azureクライアントシークレット AZURE_OPENAI_ENDPOINT 、 AZURE_OPENAI_API_KEY 、 AZURE_OPENAI_CHAT_DEPLOYMENT は、Azure OpenAI Serviceに接続するための情報となります。これはLLMにFunction Callingを実行させるために必要です。 AZURE_TENANT_ID 、 AZURE_SUBSCRIPTION_ID 、 AZURE_CLIENT_ID 、 AZURE_CLIENT_SECRET は、Azure MCP ServerがAzureリソースにアクセスするための情報となります。これらの値はAzureポータルでアプリケーション登録を行い、サービスプリンシパルを作成することで取得できます。そして、そのサービスプリンシパルに対して必要なAzureリソースへのアクセス権限を付与してください。例えば、ストレージアカウントの情報を取得する場合は、「ストレージ アカウント閲覧者」ロールを付与します。 MAX_STEPS は、AIエージェントが実行する最大ステップ数を指定します。これにより、無限ループを防止できます。もしこれを設定しないと、AIエージェントが過剰に多くのステップを実行し、Azure OpenAI Serviceにすごいい数のリクエストを送ってしまう可能性があります。結果、コストが高額になる恐れがあるため、適切な値を設定してください。 [ステップ3] 依存関係のインストール 次に、必要なPythonパッケージをインストールします。以下のコマンドを実行してください。 $ pip install -r requirements.txt [ステップ4] アプリケーションの起動 ブラウザで http://localhost:8501 にアクセスし、Azureリソースに対する操作指示を入力してみてください。例えば、「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」と入力すると、アプリケーションがAzure MCP Serverと連携して情報を取得し、結果を表示します。 まとめ いかがでしょうか。Webブラウザから対話的にAzureリソースを操作できるのは非常に便利です。Azure MCP ServerとStreamlitを組み合わせることで、ユーザーにとって使いやすいインターフェースを提供できます。こんな感じで今後も、Azureの様々なサービスと連携したWebアプリケーションを構築していきたいと思います。ぜひ皆さんも試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Azure MCP ServerとStreamlitでAzureを対話的に操作するWebアプリ first appeared on SIOS Tech. Lab .
はじめに ども!最近またですね、新しい検証を進めるために環境構築をつらつらとやっている龍ちゃんです。AI開発をスムーズに進めるための環境構築を検証しているんですが、今回は uvのワークスペース機能 を使ったモノレポ環境について共有します。 前回の記事「 uv + Ruff + mypyで構築する超軽量Python開発環境 」では、単一プロジェクトでの開発環境最適化を紹介しました。今回は、その延長として 複数プロジェクトを1つのリポジトリで管理するモノレポ環境 を構築していきます。 この記事でわかること Pythonでモノレポを管理するのは大変ですよね。requirements.txtの手動管理、複数venvの環境切り替え、AI開発ツールとの相性…。 この記事では、 uvワークスペース を使って、これらの課題を「まるっと解決」する方法を紹介します。Node.jsのpackage.jsonのような自動管理が、Pythonでも実現できます。 この記事の流れ 従来のアプローチの課題 uvワークスペースによる解決 実装ガイド(10分で構築) 実際のプロジェクト例(GA4分析プロジェクト) **注** : 本記事ではuvワークスペースを紹介しますが、Poetry、PDM、 Hatchなどでも同様のモノレポ環境を構築できます。プロジェクトの 状況(既存ツール、チームの慣れ、安定性要件など)に応じて 適切なツールを選択してください。uvは2024年登場の新しいツールで、 特に速度を重視する新規プロジェクトに適しています。 pip + requirements.txt の根本的な問題 Pythonの依存関係管理で、こんな経験はありませんか? # パッケージをインストールしても... pip install flask # → requirements.txt は更新されない! # → 手動で追加するか、pip freeze を使う必要がある これが、PythonとNode.jsの 最大の違い なんですよね。 Node.jsとの比較 項目 pip + requirements.txt npm + package.json パッケージ追加 pip install X → 手動でファイル編集が必要 npm install X → 自動でファイル更新 パッケージ削除 pip uninstall X → 手動でファイル編集が必要 npm uninstall X → 自動でファイル更新 直接依存 vs 間接依存 区別困難( pip freeze で混在) 明確に分離 pip freeze の問題 pip freeze を使うと、直接依存と間接依存が混在して出力されます。 # pip freeze の出力 flask==3.0.0 click==8.1.0 # ← これは直接依存?間接依存? Jinja2==3.1.0 # ← これは直接依存?間接依存? Werkzeug==3.0.0 # ← これは直接依存?間接依存? MarkupSafe==2.1.0 # ← Jinja2が依存(間接依存の間接依存!) 問題点 : どれが直接依存で、どれが間接依存か判別できない パッケージを削除する時に「これは本当に削除して大丈夫?」と悩む requirements.txt が肥大化する モノレポでの2つのパターンとその課題 Pythonでモノレポを作るとき、これまで主に2つのパターンを試してきました。 パターン1: 各プロジェクトに個別venv monorepo/ ├── project-a/ │ ├── .venv/ # project-a専用の仮想環境 │ ├── requirements.txt │ └── src/ ├── project-b/ │ ├── .venv/ # project-b専用の仮想環境 │ ├── requirements.txt │ └── src/ └── project-c/ ├── .venv/ # project-c専用の仮想環境 ├── requirements.txt └── src/ メリット : 各プロジェクトの依存関係が完全に分離 プロジェクト間でバージョン競合が発生しない デメリット : IDE設定が煩雑(環境切り替えが必要) 共通依存関係(pandas など)が各 .venv に重複インストール VSCodeのインタープリター設定を頻繁に変更する必要がある VSCodeワークスペース(.code-workspace)でも解決しない問題 VSCodeには複数のフォルダを1つのワークスペースとして管理する機能があります。 // monorepo.code-workspace { "folders": [ { "path": "project-a" }, { "path": "project-b" }, { "path": "project-c" } ], "settings": { "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python" } } これで各プロジェクトが独立した設定を持てるんですが、 AI開発の観点では問題 があります。 AI開発ツール(Claude Code など)の視点で不利な理由 : AIは1つのVSCodeウィンドウ全体をコンテキストとして理解する フォルダ間の関係性を把握しにくい 「project-aのコードを参考にproject-bを修正して」といった指示が通りにくい 私の場合、Claude Codeを使って開発することが多いので、この点は結構重要でした。 パターン2: ルートに大きなvenv monorepo/ ├── .venv/ # 全プロジェクトの依存関係を含む ├── requirements.txt # 全プロジェクトの依存関係を手動管理 ├── project-a/ │ └── src/ ├── project-b/ │ └── src/ └── project-c/ └── src/ メリット : IDE設定が簡単(1つのvenvを指定するだけ) 共通依存関係の重複インストールがない デメリット : requirements.txtの手動管理が確実に必要 どのパッケージがどこで使われているか不明瞭 バージョン競合が発生しやすい パッケージ削除時の影響範囲が不明 例(ルートrequirements.txtの肥大化) : # monorepo/requirements.txt # project-a の依存関係 flask==3.0.0 pandas==2.2.0 # project-b の依存関係 django==5.0.0 pandas==2.2.0 # ← project-aと重複 # project-c の依存関係 fastapi==0.115.0 pandas==2.1.0 # ← バージョン競合!どちらを選ぶ? # これらは直接依存?間接依存?誰が使っている? click==8.1.0 jinja2==3.1.0 sqlalchemy==2.0.0 ...(100行以上続く) 問題点 : どのパッケージがどのプロジェクトで使われているか追跡困難 パッケージを削除する時に「本当に削除して大丈夫か」判断できない バージョン競合を手動で解決する必要がある 私も最初はこのパターンで試していたんですが、requirements.txtの管理が煩雑で、結構な時間のロスをしました。 package.jsonライクな自動管理 uvを使うと、Node.jsのpackage.jsonのような 自動管理 が実現できます。 uvの動作 # npm の場合 npm install express # → package.json が自動更新される! # uv の場合 uv add flask # → pyproject.toml が自動更新される! これは想像以上に効果的でした。特に複数プロジェクトを管理する場合、手動でrequirements.txtを編集する手間がなくなるだけで、開発体験が大きく変わります。 重要な3つの特徴 自動更新される依存関係ファイル uv add すると pyproject.toml が自動で更新される pip のように手動で requirements.txt を編集する必要がない 直接依存と間接依存の分離 pyproject.toml : 直接依存のみ(読みやすい、package.json と同じ) uv.lock : 全依存関係をロック(再現性、package-lock.json と同じ) ロックファイルによる再現性 uv.lock で全環境で同じバージョンを保証 バージョン競合を自動解決 単一venv + ワークスペース管理 uvワークスペースを使うと、 パターン2の利点(単一venv) と パターン1の利点(明確な依存関係) を両立できます。 uvワークスペースの構成 sios-tech-lab-analytics-ga4/ ├── .venv/ ← 単一の仮想環境(全ワークスペース共有) ├── uv.lock ← 統合ロックファイル ├── pyproject.toml ← ルート設定 └── application/ ├── batch/ │ ├── pyproject.toml ← バッチの依存関係(自動管理) │ └── src/ ├── frontend/ │ ├── pyproject.toml ← フロントエンドの依存関係(自動管理) │ └── app.py └── scraper/ ├── pyproject.toml ← スクレイパーの依存関係(自動管理) └── main.py ポイント : IDE設定が簡単(1つのvenvを指定するだけ) 各ワークスペースの依存関係は pyproject.toml で明確に管理 バージョン競合は uv.lock で自動解決 手動での requirements.txt 編集が不要 モノレポ構成によるAI開発体験の向上 私が実際にClaude Codeを使って開発していて感じたのは、 モノレポ構成そのものがAI開発ツールとの相性が良い ということです。 なぜモノレポがAI開発に向いているのか? 1. AIが全プロジェクトのコンテキストを一度に把握できる 従来のアプローチ(複数リポジトリ or 個別venv) : AIはリポジトリごとにコンテキストが分断される 「project-aのコードを参考にproject-bを修正して」という指示が難しい 複数のVSCodeウィンドウを開く必要がある モノレポ構成 : 単一のVSCodeウィンドウで全体を見渡せる プロジェクト間の依存関係や共通コードをAIが理解しやすい 「batchのコードを参考にfrontendを修正して」という自然な指示が通る これは Poetry、PDM、uvなど、どのツールでも共通 するモノレポの利点です。 2. 環境管理のシンプルさ 複数venvの環境では、AIがパッケージをインストールする際に「どのvenvにインストールすべきか」の判断が必要でした。 モノレポで単一venv(または統一された依存管理)を使うと: VSCodeのインタープリター設定は1つだけ 「今どの環境にいるのか」を意識する必要がない AIが想定外の環境にパッケージをインストールするリスクが低い uvワークスペースの追加メリット その上で、uvワークスペースには以下の利点があります: 自動管理による認知負荷の軽減 # uv の場合 uv add --package my-monorepo-batch pandas # → pyproject.toml が自動更新される # Poetry の場合(同様に自動更新) cd application/batch poetry add pandas # pip の場合(手動編集が必要) pip install pandas # → requirements.txt を手動で編集... 依存関係の追加・削除時に、AIに「pyproject.tomlを更新して」と指示する必要がありません。 高速なインストール 開発中に頻繁にパッケージを試すとき、uvの高速さ(pip比10-100倍)は体感できます。 しかし : これらは「AI開発に必須」ではなく、「開発体験を向上させる要素」です。Poetry、PDMでも同等の開発体験を得られます。 AI開発における依存管理ツールの選択 要素 影響度 プロジェクト構造の明確さ 最重要 ドキュメントの充実 最重要 モノレポ構成 重要 一貫性のある命名規則 重要 依存管理ツールの種類 影響は限定的 AIツールは依存管理ツールの種類を気にしません 。重要なのは、論理的なプロジェクト構造と良いドキュメントです。 実際の選択基準 AI開発においても、依存管理ツールの選択は従来の基準で問題ありません: 新規プロジェクト + 速度重視 → uv 既存Poetryプロジェクト → そのまま継続で問題なし チームがPEP準拠を重視 → PDM PyPA公式ツール希望 → Hatch さらに深くAI協業開発を学びたい方へ : モノレポ環境を整えた後、 AI協業開発環境の構築術|モノレポでビルド時間を大幅短縮するCLAUDE.md活用法 も参考にしてみてください。CLAUDE.md階層構造を使って、AIにプロジェクト全体像を理解させる方法を解説しています。 実装ガイド(10分で構築) それでは、実際にuvワークスペースを構築してみましょう。 ステップ1: ルート pyproject.toml の作成 [project] name = "my-monorepo" version = "0.1.0" requires-python = ">=3.12" [dependency-groups] dev = [ "ruff>=0.7.0", "pytest>=8.0.0", "mypy>=1.18.2", ] [tool.uv.workspace] members = ["application/frontend", "application/batch", "application/scraper"] [tool.ruff] line-length = 88 target-version = "py312" [tool.ruff.lint] select = ["E", "W", "F", "I", "N", "UP", "B"] [tool.mypy] python_version = "3.12" warn_return_any = true check_untyped_defs = true ignore_missing_imports = true ポイント : tool.uv.workspace.members で各ワークスペースを定義 ルートには開発ツール(ruff, pytest, mypy)を配置 コード品質設定(Ruff、mypy)は全ワークスペースで共有 ステップ2: 各ワークスペースの pyproject.toml 例: application/batch/pyproject.toml [project] name = "my-monorepo-batch" version = "0.1.0" requires-python = ">=3.12" dependencies = [ "pandas>=2.2.0", "python-dotenv>=1.0.0", ] 例: application/frontend/pyproject.toml [project] name = "my-monorepo-frontend" version = "0.1.0" requires-python = ">=3.12" dependencies = [ "streamlit>=1.40.0", "pandas>=2.2.0", "plotly>=5.24.0", ] ポイント : 各ワークスペースは独立した pyproject.toml を持つ 共通依存関係(pandas など)は uv.lock で自動的に1つのバージョンに統一される ステップ3: 依存関係のインストール # 全ワークスペースの依存関係を同期 uv sync # 特定のワークスペースにパッケージを追加 uv add --package my-monorepo-batch pandas # ルートワークスペースに開発ツールを追加 uv add --dev ruff pytest mypy 重要 : uv sync 1回で全ワークスペースの依存関係がインストールされます。これは、npmの npm install と同じ感覚ですね。 ステップ4: コマンド実行 # 特定のワークスペースのコマンドを実行 uv run --package my-monorepo-batch python application/batch/script.py uv run --package my-monorepo-frontend streamlit run application/frontend/app.py # 開発ツールの実行(ルートワークスペース) uv run ruff format . uv run mypy . uv run pytest 実際のプロジェクト例: GA4分析 私が実際に構築したGA4(Google Analytics 4)分析プロジェクトでの実装例を紹介します。 ワークスペース構成 sios-tech-lab-analytics-ga4/ ├── .venv/ # 単一の仮想環境 ├── uv.lock # 統合ロックファイル(206KB、1306行) ├── pyproject.toml # ルート設定 └── application/ ├── batch/ │ ├── pyproject.toml # GA4データ取得・変換 │ └── script.py ├── frontend/ │ ├── pyproject.toml # Streamlitダッシュボード │ └── app.py └── scraper/ ├── pyproject.toml # ブログデータ収集 └── main.py 各ワークスペースの役割 1. batch: GA4からのデータ取得・変換 # application/batch/pyproject.toml [project] name = "sios-tech-lab-analytics-ga4-batch" dependencies = [ "google-analytics-data>=0.18.0", "pandas>=2.2.0", "python-dotenv>=1.0.0", ] 2. frontend: Streamlitダッシュボード # application/frontend/pyproject.toml [project] name = "sios-tech-lab-analytics-ga4-frontend" dependencies = [ "streamlit>=1.40.0", "pandas>=2.2.0", "plotly>=5.24.0", ] 3. scraper: ブログデータ収集 # application/scraper/pyproject.toml [project] name = "sios-tech-lab-analytics-ga4-scraper" dependencies = [ "requests>=2.32.0", "beautifulsoup4>=4.12.0", "lxml>=5.0.0", "click>=8.1.0", ] [project.scripts] blog-scraper = "sios_tech_lab_analytics_ga4_scraper.main:main" ポイント : エントリポイント( [project.scripts] )を定義することで、 uv run blog-scraper でコマンド実行可能 共通依存関係の扱い pandas>=2.2.0 は batch と frontend で共有されますが、 uv.lock で自動的に1つのバージョン(2.2.1)に統一されます。 これにより、バージョン競合を気にせず開発できます。手動で調整する必要がないので、すごく楽ですね。 DevContainerとの統合 { "name": "Python Dev (uv + Ruff + mypy)", "build": { "dockerfile": "Dockerfile" }, "customizations": { "vscode": { "extensions": ["charliermarsh.ruff", "ms-python.python"], "settings": { "": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true } } } }, "postCreateCommand": "uv sync" } ポイント : postCreateCommand: "uv sync" でコンテナ作成時に全依存関係を自動インストール チーム全員が同じ環境を共有できる まとめ 今回は、uvワークスペースを使ったPythonモノレポ管理の方法を紹介しました。 この環境で得られる4つのメリット package.jsonライクな自動管理 – pip + requirements.txtからの脱却 単一venv + ワークスペース管理 – IDE設定が簡単 AI開発ツールとの相性が抜群 – 全プロジェクトを一度に把握 バージョン競合の自動解決 – 手動調整が不要 Pythonのモノレポ管理が、Node.jsのように快適になります。 次のステップ 今回の記事 : 開発環境での構築(uvワークスペースの基本) 次回の記事 : デプロイ・本番環境への展開 GitHub ActionsでのUV対応 uvからrequirements.txtへの変換 コンテナビルドと本番環境での実行 ぜひ、あなたのプロジェクトでも試してみてください! 質問や感想は、コメント欄でお待ちしております。 参考リンク 公式ドキュメント uv公式ドキュメント – Workspaces uv公式ドキュメント – Projects 関連記事 uv + Ruff + mypyで構築する超軽量Python開発環境 AI協業開発環境の構築術|モノレポでビルド時間を大幅短縮するCLAUDE.md活用法 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post uvで解決!Pythonモノレポの依存関係管理【2025年版】 first appeared on SIOS Tech. Lab .

動画

書籍