{"id":43033,"date":"2025-07-29T18:44:53","date_gmt":"2025-07-29T09:44:53","guid":{"rendered":"https:\/\/techgym.jp\/?p=43033"},"modified":"2025-10-18T14:14:11","modified_gmt":"2025-10-18T05:14:11","slug":"python-web-2","status":"publish","type":"post","link":"https:\/\/techgym.jp\/column\/python-web-2\/","title":{"rendered":"Python Web\u5236\u4f5c\u5b8c\u5168\u653b\u7565\u3010Flask\u30fbDjango\u30fbFastAPI\u5fb9\u5e95\u30de\u30b9\u30bf\u30fc\u3011"},"content":{"rendered":"\n<p><iframe loading=\"lazy\" width=\"560\" height=\"314\" src=\"\/\/www.youtube.com\/embed\/7iX9nAJE0cE\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>Python \u306f Web \u958b\u767a\u306b\u304a\u3044\u3066\u975e\u5e38\u306b\u4eba\u6c17\u306e\u9ad8\u3044\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u3067\u3059\u3002Flask\u3001Django\u3001FastAPI \u306a\u3069\u306e\u512a\u79c0\u306a\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306b\u3088\u308a\u3001\u30b7\u30f3\u30d7\u30eb\u306aWeb\u30b5\u30a4\u30c8\u304b\u3089\u5927\u898f\u6a21\u306aWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u307e\u3067\u52b9\u7387\u7684\u306b\u958b\u767a\u3067\u304d\u307e\u3059\u3002\u672c\u8a18\u4e8b\u3067\u306f\u3001Python \u3067\u306e Web\u5236\u4f5c\u3092\u57fa\u672c\u304b\u3089\u5fdc\u7528\u307e\u3067\u3001\u5b9f\u7528\u7684\u306a\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u3068\u3068\u3082\u306b\u5fb9\u5e95\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n<h2>Python Web\u958b\u767a\u306e\u7279\u5fb4<\/h2>\n<h3>Python Web\u958b\u767a\u306e\u5229\u70b9<\/h3>\n<ul>\n<li><strong>\u5b66\u7fd2\u30b3\u30b9\u30c8\u304c\u4f4e\u3044<\/strong>: \u8aad\u307f\u3084\u3059\u3044\u69cb\u6587<\/li>\n<li><strong>\u8c4a\u5bcc\u306a\u30e9\u30a4\u30d6\u30e9\u30ea<\/strong>: \u6a5f\u68b0\u5b66\u7fd2\u3001\u30c7\u30fc\u30bf\u5206\u6790\u3068\u306e\u9023\u643a<\/li>\n<li><strong>\u9ad8\u3044\u751f\u7523\u6027<\/strong>: \u5c11\u306a\u3044\u30b3\u30fc\u30c9\u3067\u6a5f\u80fd\u5b9f\u88c5<\/li>\n<li><strong>\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3<\/strong>: \u5c0f\u898f\u6a21\u304b\u3089\u5927\u898f\u6a21\u307e\u3067\u5bfe\u5fdc<\/li>\n<li><strong>\u6d3b\u767a\u306a\u30b3\u30df\u30e5\u30cb\u30c6\u30a3<\/strong>: \u8c4a\u5bcc\u306a\u60c5\u5831\u3068\u30b5\u30dd\u30fc\u30c8<\/li>\n<\/ul>\n<h3>\u4e3b\u8981\u306aWeb\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af<\/th>\n<th>\u7279\u5fb4<\/th>\n<th>\u9069\u7528\u5834\u9762<\/th>\n<th>\u5b66\u7fd2\u96e3\u6613\u5ea6<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Flask<\/td>\n<td>\u8efd\u91cf\u30fb\u30b7\u30f3\u30d7\u30eb<\/td>\n<td>\u5c0f\u301c\u4e2d\u898f\u6a21\u3001API<\/td>\n<td>\u4f4e<\/td>\n<\/tr>\n<tr>\n<td>Django<\/td>\n<td>\u9ad8\u6a5f\u80fd\u30fb\u591a\u6a5f\u80fd<\/td>\n<td>\u5927\u898f\u6a21\u3001CMS<\/td>\n<td>\u4e2d\u301c\u9ad8<\/td>\n<\/tr>\n<tr>\n<td>FastAPI<\/td>\n<td>\u9ad8\u901f\u30fb\u578b\u5b89\u5168<\/td>\n<td>API\u3001\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9<\/td>\n<td>\u4e2d<\/td>\n<\/tr>\n<tr>\n<td>Tornado<\/td>\n<td>\u975e\u540c\u671f\u30fb\u9ad8\u6027\u80fd<\/td>\n<td>\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u901a\u4fe1<\/td>\n<td>\u9ad8<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>\u74b0\u5883\u69cb\u7bc9<\/h2>\n<h3>\u57fa\u672c\u7684\u306a\u74b0\u5883\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7<\/h3>\n<pre><code class=\"language-bash\"># \u4eee\u60f3\u74b0\u5883\u306e\u4f5c\u6210\npython -m venv web_project\nsource web_project\/bin\/activate  # Windows: web_project\\Scripts\\activate\n\n# \u57fa\u672c\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\npip install flask django fastapi uvicorn requests\n<\/code><\/pre>\n<h3>requirements.txt\u306e\u4f5c\u6210<\/h3>\n<pre><code class=\"language-txt\">Flask==2.3.3\nDjango==4.2.7\nFastAPI==0.104.1\nuvicorn==0.24.0\nrequests==2.31.0\n<\/code><\/pre>\n<h2>Flask\u5165\u9580<\/h2>\n<h3>\u6700\u5c0f\u306eFlask\u30a2\u30d7\u30ea<\/h3>\n<pre><code class=\"language-python\">from flask import Flask\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef hello():\n    return '&lt;h1&gt;Hello, Flask!&lt;\/h1&gt;'\n\n@app.route('\/user\/&lt;name&gt;')\ndef user(name):\n    return f'&lt;h1&gt;Hello, {name}!&lt;\/h1&gt;'\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>HTML\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, render_template\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef index():\n    users = ['Alice', 'Bob', 'Charlie']\n    return render_template('index.html', users=users)\n\n@app.route('\/about')\ndef about():\n    return render_template('about.html', title='About Us')\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>\u30d5\u30a9\u30fc\u30e0\u51e6\u7406<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, render_template, request, redirect, url_for\n\napp = Flask(__name__)\n\n@app.route('\/contact', methods=['GET', 'POST'])\ndef contact():\n    if request.method == 'POST':\n        name = request.form['name']\n        email = request.form['email']\n        message = request.form['message']\n        \n        # \u30c7\u30fc\u30bf\u51e6\u7406\uff08\u4fdd\u5b58\u3001\u30e1\u30fc\u30eb\u9001\u4fe1\u306a\u3069\uff09\n        print(f\"\u304a\u554f\u3044\u5408\u308f\u305b: {name} ({email}) - {message}\")\n        return redirect(url_for('thanks'))\n    \n    return render_template('contact.html')\n\n@app.route('\/thanks')\ndef thanks():\n    return '&lt;h1&gt;\u304a\u554f\u3044\u5408\u308f\u305b\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3057\u305f\uff01&lt;\/h1&gt;'\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h2>Django\u5165\u9580<\/h2>\n<h3>Django\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210<\/h3>\n<pre><code class=\"language-bash\"># \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u4f5c\u6210\ndjango-admin startproject mysite\ncd mysite\n\n# \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4f5c\u6210\npython manage.py startapp blog\n\n# \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u521d\u671f\u5316\npython manage.py migrate\n\n# \u958b\u767a\u30b5\u30fc\u30d0\u30fc\u8d77\u52d5\npython manage.py runserver\n<\/code><\/pre>\n<h3>\u57fa\u672c\u7684\u306aDjango\u30d3\u30e5\u30fc<\/h3>\n<pre><code class=\"language-python\"># blog\/views.py\nfrom django.shortcuts import render\nfrom django.http import HttpResponse\nimport datetime\n\ndef index(request):\n    return HttpResponse('&lt;h1&gt;Welcome to Django!&lt;\/h1&gt;')\n\ndef current_time(request):\n    now = datetime.datetime.now()\n    return HttpResponse(f'&lt;h1&gt;\u73fe\u5728\u6642\u523b: {now}&lt;\/h1&gt;')\n\ndef user_profile(request, user_id):\n    return HttpResponse(f'&lt;h1&gt;\u30e6\u30fc\u30b6\u30fcID: {user_id}&lt;\/h1&gt;')\n<\/code><\/pre>\n<h3>Django\u306eURL\u8a2d\u5b9a<\/h3>\n<pre><code class=\"language-python\"># blog\/urls.py\nfrom django.urls import path\nfrom . import views\n\nurlpatterns = [\n    path('', views.index, name='index'),\n    path('time\/', views.current_time, name='time'),\n    path('user\/&lt;int:user_id&gt;\/', views.user_profile, name='profile'),\n]\n\n# mysite\/urls.py\nfrom django.contrib import admin\nfrom django.urls import path, include\n\nurlpatterns = [\n    path('admin\/', admin.site.urls),\n    path('blog\/', include('blog.urls')),\n]\n<\/code><\/pre>\n<h3>Django\u30e2\u30c7\u30eb<\/h3>\n<pre><code class=\"language-python\"># blog\/models.py\nfrom django.db import models\nfrom django.utils import timezone\n\nclass Post(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    created_at = models.DateTimeField(default=timezone.now)\n    published = models.BooleanField(default=False)\n    \n    def __str__(self):\n        return self.title\n    \n    class Meta:\n        ordering = ['-created_at']\n\n# \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u5b9f\u884c\n# python manage.py makemigrations\n# python manage.py migrate\n<\/code><\/pre>\n<h2>FastAPI\u5165\u9580<\/h2>\n<h3>\u6700\u5c0f\u306eFastAPI\u30a2\u30d7\u30ea<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass User(BaseModel):\n    name: str\n    age: int\n    email: str\n\n@app.get(\"\/\")\ndef read_root():\n    return {\"message\": \"Hello, FastAPI!\"}\n\n@app.get(\"\/users\/{user_id}\")\ndef read_user(user_id: int):\n    return {\"user_id\": user_id, \"name\": f\"User {user_id}\"}\n\n@app.post(\"\/users\/\")\ndef create_user(user: User):\n    return {\"message\": f\"User {user.name} created successfully\"}\n\n# \u5b9f\u884c: uvicorn main:app --reload\n<\/code><\/pre>\n<h3>FastAPI\u3067\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u9023\u643a<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI, Depends, HTTPException\nfrom sqlalchemy import create_engine, Column, Integer, String\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker, Session\n\n# \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\nSQLALCHEMY_DATABASE_URL = \"sqlite:\/\/\/.\/test.db\"\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\n\nclass User(Base):\n    __tablename__ = \"users\"\n    id = Column(Integer, primary_key=True, index=True)\n    name = Column(String, index=True)\n    email = Column(String, unique=True, index=True)\n\nBase.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\ndef get_db():\n    db = SessionLocal()\n    try:\n        yield db\n    finally:\n        db.close()\n\n@app.get(\"\/users\/{user_id}\")\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n    user = db.query(User).filter(User.id == user_id).first()\n    if user is None:\n        raise HTTPException(status_code=404, detail=\"User not found\")\n    return user\n<\/code><\/pre>\n<h2>RESTful API\u958b\u767a<\/h2>\n<h3>Flask\u3067\u30b7\u30f3\u30d7\u30eb\u306aREST API<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, jsonify, request\n\napp = Flask(__name__)\n\n# \u30c0\u30df\u30fc\u30c7\u30fc\u30bf\nusers = [\n    {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},\n    {'id': 2, 'name': 'Bob', 'email': 'bob@example.com'}\n]\n\n@app.route('\/api\/users', methods=['GET'])\ndef get_users():\n    return jsonify(users)\n\n@app.route('\/api\/users\/&lt;int:user_id&gt;', methods=['GET'])\ndef get_user(user_id):\n    user = next((u for u in users if u['id'] == user_id), None)\n    return jsonify(user) if user else ('Not Found', 404)\n\n@app.route('\/api\/users', methods=['POST'])\ndef create_user():\n    data = request.json\n    new_user = {\n        'id': max(u['id'] for u in users) + 1,\n        'name': data['name'],\n        'email': data['email']\n    }\n    users.append(new_user)\n    return jsonify(new_user), 201\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>FastAPI\u3067\u306e\u9ad8\u5ea6\u306aAPI<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI, HTTPException, Depends, status\nfrom pydantic import BaseModel, EmailStr\nfrom typing import List, Optional\nimport jwt\nfrom datetime import datetime, timedelta\n\napp = FastAPI(title=\"Advanced API\", version=\"1.0.0\")\n\nclass UserCreate(BaseModel):\n    name: str\n    email: EmailStr\n    password: str\n\nclass UserResponse(BaseModel):\n    id: int\n    name: str\n    email: str\n    created_at: datetime\n\n# \u30c0\u30df\u30fc\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\nfake_db = []\n\n@app.post(\"\/users\/\", response_model=UserResponse, status_code=status.HTTP_201_CREATED)\ndef create_user(user: UserCreate):\n    new_user = {\n        \"id\": len(fake_db) + 1,\n        \"name\": user.name,\n        \"email\": user.email,\n        \"created_at\": datetime.now()\n    }\n    fake_db.append(new_user)\n    return new_user\n\n@app.get(\"\/users\/\", response_model=List[UserResponse])\ndef list_users(skip: int = 0, limit: int = 10):\n    return fake_db[skip : skip + limit]\n\n@app.get(\"\/users\/{user_id}\", response_model=UserResponse)\ndef get_user(user_id: int):\n    user = next((u for u in fake_db if u[\"id\"] == user_id), None)\n    if not user:\n        raise HTTPException(status_code=404, detail=\"User not found\")\n    return user\n<\/code><\/pre>\n<h2>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u9023\u643a<\/h2>\n<h3>Flask\u3068SQLAlchemy<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, render_template, request, redirect, url_for\nfrom flask_sqlalchemy import SQLAlchemy\n\napp = Flask(__name__)\napp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:\/\/\/blog.db'\napp.config['SECRET_KEY'] = 'your-secret-key'\ndb = SQLAlchemy(app)\n\nclass Post(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    title = db.Column(db.String(100), nullable=False)\n    content = db.Column(db.Text, nullable=False)\n    created_at = db.Column(db.DateTime, default=db.func.current_timestamp())\n\n@app.route('\/')\ndef index():\n    posts = Post.query.order_by(Post.created_at.desc()).all()\n    return render_template('index.html', posts=posts)\n\n@app.route('\/create', methods=['GET', 'POST'])\ndef create_post():\n    if request.method == 'POST':\n        post = Post(\n            title=request.form['title'],\n            content=request.form['content']\n        )\n        db.session.add(post)\n        db.session.commit()\n        return redirect(url_for('index'))\n    \n    return render_template('create.html')\n\nwith app.app_context():\n    db.create_all()\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>Django\u306eORM<\/h3>\n<pre><code class=\"language-python\"># blog\/models.py\nfrom django.db import models\n\nclass Category(models.Model):\n    name = models.CharField(max_length=100)\n    created_at = models.DateTimeField(auto_now_add=True)\n\nclass Post(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    category = models.ForeignKey(Category, on_delete=models.CASCADE)\n    created_at = models.DateTimeField(auto_now_add=True)\n    updated_at = models.DateTimeField(auto_now=True)\n\n# blog\/views.py\nfrom django.shortcuts import render, get_object_or_404\nfrom .models import Post, Category\n\ndef post_list(request):\n    posts = Post.objects.select_related('category').order_by('-created_at')\n    return render(request, 'blog\/list.html', {'posts': posts})\n\ndef post_detail(request, post_id):\n    post = get_object_or_404(Post, id=post_id)\n    return render(request, 'blog\/detail.html', {'post': post})\n<\/code><\/pre>\n<h2>\u8a8d\u8a3c\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3<\/h2>\n<h3>Flask-Login\u3067\u306e\u8a8d\u8a3c<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, render_template, request, redirect, url_for, flash\nfrom flask_login import LoginManager, UserMixin, login_user, logout_user, login_required\nfrom werkzeug.security import generate_password_hash, check_password_hash\n\napp = Flask(__name__)\napp.secret_key = 'your-secret-key'\n\nlogin_manager = LoginManager()\nlogin_manager.init_app(app)\nlogin_manager.login_view = 'login'\n\nclass User(UserMixin):\n    def __init__(self, id, username, password_hash):\n        self.id = id\n        self.username = username\n        self.password_hash = password_hash\n\n# \u30c0\u30df\u30fc\u30e6\u30fc\u30b6\u30fc\u30c7\u30fc\u30bf\nusers = {\n    'admin': User('1', 'admin', generate_password_hash('password'))\n}\n\n@login_manager.user_loader\ndef load_user(user_id):\n    return next((u for u in users.values() if u.id == user_id), None)\n\n@app.route('\/login', methods=['GET', 'POST'])\ndef login():\n    if request.method == 'POST':\n        username = request.form['username']\n        password = request.form['password']\n        \n        user = users.get(username)\n        if user and check_password_hash(user.password_hash, password):\n            login_user(user)\n            return redirect(url_for('dashboard'))\n        else:\n            flash('\u30ed\u30b0\u30a4\u30f3\u5931\u6557')\n    \n    return render_template('login.html')\n\n@app.route('\/dashboard')\n@login_required\ndef dashboard():\n    return '&lt;h1&gt;\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\uff08\u30ed\u30b0\u30a4\u30f3\u6e08\u307f\uff09&lt;\/h1&gt;'\n\n@app.route('\/logout')\n@login_required\ndef logout():\n    logout_user()\n    return redirect(url_for('login'))\n<\/code><\/pre>\n<h3>FastAPI\u3067\u306eJWT\u8a8d\u8a3c<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI, Depends, HTTPException, status\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom pydantic import BaseModel\nimport jwt\nfrom datetime import datetime, timedelta\nfrom passlib.context import CryptContext\n\napp = FastAPI()\nsecurity = HTTPBearer()\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n\nSECRET_KEY = \"your-secret-key\"\nALGORITHM = \"HS256\"\n\nclass UserLogin(BaseModel):\n    username: str\n    password: str\n\nclass Token(BaseModel):\n    access_token: str\n    token_type: str\n\ndef create_access_token(data: dict):\n    to_encode = data.copy()\n    expire = datetime.utcnow() + timedelta(hours=24)\n    to_encode.update({\"exp\": expire})\n    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n\ndef verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):\n    try:\n        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])\n        username = payload.get(\"sub\")\n        if username is None:\n            raise HTTPException(status_code=401, detail=\"Invalid token\")\n        return username\n    except jwt.PyJWTError:\n        raise HTTPException(status_code=401, detail=\"Invalid token\")\n\n@app.post(\"\/login\", response_model=Token)\ndef login(user: UserLogin):\n    # \u30c0\u30df\u30fc\u8a8d\u8a3c\uff08\u5b9f\u969b\u306f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3067\u78ba\u8a8d\uff09\n    if user.username == \"admin\" and user.password == \"password\":\n        access_token = create_access_token(data={\"sub\": user.username})\n        return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n    raise HTTPException(status_code=401, detail=\"Incorrect credentials\")\n\n@app.get(\"\/protected\")\ndef protected_route(username: str = Depends(verify_token)):\n    return {\"message\": f\"Hello, {username}! This is a protected route.\"}\n<\/code><\/pre>\n<h2>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u9023\u643a<\/h2>\n<h3>Flask + Ajax<\/h3>\n<pre><code class=\"language-python\">from flask import Flask, render_template, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef index():\n    return render_template('ajax_demo.html')\n\n@app.route('\/api\/search', methods=['POST'])\ndef search():\n    query = request.json.get('query', '')\n    # \u691c\u7d22\u51e6\u7406\uff08\u30c0\u30df\u30fc\uff09\n    results = [f\"\u7d50\u679c{i}: {query}\" for i in range(1, 4)]\n    return jsonify({'results': results})\n\n@app.route('\/api\/users\/&lt;int:user_id&gt;')\ndef get_user_api(user_id):\n    # \u30c0\u30df\u30fc\u30e6\u30fc\u30b6\u30fc\u30c7\u30fc\u30bf\n    user = {'id': user_id, 'name': f'User {user_id}', 'email': f'user{user_id}@example.com'}\n    return jsonify(user)\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>FastAPI\u3067\u306eCORS\u8a2d\u5b9a<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n# CORS\u8a2d\u5b9a\napp.add_middleware(\n    CORSMiddleware,\n    allow_origins=[\"http:\/\/localhost:3000\"],  # React\u958b\u767a\u30b5\u30fc\u30d0\u30fc\u306a\u3069\n    allow_credentials=True,\n    allow_methods=[\"*\"],\n    allow_headers=[\"*\"],\n)\n\nclass Item(BaseModel):\n    name: str\n    price: float\n\n@app.get(\"\/api\/items\")\ndef get_items():\n    return [\n        {\"id\": 1, \"name\": \"\u5546\u54c1A\", \"price\": 1000},\n        {\"id\": 2, \"name\": \"\u5546\u54c1B\", \"price\": 2000}\n    ]\n\n@app.post(\"\/api\/items\")\ndef create_item(item: Item):\n    return {\"message\": f\"\u5546\u54c1 '{item.name}' \u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\", \"item\": item}\n<\/code><\/pre>\n<h2>\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8<\/h2>\n<h3>Heroku\u3078\u306e\u30c7\u30d7\u30ed\u30a4<\/h3>\n<pre><code class=\"language-python\"># Procfile\nweb: gunicorn app:app\n\n# requirements.txt\nFlask==2.3.3\ngunicorn==21.2.0\n\n# runtime.txt\npython-3.11.6\n<\/code><\/pre>\n<pre><code class=\"language-python\"># app.py (Heroku\u5bfe\u5fdc)\nimport os\nfrom flask import Flask\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef hello():\n    return '&lt;h1&gt;Hello, Heroku!&lt;\/h1&gt;'\n\nif __name__ == '__main__':\n    port = int(os.environ.get('PORT', 5000))\n    app.run(host='0.0.0.0', port=port)\n<\/code><\/pre>\n<h3>Docker\u3067\u306e\u30b3\u30f3\u30c6\u30ca\u5316<\/h3>\n<pre><code class=\"language-dockerfile\"># Dockerfile\nFROM python:3.11-slim\n\nWORKDIR \/app\n\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\nCOPY . .\n\nEXPOSE 8000\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n<\/code><\/pre>\n<pre><code class=\"language-yaml\"># docker-compose.yml\nversion: '3.8'\n\nservices:\n  web:\n    build: .\n    ports:\n      - \"8000:8000\"\n    environment:\n      - DATABASE_URL=postgresql:\/\/user:password@db:5432\/mydb\n    depends_on:\n      - db\n  \n  db:\n    image: postgres:13\n    environment:\n      POSTGRES_DB: mydb\n      POSTGRES_USER: user\n      POSTGRES_PASSWORD: password\n    volumes:\n      - postgres_data:\/var\/lib\/postgresql\/data\n\nvolumes:\n  postgres_data:\n<\/code><\/pre>\n<h2>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/h2>\n<h3>\u30ad\u30e3\u30c3\u30b7\u30f3\u30b0<\/h3>\n<pre><code class=\"language-python\">from flask import Flask\nfrom flask_caching import Cache\n\napp = Flask(__name__)\napp.config['CACHE_TYPE'] = 'simple'\ncache = Cache(app)\n\n@app.route('\/expensive-operation')\n@cache.cached(timeout=300)  # 5\u5206\u9593\u30ad\u30e3\u30c3\u30b7\u30e5\ndef expensive_operation():\n    # \u91cd\u3044\u51e6\u7406\u306e\u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\n    import time\n    time.sleep(2)\n    return {'result': 'heavy computation completed'}\n\n@app.route('\/user\/&lt;int:user_id&gt;')\n@cache.cached(timeout=60, key_prefix='user')\ndef get_user(user_id):\n    # \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u306e\u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\n    return {'user_id': user_id, 'name': f'User {user_id}'}\n\nif __name__ == '__main__':\n    app.run(debug=True)\n<\/code><\/pre>\n<h3>\u975e\u540c\u671f\u51e6\u7406\u3068WebSocket<\/h3>\n<pre><code class=\"language-python\">from fastapi import FastAPI, WebSocket\nimport asyncio\nimport json\n\napp = FastAPI()\n\nclass ConnectionManager:\n    def __init__(self):\n        self.active_connections: list[WebSocket] = []\n    \n    async def connect(self, websocket: WebSocket):\n        await websocket.accept()\n        self.active_connections.append(websocket)\n    \n    def disconnect(self, websocket: WebSocket):\n        self.active_connections.remove(websocket)\n    \n    async def broadcast(self, message: str):\n        for connection in self.active_connections:\n            await connection.send_text(message)\n\nmanager = ConnectionManager()\n\n@app.websocket(\"\/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n    await manager.connect(websocket)\n    try:\n        while True:\n            data = await websocket.receive_text()\n            await manager.broadcast(f\"\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8: {data}\")\n    except Exception:\n        manager.disconnect(websocket)\n\n@app.get(\"\/\")\ndef index():\n    return {\"message\": \"WebSocket server running\"}\n<\/code><\/pre>\n<h2>\u30c6\u30b9\u30c8\u3068\u30c7\u30d0\u30c3\u30b0<\/h2>\n<h3>Flask\u30a2\u30d7\u30ea\u306e\u30c6\u30b9\u30c8<\/h3>\n<pre><code class=\"language-python\">import pytest\nfrom app import app\n\n@pytest.fixture\ndef client():\n    app.config['TESTING'] = True\n    with app.test_client() as client:\n        yield client\n\ndef test_index(client):\n    response = client.get('\/')\n    assert response.status_code == 200\n    assert b'Hello' in response.data\n\ndef test_api_users(client):\n    response = client.get('\/api\/users')\n    assert response.status_code == 200\n    data = response.get_json()\n    assert isinstance(data, list)\n\ndef test_create_user(client):\n    response = client.post('\/api\/users', \n                          json={'name': 'Test User', 'email': 'test@example.com'})\n    assert response.status_code == 201\n<\/code><\/pre>\n<h3>FastAPI\u306e\u30c6\u30b9\u30c8<\/h3>\n<pre><code class=\"language-python\">from fastapi.testclient import TestClient\nfrom main import app\n\nclient = TestClient(app)\n\ndef test_read_main():\n    response = client.get(\"\/\")\n    assert response.status_code == 200\n    assert response.json() == {\"message\": \"Hello, FastAPI!\"}\n\ndef test_create_user():\n    response = client.post(\"\/users\/\", \n                          json={\"name\": \"Test\", \"age\": 25, \"email\": \"test@example.com\"})\n    assert response.status_code == 200\n    assert response.json()[\"message\"] == \"User Test created successfully\"\n<\/code><\/pre>\n<h2>\u307e\u3068\u3081<\/h2>\n<p>Python \u3067\u306e Web \u5236\u4f5c\u306f\u3001\u7528\u9014\u306b\u5fdc\u3058\u3066\u9069\u5207\u306a\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u3067\u52b9\u7387\u7684\u306a\u958b\u767a\u304c\u53ef\u80fd\u3067\u3059\u3002\u5404\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u7279\u5fb4\u3092\u7406\u89e3\u3057\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8981\u4ef6\u306b\u6700\u9069\u306a\u6280\u8853\u9078\u629e\u3092\u884c\u3046\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n<p><strong>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u9078\u629e\u306e\u6307\u91dd\uff1a<\/strong><\/p>\n<ul>\n<li><strong>Flask<\/strong>: \u5c0f\u898f\u6a21\u3001\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u6027\u91cd\u8996\u3001\u5b66\u7fd2\u76ee\u7684<\/li>\n<li><strong>Django<\/strong>: \u5927\u898f\u6a21\u3001\u77ed\u671f\u958b\u767a\u3001CMS\u30fb\u7ba1\u7406\u753b\u9762<\/li>\n<li><strong>FastAPI<\/strong>: API\u958b\u767a\u3001\u9ad8\u6027\u80fd\u3001\u578b\u5b89\u5168\u6027<\/li>\n<\/ul>\n<p><strong>\u91cd\u8981\u306a\u6280\u8853\u8981\u7d20\uff1a<\/strong><\/p>\n<ul>\n<li><strong>\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/strong>: URL\u3068\u30d3\u30e5\u30fc\u306e\u95a2\u9023\u4ed8\u3051<\/li>\n<li><strong>\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8<\/strong>: HTML\u306e\u52d5\u7684\u751f\u6210<\/li>\n<li><strong>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9<\/strong>: ORM \u3092\u4f7f\u3063\u305f\u52b9\u7387\u7684\u306a\u30c7\u30fc\u30bf\u64cd\u4f5c<\/li>\n<li><strong>\u8a8d\u8a3c\u30fb\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3<\/strong>: \u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\u3068\u4fdd\u8b77<\/li>\n<li><strong>API\u8a2d\u8a08<\/strong>: RESTful \u307e\u305f\u306f GraphQL<\/li>\n<li><strong>\u30c7\u30d7\u30ed\u30a4<\/strong>: \u30af\u30e9\u30a6\u30c9\u30b5\u30fc\u30d3\u30b9\u3084\u30b3\u30f3\u30c6\u30ca\u6280\u8853<\/li>\n<\/ul>\n<p><strong>\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/strong><\/p>\n<ul>\n<li>\u4eee\u60f3\u74b0\u5883\u3067\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u7ba1\u7406<\/li>\n<li>\u74b0\u5883\u5909\u6570\u3067\u306e\u8a2d\u5b9a\u7ba1\u7406<\/li>\n<li>\u9069\u5207\u306a\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/li>\n<li>\u30c6\u30b9\u30c8\u30b3\u30fc\u30c9\u306e\u4f5c\u6210<\/li>\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u306e\u5b9f\u88c5<\/li>\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/li>\n<\/ul>\n<p>\u672c\u8a18\u4e8b\u306e\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u3092\u53c2\u8003\u306b\u3001\u3042\u306a\u305f\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u6700\u9069\u306a Web \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u958b\u767a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u7d99\u7d9a\u7684\u306a\u5b66\u7fd2\u306b\u3088\u308a\u3001\u3088\u308a\u9ad8\u5ea6\u3067\u5b9f\u7528\u7684\u306a Web \u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n<h2>\u53c2\u8003\u6587\u732e<\/h2>\n<ul>\n<li>Flask\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/li>\n<li>Django\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/li>\n<li>FastAPI\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/li>\n<li>Python Web Development with Flask<\/li>\n<li>Two Scoops of Django<\/li>\n<\/ul>\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u25a0<a href=\"https:\/\/amzn.to\/3VxGkpx\">\u3089\u304f\u3089\u304fPython\u587e &#8211; \u8aad\u3080\u3060\u3051\u3067\u30de\u30b9\u30bf\u30fc<\/a><\/h2>\n\n\n\n<p><iframe loading=\"lazy\" width=\"560\" height=\"314\" src=\"\/\/www.youtube.com\/embed\/7iX9nAJE0cE\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n\n\n\n<p>\u25a0\u30d7\u30ed\u30f3\u30d7\u30c8\u3060\u3051\u3067\u30aa\u30ea\u30b8\u30ca\u30eb\u30a2\u30d7\u30ea\u3092\u958b\u767a\u30fb\u516c\u958b\u3057\u3066\u307f\u305f\uff01\uff01<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"FxVxRREZz5\"><a href=\"https:\/\/techgym.jp\/column\/ori-app\/\">\u30d7\u30ed\u30f3\u30d7\u30c8\u3060\u3051\u3067\u30aa\u30ea\u30b8\u30ca\u30eb\u30a2\u30d7\u30ea\u3092\u958b\u767a\u30fb\u516c\u958b\u3057\u3066\u307f\u305f\uff01\uff01<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;\u30d7\u30ed\u30f3\u30d7\u30c8\u3060\u3051\u3067\u30aa\u30ea\u30b8\u30ca\u30eb\u30a2\u30d7\u30ea\u3092\u958b\u767a\u30fb\u516c\u958b\u3057\u3066\u307f\u305f\uff01\uff01&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/column\/ori-app\/embed\/#?secret=4g9JG1Vdac#?secret=FxVxRREZz5\" data-secret=\"FxVxRREZz5\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\u25a0AI\u6642\u4ee3\u306e\u7b2c\u4e00\u6b69\uff01\u300cAI\u99c6\u52d5\u958b\u767a\u30b3\u30fc\u30b9\u300d\u306f\u3058\u3081\u307e\u3057\u305f\uff01<\/p>\n\n\n\n<p>\u30c6\u30c3\u30af\u30b8\u30e0\u6771\u4eac\u672c\u6821\u3067\u5148\u884c\u958b\u59cb\u3002<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"eTf50FCD7a\"><a href=\"https:\/\/techgym.jp\/about\/ai-driven-development\/\">AI\u99c6\u52d5\u958b\u767a\/\u751f\u6210AI\u30a8\u30f3\u30b8\u30cb\u30a2\u30b3\u30fc\u30b9\uff08\u521d\u5fc3\u8005\u5411\u3051\uff09<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;AI\u99c6\u52d5\u958b\u767a\/\u751f\u6210AI\u30a8\u30f3\u30b8\u30cb\u30a2\u30b3\u30fc\u30b9\uff08\u521d\u5fc3\u8005\u5411\u3051\uff09&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/about\/ai-driven-development\/embed\/#?secret=F5Md1hJJiZ#?secret=eTf50FCD7a\" data-secret=\"eTf50FCD7a\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\u25a0\u30c6\u30c3\u30af\u30b8\u30e0\u6771\u4eac\u672c\u6821<\/p>\n\n\n\n<p>\u300c\u6b66\u7530\u587e\u300d\u306e\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u7248\u3068\u3044\u3048\u3070\u300c\u30c6\u30c3\u30af\u30b8\u30e0\u300d\u3002<br>\u8b1b\u7fa9\u52d5\u753b\u306a\u3057\u3001\u6559\u79d1\u66f8\u306a\u3057\u3002\u300c\u9032\u6357\u7ba1\u7406\u3068\u30b3\u30fc\u30c1\u30f3\u30b0\u300d\u3067\u52b9\u7387\u5b66\u7fd2\u3002<br>\u3088\u308a\u65e9\u304f\u3001\u3088\u308a\u5b89\u304f\u3001\u3057\u304b\u3082\u5bfe\u9762\u578b\u306e\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\u3067\u3059\u3002<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"X8m4lKloxm\"><a href=\"https:\/\/techgym.jp\/tokyo\/tokyo_honko\/\">\u30c6\u30c3\u30af\u30b8\u30e0\u6771\u4eac\u672c\u6821<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;\u30c6\u30c3\u30af\u30b8\u30e0\u6771\u4eac\u672c\u6821&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/tokyo\/tokyo_honko\/embed\/#?secret=Z9T5HALkVg#?secret=X8m4lKloxm\" data-secret=\"X8m4lKloxm\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\uff1c\u77ed\u671f\u8b1b\u7fd2\uff1e5\u65e5\u30675\u4e07\u5186\u306e\u300cPython\u30df\u30cb\u30ad\u30e3\u30f3\u30d7\u300d\u958b\u50ac\u4e2d\u3002<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"ZJ1C8UYqnn\"><a href=\"https:\/\/techgym.jp\/event\/nagatacho_camp\/\">\u3010\u6700\u901f\u30fb\u78ba\u5b9f\u3011\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u653b\u7565\u300c\u6c38\u7530\u753aPython\u30df\u30cb\u30ad\u30e3\u30f3\u30d7\u300d\u30105\u65e5\u9593\u30675\u4e07\u5186\u3011<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;\u3010\u6700\u901f\u30fb\u78ba\u5b9f\u3011\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u653b\u7565\u300c\u6c38\u7530\u753aPython\u30df\u30cb\u30ad\u30e3\u30f3\u30d7\u300d\u30105\u65e5\u9593\u30675\u4e07\u5186\u3011&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/event\/nagatacho_camp\/embed\/#?secret=5lY68hBPJj#?secret=ZJ1C8UYqnn\" data-secret=\"ZJ1C8UYqnn\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\uff1c\u67081\u958b\u50ac\uff1e\u653e\u9001\u4f5c\u5bb6\u306b\u3088\u308b\u6620\u50cf\u30c7\u30a3\u30ec\u30af\u30bf\u30fc\u990a\u6210\u8b1b\u5ea7<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"yT8daBFNbI\"><a href=\"https:\/\/techgym.jp\/event\/video_director\/\">\u73fe\u5f79\u653e\u9001\u4f5c\u5bb6\u304c\u6559\u3048\u308b\u52d5\u753b\u8b1b\u5ea7\uff01\u300e\uff24\uff2f\uff27\uff21\u300f<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;\u73fe\u5f79\u653e\u9001\u4f5c\u5bb6\u304c\u6559\u3048\u308b\u52d5\u753b\u8b1b\u5ea7\uff01\u300e\uff24\uff2f\uff27\uff21\u300f&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/event\/video_director\/embed\/#?secret=rKqMjh1lr1#?secret=yT8daBFNbI\" data-secret=\"yT8daBFNbI\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\uff1c\u30aa\u30f3\u30e9\u30a4\u30f3\u7121\u6599\uff1e\u30bc\u30ed\u304b\u3089\u59cb\u3081\u308bPython\u7206\u901f\u8b1b\u5ea7<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"hYNgTL2iEI\"><a href=\"https:\/\/techgym.jp\/tokyo_python\/\">\u3010\u7121\u6599\u30fb\u30aa\u30f3\u30e9\u30a4\u30f3\u3011\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308bPython\u7206\u901f\u8b1b\u5ea7<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;\u3010\u7121\u6599\u30fb\u30aa\u30f3\u30e9\u30a4\u30f3\u3011\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308bPython\u7206\u901f\u8b1b\u5ea7&#8221; &#8212; \u3010\u30c6\u30c3\u30af\u30b8\u30e0\u3011\u683c\u5b89\u30fb\u5bfe\u9762\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\" src=\"https:\/\/techgym.jp\/tokyo_python\/embed\/#?secret=Fh60BpGWuY#?secret=hYNgTL2iEI\" data-secret=\"hYNgTL2iEI\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Python \u306f Web \u958b\u767a\u306b\u304a\u3044\u3066\u975e\u5e38\u306b\u4eba\u6c17\u306e\u9ad8\u3044\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u3067\u3059\u3002Flask\u3001Django\u3001FastAPI \u306a\u3069\u306e\u512a\u79c0\u306a\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306b\u3088\u308a\u3001\u30b7\u30f3\u30d7\u30eb\u306aWeb\u30b5\u30a4\u30c8\u304b\u3089\u5927\u898f\u6a21\u306aWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u307e\u3067\u52b9\u7387\u7684 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":42501,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-43033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-column"],"views":77,"jetpack_featured_media_url":"\/wp-content\/uploads\/2025\/07\/f3403acf5c65aedec0dba821c4c26404.png","jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/posts\/43033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/comments?post=43033"}],"version-history":[{"count":0,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/posts\/43033\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/media\/42501"}],"wp:attachment":[{"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/media?parent=43033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/categories?post=43033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techgym.jp\/wp-json\/wp\/v2\/tags?post=43033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}