1
1
#!/usr/bin/env python
2
2
# filepath: /home/runner/work/template-fastapi/template-fastapi/scripts/files.py
3
3
4
- import os
5
4
from pathlib import Path
6
- from typing import List , Optional
7
5
8
6
import typer
9
7
from rich .console import Console
18
16
19
17
@app .command ()
20
18
def list_files (
21
- prefix : Optional [ str ] = typer .Option (None , "--prefix" , "-p" , help = "ファイル名のプレフィックス" ),
19
+ prefix : str | None = typer .Option (None , "--prefix" , "-p" , help = "ファイル名のプレフィックス" ),
22
20
):
23
21
"""ファイル一覧を取得する"""
24
- console .print (f "[bold green]ファイル一覧[/bold green]を取得します" )
25
-
22
+ console .print ("[bold green]ファイル一覧[/bold green]を取得します" )
23
+
26
24
if prefix :
27
25
console .print (f"プレフィックス: { prefix } " )
28
-
26
+
29
27
try :
30
28
files = file_repo .list_files (prefix = prefix )
31
-
29
+
32
30
if not files :
33
31
console .print ("[yellow]ファイルが見つかりませんでした[/yellow]" )
34
32
return
35
-
33
+
36
34
# テーブルで表示
37
35
table = Table (title = "ファイル一覧" )
38
36
table .add_column ("ファイル名" , style = "cyan" )
39
37
table .add_column ("サイズ (bytes)" , style = "green" )
40
38
table .add_column ("コンテンツタイプ" , style = "yellow" )
41
39
table .add_column ("最終更新日時" , style = "magenta" )
42
-
40
+
43
41
for file in files :
44
42
table .add_row (
45
43
file .name ,
46
44
str (file .size ) if file .size else "N/A" ,
47
45
file .content_type or "N/A" ,
48
- file .last_modified .strftime ("%Y-%m-%d %H:%M:%S" ) if file .last_modified else "N/A"
46
+ file .last_modified .strftime ("%Y-%m-%d %H:%M:%S" ) if file .last_modified else "N/A" ,
49
47
)
50
-
48
+
51
49
console .print (table )
52
50
console .print (f"[bold blue]合計: { len (files )} 件[/bold blue]" )
53
-
51
+
54
52
except Exception as e :
55
53
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
56
54
57
55
58
56
@app .command ()
59
57
def upload_file (
60
58
file_path : str = typer .Argument (..., help = "アップロードするファイルのパス" ),
61
- blob_name : Optional [ str ] = typer .Option (None , "--name" , "-n" , help = "Blob名(指定しない場合はファイル名を使用)" ),
59
+ blob_name : str | None = typer .Option (None , "--name" , "-n" , help = "Blob名(指定しない場合はファイル名を使用)" ),
62
60
):
63
61
"""単一のファイルをアップロードする"""
64
62
file_path_obj = Path (file_path )
65
-
63
+
66
64
if not file_path_obj .exists ():
67
65
console .print (f"[bold red]エラー[/bold red]: ファイル '{ file_path } ' が見つかりません" )
68
66
return
69
-
67
+
70
68
if not file_path_obj .is_file ():
71
69
console .print (f"[bold red]エラー[/bold red]: '{ file_path } ' はファイルではありません" )
72
70
return
73
-
71
+
74
72
blob_name = blob_name or file_path_obj .name
75
73
console .print (f"[bold green]ファイル[/bold green]: { file_path } -> { blob_name } " )
76
-
74
+
77
75
try :
78
76
with open (file_path_obj , "rb" ) as f :
79
77
file_data = f .read ()
80
-
78
+
81
79
uploaded_file = file_repo .upload_file (
82
80
file_name = blob_name ,
83
81
file_data = file_data ,
84
- content_type = None # Let Azure detect the content type
82
+ content_type = None , # Let Azure detect the content type
85
83
)
86
-
87
- console .print (f "[bold green]アップロード成功[/bold green]" )
84
+
85
+ console .print ("[bold green]アップロード成功[/bold green]" )
88
86
console .print (f" ファイル名: { uploaded_file .name } " )
89
87
console .print (f" サイズ: { uploaded_file .size } bytes" )
90
88
console .print (f" コンテンツタイプ: { uploaded_file .content_type } " )
91
89
console .print (f" URL: { uploaded_file .url } " )
92
-
90
+
93
91
except Exception as e :
94
92
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
95
93
96
94
97
95
@app .command ()
98
96
def upload_multiple_files (
99
- file_paths : List [str ] = typer .Argument (..., help = "アップロードするファイルのパス(複数指定可能)" ),
97
+ file_paths : list [str ] = typer .Argument (..., help = "アップロードするファイルのパス(複数指定可能)" ),
100
98
):
101
99
"""複数のファイルを同時にアップロードする"""
102
- console .print (f "[bold green]複数ファイル[/bold green]をアップロードします" )
103
-
100
+ console .print ("[bold green]複数ファイル[/bold green]をアップロードします" )
101
+
104
102
# ファイルの存在チェック
105
103
valid_files = []
106
104
for file_path in file_paths :
@@ -112,49 +110,49 @@ def upload_multiple_files(
112
110
console .print (f"[bold red]警告[/bold red]: '{ file_path } ' はファイルではありません - スキップします" )
113
111
continue
114
112
valid_files .append (file_path_obj )
115
-
113
+
116
114
if not valid_files :
117
115
console .print ("[bold red]エラー[/bold red]: 有効なファイルが見つかりませんでした" )
118
116
return
119
-
117
+
120
118
try :
121
119
file_data_list = []
122
120
for file_path_obj in valid_files :
123
121
with open (file_path_obj , "rb" ) as f :
124
122
file_data = f .read ()
125
123
file_data_list .append ((file_path_obj .name , file_data , None ))
126
-
124
+
127
125
uploaded_files = file_repo .upload_files (file_data_list )
128
-
126
+
129
127
console .print (f"[bold green]アップロード成功[/bold green]: { len (uploaded_files )} 件" )
130
128
for uploaded_file in uploaded_files :
131
129
console .print (f" - { uploaded_file .name } ({ uploaded_file .size } bytes)" )
132
-
130
+
133
131
except Exception as e :
134
132
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
135
133
136
134
137
135
@app .command ()
138
136
def download_file (
139
137
blob_name : str = typer .Argument (..., help = "ダウンロードするBlobの名前" ),
140
- output_path : Optional [ str ] = typer .Option (None , "--output" , "-o" , help = "出力ファイルのパス" ),
138
+ output_path : str | None = typer .Option (None , "--output" , "-o" , help = "出力ファイルのパス" ),
141
139
):
142
140
"""ファイルをダウンロードする"""
143
141
console .print (f"[bold green]ファイル[/bold green]: { blob_name } をダウンロードします" )
144
-
142
+
145
143
try :
146
144
file_data = file_repo .download_file (blob_name )
147
-
145
+
148
146
output_path = output_path or blob_name
149
147
output_path_obj = Path (output_path )
150
-
148
+
151
149
with open (output_path_obj , "wb" ) as f :
152
150
f .write (file_data )
153
-
154
- console .print (f "[bold green]ダウンロード成功[/bold green]" )
151
+
152
+ console .print ("[bold green]ダウンロード成功[/bold green]" )
155
153
console .print (f" 出力先: { output_path_obj .absolute ()} " )
156
154
console .print (f" サイズ: { len (file_data )} bytes" )
157
-
155
+
158
156
except Exception as e :
159
157
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
160
158
@@ -165,16 +163,16 @@ def get_file_info(
165
163
):
166
164
"""ファイル情報を取得する"""
167
165
console .print (f"[bold green]ファイル情報[/bold green]: { blob_name } " )
168
-
166
+
169
167
try :
170
168
file_info = file_repo .get_file_info (blob_name )
171
-
169
+
172
170
console .print (f" ファイル名: { file_info .name } " )
173
171
console .print (f" サイズ: { file_info .size } bytes" )
174
172
console .print (f" コンテンツタイプ: { file_info .content_type } " )
175
173
console .print (f" 最終更新日時: { file_info .last_modified } " )
176
174
console .print (f" URL: { file_info .url } " )
177
-
175
+
178
176
except Exception as e :
179
177
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
180
178
@@ -186,7 +184,7 @@ def delete_file(
186
184
):
187
185
"""ファイルを削除する"""
188
186
console .print (f"[bold green]ファイル削除[/bold green]: { blob_name } " )
189
-
187
+
190
188
try :
191
189
# 削除前に確認
192
190
if not force :
@@ -195,45 +193,45 @@ def delete_file(
195
193
console .print (f" ファイル名: { file_info .name } " )
196
194
console .print (f" サイズ: { file_info .size } bytes" )
197
195
console .print (f" 最終更新日時: { file_info .last_modified } " )
198
-
196
+
199
197
if not typer .confirm ("削除してもよろしいですか?" ):
200
198
console .print ("[yellow]削除をキャンセルしました[/yellow]" )
201
199
return
202
-
200
+
203
201
file_repo .delete_file (blob_name )
204
202
console .print (f"[bold green]削除成功[/bold green]: { blob_name } " )
205
-
203
+
206
204
except Exception as e :
207
205
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
208
206
209
207
210
208
@app .command ()
211
209
def delete_multiple_files (
212
- blob_names : List [str ] = typer .Argument (..., help = "削除するBlobの名前(複数指定可能)" ),
210
+ blob_names : list [str ] = typer .Argument (..., help = "削除するBlobの名前(複数指定可能)" ),
213
211
force : bool = typer .Option (False , "--force" , "-f" , help = "確認なしで削除する" ),
214
212
):
215
213
"""複数のファイルを同時に削除する"""
216
214
console .print (f"[bold green]複数ファイル削除[/bold green]: { len (blob_names )} 件" )
217
-
215
+
218
216
try :
219
217
# 削除前に確認
220
218
if not force :
221
219
console .print ("以下のファイルを削除しようとしています:" )
222
220
for blob_name in blob_names :
223
221
console .print (f" - { blob_name } " )
224
-
222
+
225
223
if not typer .confirm ("削除してもよろしいですか?" ):
226
224
console .print ("[yellow]削除をキャンセルしました[/yellow]" )
227
225
return
228
-
226
+
229
227
deleted_files = file_repo .delete_files (blob_names )
230
228
console .print (f"[bold green]削除成功[/bold green]: { len (deleted_files )} 件" )
231
229
for deleted_file in deleted_files :
232
230
console .print (f" - { deleted_file } " )
233
-
231
+
234
232
except Exception as e :
235
233
console .print (f"[bold red]エラー[/bold red]: { str (e )} " )
236
234
237
235
238
236
if __name__ == "__main__" :
239
- app ()
237
+ app ()
0 commit comments