Open phonon-py opened 1 month ago
SQLite3に対応するための設定を行います。以下に、SQLite3を使ったFastAPIプロジェクトの例を示します。
pip install fastapi uvicorn sqlalchemy sqlite3
main.pyの作成
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
app = FastAPI()
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Member(Base):
__tablename__ = "members"
id = Column(Integer, primary_key=True, index=True)
felica_id = Column(String(255), unique=True, index=True)
name = Column(String(255))
email = Column(String(255))
Base.metadata.create_all(bind=engine)
class MemberCreate(BaseModel):
felica_id: str
name: str
email: str
@app.post("/members/", response_model=MemberCreate)
def create_member(member: MemberCreate):
db = SessionLocal()
db_member = Member(felica_id=member.felica_id, name=member.name, email=member.email)
db.add(db_member)
try:
db.commit()
db.refresh(db_member)
except:
db.rollback()
raise HTTPException(status_code=400, detail="Felica ID already registered")
finally:
db.close()
return member
@app.get("/members/{felica_id}", response_model=MemberCreate)
def read_member(felica_id: str):
db = SessionLocal()
db_member = db.query(Member).filter(Member.felica_id == felica_id).first()
if db_member is None:
raise HTTPException(status_code=404, detail="Member not found")
return MemberCreate(felica_id=db_member.felica_id, name=db_member.name, email=db_member.email)
サーバーの起動
uvicorn main:app --reload
APIが正しく動作するかをテストするには、http://127.0.0.1:8000/docs
にアクセスし、Swagger UIを使ってエンドポイントを試すことができます。
DATABASE_URL
をSQLite用に設定し、test.db
というデータベースファイルを使用しています。create_engine
の際に、connect_args={"check_same_thread": False}
を指定して、SQLiteが同じスレッド内で複数のコネクションを許可するようにしています。これで、SQLite3を使った会員情報の登録と参照の基本的なAPIが構築できます。質問があればお知らせください。
わかりました。まず、FastAPIとFlaskについて簡単に説明します。
APIってなに?
サッカーのチーム(フレームワーク)
FastAPIもFlaskも、ウェブアプリやAPIを作るために使える強力なツールです。どちらもPythonで書かれていて、それぞれに得意なことがあります。
画面 - html, css api - fastapi db - oracle オンプレミスのサーバーにWebアプリとして構築したい。 Felicaの情報を活用したログアプリ
NFCカードリーダーの情報を読み取る画面があり、その情報をdumpしてAPIを介してDBに情報を追加するWebアプリ 参考URL: https://zenn.dev/3w36zj6/articles/d3894e83cb7423
以下のコードは、Fletを使用して名前を入力してデータベースに保存し、データベース内の名前を表示するビューを追加したものです。
import flet as ft
import requests
def main(page: ft.Page):
page.title = "名前の入力"
def on_submit(e):
name = name_input.value
response = requests.post("http://localhost:8000/submit", json={"name": name})
if response.status_code == 200:
result_text.value = "名前をデータベースに保存しました"
update_names_list()
else:
result_text.value = "エラーが発生しました"
page.update()
def update_names_list():
response = requests.get("http://localhost:8000/names")
if response.status_code == 200:
names = response.json()
names_list.controls = [ft.Text(name["name"]) for name in names]
else:
names_list.controls = [ft.Text("エラーが発生しました")]
page.update()
name_input = ft.TextField(label="氏名")
submit_button = ft.ElevatedButton(text="送信", on_click=on_submit)
result_text = ft.Text()
names_list = ft.Column()
page.add(ft.Column([name_input, submit_button, result_text, ft.Text("データベース内の名前一覧:"), names_list]))
update_names_list()
ft.app(target=main, view=ft.WEB_BROWSER) # Webブラウザで起動
以下にFastAPIのコードを示します。新たにデータベース内の名前を取得するエンドポイントを追加します。
from fastapi import FastAPI
from pydantic import BaseModel
import sqlite3
app = FastAPI()
class Name(BaseModel):
name: str
def init_db():
conn = sqlite3.connect('names.db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS names
(id INTEGER PRIMARY KEY, name TEXT)''')
conn.commit()
conn.close()
@app.post("/submit")
async def submit_name(name: Name):
conn = sqlite3.connect('names.db')
cursor = conn.cursor()
cursor.execute("INSERT INTO names (name) VALUES (?)", (name.name,))
conn.commit()
conn.close()
return {"message": "Name inserted successfully"}
@app.get("/names")
async def get_names():
conn = sqlite3.connect('names.db')
cursor = conn.cursor()
cursor.execute("SELECT name FROM names")
names = [{"name": row[0]} for row in cursor.fetchall()]
conn.close()
return names
init_db()
バックエンドの起動:
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
フロントエンドの起動:
python flet_app.py
これにより、名前をデータベースに保存し、データベース内の名前を表示するWebアプリケーションが実現できます。ユーザーが名前を入力して送信すると、名前がデータベースに保存され、その後データベース内のすべての名前が画面に表示されます。
PDFをPPTXに変換するには、Pythonを使う方法がいくつかあります。以下はその一例です。必要なライブラリとして、pdf2image
とpython-pptx
を使用します。
必要なライブラリのインストール
pip install pdf2image python-pptx
PDFをPPTXに変換するコード
from pdf2image import convert_from_path
from pptx import Presentation
from pptx.util import Inches
import os
def pdf_to_pptx(pdf_path, pptx_path):
# PDFから画像に変換
images = convert_from_path(pdf_path)
# 新しいプレゼンテーションを作成
prs = Presentation()
for i, image in enumerate(images):
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
img_path = f'image_{i}.png'
image.save(img_path, 'PNG')
slide.shapes.add_picture(img_path, Inches(0), Inches(0), height=prs.slide_height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
# 使用例
pdf_path = 'your_pdf_file.pdf'
pptx_path = 'output_presentation.pptx'
pdf_to_pptx(pdf_path, pptx_path)
このコードは、PDFファイルを読み込み、各ページを画像に変換し、それをPPTXファイルの各スライドに追加するものです。変換された画像は一時ファイルとして保存され、プレゼンテーションに追加後に削除されます。
この方法で、PDFの各ページがPPTXの各スライドとして追加されるため、手軽にPDFをPPTXに変換できます。質問や補足があればお知らせください。
環境変数にプロキシ認証を通し、WebDriverをブラウザに適したバージョンで取得するスクリプトの例を以下に示します。この例では、PythonとSeleniumを使用します。プロキシ認証を行うために、環境変数を設定し、その後、WebDriverのセットアップを行います。
まず、必要なライブラリをインストールします。
pip install selenium webdriver-manager
次に、プロキシ認証とWebDriverのセットアップを行うPythonスクリプトを作成します。
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
# プロキシ認証情報
proxy_user = 'your_proxy_username'
proxy_pass = 'your_proxy_password'
proxy_host = 'proxy_host'
proxy_port = 'proxy_port'
# 環境変数にプロキシ情報を設定
os.environ['http_proxy'] = f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}'
os.environ['https_proxy'] = f'https://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}'
# Chromeオプションの設定
chrome_options = Options()
chrome_options.add_argument('--proxy-server=http://%s:%s' % (proxy_host, proxy_port))
# WebDriverの取得とセットアップ
service = ChromeService(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
# Webページのアクセス例
driver.get('http://www.example.com')
print(driver.title)
# WebDriverを終了
driver.quit()
このスクリプトは以下の手順で動作します:
webdriver_manager
ライブラリを使用して、ブラウザに適したバージョンのWebDriverを自動的にインストールします。必要に応じて、ブラウザやWebDriverの設定を変更できます。例えば、Firefoxを使用する場合は、対応するWebDriverとオプションを使用してください。質問やさらなるカスタマイズが必要であればお知らせください。
pathlib
を使用してPDFファイルをPPTXに変換するスクリプトを修正します。以下の例では、pathlib.Path
を使用してファイルパスを管理しています。
from pathlib import Path
from pdf2image import convert_from_path
from pptx import Presentation
from pptx.util import Inches
import os
def pdf_to_pptx(pdf_path, pptx_path):
# パスをPathオブジェクトに変換
pdf_path = Path(pdf_path)
pptx_path = Path(pptx_path)
# PDFから画像に変換
images = convert_from_path(pdf_path)
# 新しいプレゼンテーションを作成
prs = Presentation()
for i, image in enumerate(images):
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
# 一時画像ファイルのパスをPathオブジェクトで管理
img_path = pdf_path.parent / f'image_{i}.png'
image.save(img_path, 'PNG')
slide.shapes.add_picture(str(img_path), Inches(0), Inches(0), height=prs.slide_height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
# 使用例
pdf_path = 'your_pdf_file.pdf'
pptx_path = 'output_presentation.pptx'
pdf_to_pptx(pdf_path, pptx_path)
このスクリプトでは、以下のように変更を行っています:
Path
オブジェクトを使用してファイルパスを管理するように変更。Path
オブジェクトを文字列に変換する際にstr()
を使用。これにより、pathlib
を使ったパス管理が可能になり、コードの可読性と保守性が向上します。
pathlib
とファイルパスの取り扱いに問題がないか確認するために、スクリプトのパス指定部分を慎重に見直しましょう。また、パスが正しく渡されているか確認するためのデバッグメッセージを追加します。
以下は、パスが正しく指定されているか確認するための修正版スクリプトです。
from pathlib import Path
from pdf2image import convert_from_path
from pptx import Presentation
from pptx.util import Inches
import os
def pdf_to_pptx(pdf_path, pptx_path):
# パスをPathオブジェクトに変換
pdf_path = Path(pdf_path)
pptx_path = Path(pptx_path)
# パスが存在するかチェック
if not pdf_path.exists():
print(f"Error: PDF file does not exist at {pdf_path}")
return
# PDFから画像に変換
try:
images = convert_from_path(pdf_path)
except Exception as e:
print(f"Error converting PDF to images: {e}")
return
# 新しいプレゼンテーションを作成
prs = Presentation()
for i, image in enumerate(images):
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
# 一時画像ファイルのパスをPathオブジェクトで管理
img_path = pdf_path.parent / f'image_{i}.png'
image.save(img_path, 'PNG')
slide.shapes.add_picture(str(img_path), Inches(0), Inches(0), height=prs.slide_height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
print(f"PPTX file saved at {pptx_path}")
# 使用例
pdf_path = r'path\to\your_pdf_file.pdf' # パスを適宜変更してください
pptx_path = r'path\to\output_presentation.pptx' # パスを適宜変更してください
pdf_to_pptx(pdf_path, pptx_path)
ここで以下の点を確認してください:
パスの指定: pdf_path
と pptx_path
の値が正しいか確認します。絶対パスを使用する場合は、Path
オブジェクトを使うときも問題なく動作します。
デバッグメッセージ: パスが正しく指定されているか、pdf_path.exists()
でチェックし、存在しない場合はエラーメッセージを出力します。
パスのエスケープシーケンス: パスが正しくエスケープされているか確認するために、r
文字列リテラルを使用します。
上記の修正を試してみてください。正しいパスを指定しても問題が解決しない場合、ファイルシステムやアクセス権限に問題があるかもしれませんので、ファイルの場所とアクセス権限も確認してください。
PyMuPDF
を使用してPDFをPPTXに変換するスクリプトを以下に示します。PyMuPDF
(fitz
としてインポートされます)を使用することで、PDFの各ページを画像に変換し、その画像をPPTXファイルのスライドに追加します。
必要なライブラリをインストールします。
pip install pymupdf python-pptx
次に、PyMuPDF
を使用したスクリプトを作成します。
from pathlib import Path
import fitz # PyMuPDF
from pptx import Presentation
from pptx.util import Inches
import os
def pdf_to_pptx(pdf_path, pptx_path):
# パスをPathオブジェクトに変換
pdf_path = Path(pdf_path)
pptx_path = Path(pptx_path)
# パスが存在するかチェック
if not pdf_path.exists():
print(f"Error: PDF file does not exist at {pdf_path}")
return
# PDFドキュメントを開く
pdf_document = fitz.open(pdf_path)
# 新しいプレゼンテーションを作成
prs = Presentation()
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
pix = page.get_pixmap()
# 一時画像ファイルのパスをPathオブジェクトで管理
img_path = pdf_path.parent / f'image_{page_num}.png'
pix.save(str(img_path))
# プレゼンテーションに画像を追加
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
slide.shapes.add_picture(str(img_path), Inches(0), Inches(0), height=prs.slide_height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
print(f"PPTX file saved at {pptx_path}")
# 使用例
pdf_path = r'path\to\your_pdf_file.pdf' # パスを適宜変更してください
pptx_path = r'path\to\output_presentation.pptx' # パスを適宜変更してください
pdf_to_pptx(pdf_path, pptx_path)
このスクリプトでは、以下の手順でPDFをPPTXに変換します:
Path
オブジェクトを使用してファイルパスを管理。fitz
(PyMuPDF
)を使用してPDFドキュメントを開く。python-pptx
を使用して新しいプレゼンテーションを作成し、各ページの画像をスライドに追加。これにより、PDFの各ページをPPTXファイルの各スライドとして追加することができます。
はい、PDFのページが縦長のレイアウトの場合、それに合わせたPowerPointスライドを作成することが可能です。以下のスクリプトでは、PDFの各ページの縦横比を取得し、PowerPointスライドのサイズをそれに合わせて設定しています。
from pathlib import Path
import fitz # PyMuPDF
from pptx import Presentation
from pptx.util import Inches, Pt
import os
def pdf_to_pptx(pdf_path, pptx_path):
# パスをPathオブジェクトに変換
pdf_path = Path(pdf_path)
pptx_path = Path(pptx_path)
# パスが存在するかチェック
if not pdf_path.exists():
print(f"Error: PDF file does not exist at {pdf_path}")
return
# PDFドキュメントを開く
pdf_document = fitz.open(pdf_path)
# 新しいプレゼンテーションを作成
prs = Presentation()
# プレゼンテーションのデフォルトスライドサイズを設定(初期値)
slide_width, slide_height = prs.slide_width, prs.slide_height
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
pix = page.get_pixmap()
# 一時画像ファイルのパスをPathオブジェクトで管理
img_path = pdf_path.parent / f'image_{page_num}.png'
pix.save(str(img_path))
# PDFページのサイズを取得し、インチに変換(72DPI基準)
pdf_width, pdf_height = page.rect.width, page.rect.height
width, height = Inches(pdf_width / 72.0), Inches(pdf_height / 72.0)
# スライドのサイズをPDFページのサイズに合わせる
prs.slide_width = width
prs.slide_height = height
# プレゼンテーションに画像を追加
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
slide.shapes.add_picture(str(img_path), Pt(0), Pt(0), width=width, height=height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
print(f"PPTX file saved at {pptx_path}")
# 使用例
pdf_path = r'path\to\your_pdf_file.pdf' # パスを適宜変更してください
pptx_path = r'path\to\output_presentation.pptx' # パスを適宜変更してください
pdf_to_pptx(pdf_path, pptx_path)
このスクリプトのポイントは以下の通りです:
page.rect.width
と page.rect.height
を使用してPDFページのサイズをポイント(pt)単位で取得します。1インチは72ポイントに相当するため、72DPI
を基準としてインチに変換します。これにより、PDFの各ページが縦長のレイアウトに合わせたスライドとしてPowerPointに変換されます。スライドのサイズがPDFのページサイズに基づいて動的に設定されるため、PDFのレイアウトがそのまま反映されます。
PDFページの解像度を維持するために、PyMuPDF
のget_pixmap
メソッドで解像度を設定します。これにより、変換された画像が高解像度で出力され、PowerPointスライドに追加される際に元の品質が保たれます。
以下のスクリプトは、PDFページの解像度を維持しながらPowerPointに変換する方法を示しています。
from pathlib import Path
import fitz # PyMuPDF
from pptx import Presentation
from pptx.util import Inches, Pt
import os
def pdf_to_pptx(pdf_path, pptx_path, resolution=300):
# パスをPathオブジェクトに変換
pdf_path = Path(pdf_path)
pptx_path = Path(pptx_path)
# パスが存在するかチェック
if not pdf_path.exists():
print(f"Error: PDF file does not exist at {pdf_path}")
return
# PDFドキュメントを開く
pdf_document = fitz.open(pdf_path)
# 新しいプレゼンテーションを作成
prs = Presentation()
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
# 解像度を指定して画像を取得
zoom = resolution / 72 # 解像度を反映するためのズーム係数
mat = fitz.Matrix(zoom, zoom)
pix = page.get_pixmap(matrix=mat)
# 一時画像ファイルのパスをPathオブジェクトで管理
img_path = pdf_path.parent / f'image_{page_num}.png'
pix.save(str(img_path))
# PDFページのサイズを取得し、インチに変換(72DPI基準)
pdf_width, pdf_height = page.rect.width, page.rect.height
width, height = Inches(pdf_width / 72.0), Inches(pdf_height / 72.0)
# スライドのサイズをPDFページのサイズに合わせる
prs.slide_width = width
prs.slide_height = height
# プレゼンテーションに画像を追加
slide_layout = prs.slide_layouts[5] # 白紙のレイアウト
slide = prs.slides.add_slide(slide_layout)
slide.shapes.add_picture(str(img_path), Pt(0), Pt(0), width=width, height=height)
# 一時画像ファイルを削除
os.remove(img_path)
prs.save(pptx_path)
print(f"PPTX file saved at {pptx_path}")
# 使用例
pdf_path = r'path\to\your_pdf_file.pdf' # パスを適宜変更してください
pptx_path = r'path\to\output_presentation.pptx' # パスを適宜変更してください
pdf_to_pptx(pdf_path, pptx_path)
このスクリプトでは、次のように変更を加えています:
resolution
パラメータで出力画像の解像度を指定します。デフォルトは300DPIです。fitz.Matrix
を使用してズーム係数を計算し、解像度を反映した画像を生成します。これにより、PDFページの解像度を維持しながら、PowerPointスライドに高品質な画像を追加することができます。
cx_Oracleを使ってOracleクライアントを初期化すると、再度初期化しようとした際にエラーが発生することがあります。これは、Oracleクライアントの初期化が一度しかできないためです。
この問題を回避するための方法として、以下のようにtry-exceptブロックを使用して初期化を試み、既に初期化されている場合にはエラーを無視する方法があります:
import cx_Oracle
# Oracleクライアントのパスを指定して初期化
try:
cx_Oracle.init_oracle_client(lib_dir="/path/to/oracle/client")
except cx_Oracle.ProgrammingError as e:
# すでに初期化されている場合のエラーを無視する
if "already initialized" not in str(e):
raise
# ここにスクリプトのメインロジックを記述
この方法では、cx_Oracle.init_oracle_client()
が既に初期化されている場合に発生するエラー(ProgrammingError
)をキャッチし、そのエラーメッセージが「already initialized」を含んでいる場合には無視し、他のエラーの場合には再度raiseするようにしています。
このアプローチにより、スクリプトが複数回実行される場合でも、初期化の重複によるエラーを回避できます。
LANポートを塞ぐことが情報セキュリティの観点で重要な理由はいくつかあります。
不正アクセス防止: 物理的なLANポートはネットワークに直接接続できるため、悪意のある人物が簡単にアクセスできるリスクがあります。未使用のLANポートを塞ぐことで、物理的に不正なデバイスを接続することを防ぎます。
マルウェア感染防止: 悪意のあるデバイスがネットワークに接続されると、マルウェアの拡散が容易になります。LANポートを塞ぐことで、許可されていないデバイスの接続を防ぎ、マルウェアの感染リスクを低減します。
ネットワークセグメンテーション: ネットワークをセグメント化し、アクセス権限を厳格に管理するために、不要なポートを塞ぐことが有効です。これにより、特定のセグメントへの不正アクセスを防ぎます。
資産管理: 使用されているネットワークポートを管理することで、どのデバイスが接続されているかを把握しやすくなります。塞がれていないポートがあると、管理が難しくなり、潜在的なセキュリティリスクが見逃される可能性があります。
ポリシー遵守: 多くの企業や組織では、セキュリティポリシーに基づいて未使用のポートを塞ぐことが義務付けられています。これは、全体的なセキュリティ態勢を維持するための一環です。
これらの理由から、LANポートを塞ぐことはネットワークのセキュリティを強化するための重要な対策とされています。
まずはMySQLでローカル環境にて試してみるのは非常に良いアイデアです。以下に、FastAPIを使ってMySQLデータベースに会員情報の登録と参照を行う基本的な方法を説明します。
環境設定
Pythonと依存関係のインストール
MySQLデータベースの準備 MySQLに以下のようなテーブルを作成します。
FastAPIプロジェクトの作成
main.pyの作成
サーバーの起動
APIのテスト
APIが正しく動作するかをテストするには、
http://127.0.0.1:8000/docs
にアクセスし、Swagger UIを使ってエンドポイントを試すことができます。次のステップ
MySQLでローカル環境で基本的な動作を確認したら、Oracleデータベースを使うように設定を変更することができます。その際は、
sqlalchemy
のOracleドライバであるcx_Oracle
を使って、接続文字列をOracle用に変更します。Oracleデータベースの設定が必要であれば、詳細な手順も提供できますので、お知らせください。