0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

API作り

Last updated at Posted at 2025-05-03

まとめ未完了 ドキュメ(今日中にやる)

これから触りたいAPI

OpenWeatherMap	天気情報	今日の天気を表示
🐶 Dog API	犬の画像を取得できる	クリックでランダム犬画像
🧠 Advice Slip	ランダムな名言助言	元気が出る一言アプリ
📦 JSONPlaceholder	仮データで練習できる	投稿一覧/新規投稿などのCRUD練習に最適
📅 Holidays API	祝日一覧	カレンダーと組み合わせて使える

ワシが作りたいAPI アイデア

 投稿PDF出力	Flask + HTML + pdfkit	
 Ajaxで通知	Ajax + 通知テーブル + .append()	PDF作ったよ 通知
 Notion APIでメモ取得	                        	.append()で表示
 LINE Messaging API連携	FlaskでWebhook受信送信	こんにちはで返信させる
 Outlook APIでメール取得	MS Graph API + OAuth認証	メール一覧 Ajaxで表示
 メールPDF化企業名抽出	pdfkit + reやspaCy	PDF生成して正規表現で企業名抽出CSV保存

#restful APIとは
フロントをVue/ Ajax /スマホアプリにしたい or チーム開発でフロントとバックをわけたい時に便利。
Restful APIの仕組みは、JSONデータを受け取る +受け取ったJsondataの整形。
JsonをSQLAcademyやDBからとってきて加工するには、
必ずMAshmaronがいる。

MAshmaron使用例

from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow import fields

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    first_name = db.Column(db.String(100), default=None)
    last_name = db.Column(db.String(100), default=None)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)

    class UserSchema(ma.SQLAlchemySchema):  
    class Meta:
        model = User
        load_instance = True

    id = ma.auto_field()
    name = ma.auto_field()
    email = ma.auto_field()
    is_active = ma.auto_field()
    first_name = ma.auto_field()
    last_name = ma.auto_field()
    created_at = fields.DateTime(format='%Y-%m-%dT%H:%M:%S+09:00')
    updated_at = fields.DateTime(format='%Y-%m-%dT%H:%M:%S+09:00')
    full_name = fields.Method("get_full_name")

    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}"

   
   ###出力結果
   {
  "status": "ok",
  "users": [
    {
      "id": 1,
      "full_name": "yuto matsuki",
      "created_at": "2017-08-19T19:50:39+00:00",
      "updated_at": "2017-08-19T19:50:39+00:00"
    },
    {
      ...
    }
    ...
  ]
}

 ### marshmallowでModelSchemaを定義
 class UserSchema(ma.SQLAlchemySchema):  
    class Meta:
        model = User
        load_instance = True

    id = ma.auto_field()
    name = ma.auto_field()
    email = ma.auto_field()
    is_active = ma.auto_field()
    first_name = ma.auto_field()
    last_name = ma.auto_field()
    created_at = fields.DateTime(format='%Y-%m-%dT%H:%M:%S+09:00')
    updated_at = fields.DateTime(format='%Y-%m-%dT%H:%M:%S+09:00')
    full_name = fields.Method("get_full_name")


    Schemaは1ユーザー1
複数形  guest_list  guests複数人全体の一覧  Schemaには入れない

引用元: https://techblog.recochoku.jp/3107

おすすめギッハブ

参考サイト(初心者向け)


### API作り基本(Restful API)

```ruby:
# データ取得 (GET) + .get
users = {
    1: {"name": "John", "birthdate": "1990-01-01"},
    2: {"name": "Jane", "birthdate": "1995-05-05"}
}

@app.route('/api/user/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = users.get(user_id)
    if user:
        return jsonify(user)  # ユーザー情報をJSONで返す
    return jsonify({"message": "User not found"}), 404

# 新規作成 (post)
users = {}

@app.route('/api/user', methods=['POST'])
def add_user():
    user_data = request.get_json()  # JSONデータを取得
    user_id = len(users) + 1  # ユーザーID自動生成
    users[user_id] = user_data
    return jsonify({"message": "User added", "user_id": user_id}), 201

# 更新 (PUT) + .update

users = {1: {"name": "John", "birthdate": "1990-01-01"}}

@app.route('/api/user/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    if user_id in users:
        user_data = request.get_json()  # 更新するデータを取得
        users[user_id].update(user_data)  # ユーザー情報を更新
        return jsonify({"message": "User updated"}), 200
    return jsonify({"message": "User not found"}), 404


# 削除(DELETE) + del [消したいもの]
users = {1: {"name": "John", "birthdate": "1990-01-01"}}

@app.route('/api/user/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    if user_id in users:
        del users[user_id]  # ユーザー削除
        return jsonify({"message": "User deleted"}), 200
    return jsonify({"message": "User not found"}), 404

複数人をリストに追加 samplecode

from flask import Flask
from flask_restful import Resource, Api, reqparse

app = Flask(__name__)
api = Api(app)

guest_list = ['Akansh', 'Bill Gates', 'Elon Musk']

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, help='Name of guest')


class GuestList(Resource):
    def get(self):
        return {'guests': guest_list}, 200


class GuestById(Resource):
    def get(self, id):
        if id < 0 or id >= len(guest_list):
            return {'error': 'Guest not found'}, 404
        return {'name': guest_list[id]}, 200

    def put(self, id):
        args = parser.parse_args()
        name = args['name']
        if id < 0 or id >= len(guest_list):
            return {'error': 'Guest not found'}, 404
        guest_list[id] = name
        return {'message': 'Updated', 'guests': guest_list}, 200

    def delete(self, id):
        if id < 0 or id >= len(guest_list):
            return {'error': 'Guest not found'}, 404
        deleted_name = guest_list.pop(id)
        return {'message': f'{deleted_name} deleted', 'guests': guest_list}, 200


class GuestAdd(Resource):

    def post(self):
        args = parser.parse_args()
        name = args['name']
        guest_list.append(name)
        return {'message': 'Added', 'guests': guest_list}, 201


api.add_resource(GuestList, '/guests')
api.add_resource(GuestById, '/guest/<int:id>')
api.add_resource(GuestAdd, '/guest')

Comment → Post → User  スキーマ

schema
from flask_marshmallow import Marshmallow
from marshmallow import fields

ma = Marshmallow()

class UserSchema(ma.SQLAlchemySchema):
    class Meta:
        model = User
        load_instance = True

    id = ma.auto_field()
    username = ma.auto_field()

class PostSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Post
        load_instance = True

    id = ma.auto_field()
    content = ma.auto_field()
    user = ma.Nested(UserSchema)  # ← Post の中に User を入れる!

class CommentSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Comment
        load_instance = True

    id = ma.auto_field()
    text = ma.auto_field()
    post = ma.Nested(PostSchema)  # ← Comment の中に Post(→ さらに User)を入れる!

model
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

db = SQLAlchemy()
ma = Marshmallow()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    user = db.relationship('User', backref='posts')

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
    post = db.relationship('Post', backref='comments')
json
{
  "id": 1,
  "text": "Nice post!",
  "post": {
    "id": 10,
    "content": "Flaskは楽しい!",
    "user": {
      "id": 5,
      "username": "YamadaTarou"
    }
  }
}


### json出力例
CommentSchema().dump(comment_obj) 

リレーションを含める ma.Nested(他のSchema)

複数データをまとめて表示(リスト表示)

全コメント一覧」を取得したい
comments = Comment.query.all()
CommentSchema(many=True).dump(comments)

class UserSchema(ma.SQLAlchemySchema):
    class Meta:
        model = User
        load_instance = True

    id = ma.auto_field()
    username = ma.auto_field()
    posts = ma.Nested(PostSchema, many=True)

id = fields.Int(dump_only=True) # 出力のみ。入力❌ dump?only = true
password = fields.Str(load_only=True) # 入力だけ。出力には含めない

post = fields.Nested(PostSchema) # Comment スキーマでPostも表示

TypeError: Object of type X is not JSON serializable Nested()がない or many=Trueの付け忘れ
AttributeError: 'dict' object has no attribute load_instance = Trueがないと、dictしか返らない

name = fields.Str(required=True, validate=Length(min=2))

POSTで受け取ったJSONをUserモデルに自動で変換して保存できる : load_instance = True

###IDでゲストを検索し、guest.nameを更新

# PUTリクエストで更新
class GuestUpdate(Resource):
    def put(self):
        # JSONデータを解析
        args = parser.parse_args()
        guest_id = args['id']
        name = args['name']
        
        # IDでゲストを検索して更新
        guest = Guest.query.get(guest_id)
        if guest:
            guest.name = name  # 新しい名前に更新
            db.session.commit()  # 変更をデータベースに保存
            return {'message': 'Guest updated successfully'}
        return {'message': 'Guest not found'}, 404

削除するレコードが存在しない場合、または編集する際に、入力値が不正な場合などを事前にチェック

from marshmallow import ValidationError

# 編集時のバリデーション
class GuestUpdate(Resource):
    def put(self):
        args = parser.parse_args()
        guest_id = args['id']
        name = args['name']
        
        if len(name) < 3:
            raise ValidationError('Name must be at least 3 characters long')
        
        guest = Guest.query.get(guest_id)
        if guest:
            guest.name = name
            db.session.commit()
            return {'message': 'Guest updated successfully'}
        return {'message': 'Guest not found'}, 404

一括削除 argsの中身が複数形に

argsの中身が複数形になる
# 複数ゲスト削除(DELETEリクエスト)
class BatchDelete(Resource):
    def delete(self):
        args = parser.parse_args()
        guest_ids = args['ids']  # 複数のIDをリストで受け取る
        
        for guest_id in guest_ids:
            guest = Guest.query.get(guest_id)
            if guest:
                db.session.delete(guest)
        
        db.session.commit()  # 一括で変更を反映
        return {'message': f'{len(guest_ids)} guests deleted successfully'}

###エラー処理 dataがない以外のエラーも必ずつける

dataなし以外
except Exception as e:
    return {'message': f'Error: {str(e)}'}, 500
全体
guest = Guest.query.get(guest_id)
            if guest:
                # 処理
                return {'message': 'Guest updated successfully'}
            else:
                return {'message': 'Guest not found'}, 404
        except Exception as e:
            return {'message': f'Error: {str(e)}'}, 500

Outlookメール +REstfulAPI

Azure ADでアプリ登録 → OAuth 2.0でアクセストークン取得

ajaxでメールデータ取得
$.ajax({
    type:"GET",
    dataType: "json",
    data:{'name':'Payam'},
    url: "http://mypythonapp-spacepirate.rhcloud.com/hello/",
    data: { name: 'Payam' },
    dataType: "json",
    success: function(data) {
        console.log(data);  // => {key: "Hello World!", q: "Payam"}
    },
    error: function(err) {
        console.error("AJAX Error:", err);
    }
})

# Flaskでこう書く
@app.route('/hello/', methods=['GET'])
def hello_world():
    name = request.args.get('name')
    response = {'key': 'Hello World!', 'q': name}
    return jsonify(response)

mysql接続 

from flask import current_app
from flask_sqlalchemy_session import flask_scoped_session
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session

class WriteEngine:
    def __init__(self):
        username = 'hogehoge'
        password = 'mogemoge'
        hostname = 'localhost'
        dbname   = 'rest'
        charset  = 'utf8mb4'
        url = f'mysql+mysqldb://{username}:{password}@{hostname}/{dbname}?charset={charset}'
        self.engine = create_engine(url, echo=True)

class WriteSession(WriteEngine):
    def __init__(self):
        super().__init__()
        self.session = scoped_session(sessionmaker(bind=self.engine))

セキュリティ対策

セキュリティ対策

https://chatgpt.com/c/6816dfc6-ffc8-8010-86eb-ef079cc666ce

続き

dairy



 Dockerより軽 初心者向. :  Podman Desktop


Heroku : Render  / Fly.io


管理者機能 いる状況
 使うユーザー   (不正利用防止)


 Flaskでレスポンシブ
    HTMLに " <meta name="viewport" content="width=device-width, initial-scale=1.0">"

デザインパターン編 参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?