tomo2chin2 commited on
Commit
2c8d979
·
verified ·
1 Parent(s): cf72722

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -60
app.py CHANGED
@@ -1,90 +1,196 @@
1
  import os
2
- import re
3
- import requests
4
  import gradio as gr
5
- from huggingface_hub import HfApi
 
 
 
 
 
6
 
7
- # 環境変数から取得
8
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
9
- MODEL_REPO = os.environ.get("MODEL_REPO", None)
10
  LORA_REPO = os.environ.get("LORA_REPO", None)
11
- CIVITAI_TOKEN = os.environ.get("CIVITAI_TOKEN", None) # Civitai用トークン
12
 
13
  api = HfApi()
14
 
 
 
 
15
  def download_and_upload(url, repo_type):
16
- # 入力チェック
17
- if not url or not repo_type:
18
- return "URLまたはタイプが未指定です。"
 
 
 
 
 
 
19
 
20
- # Civitai API用ヘッダ
21
- headers = {}
22
- if CIVITAI_TOKEN:
23
- headers["Authorization"] = f"Bearer {CIVITAI_TOKEN}"
 
 
 
 
 
 
 
 
24
 
25
- # ファイルダウンロード実行
26
- # CivitaiのAPIからモデルを取得
27
  try:
28
- response = requests.get(url, headers=headers)
29
- response.raise_for_status() # ステータスコードがエラーなら例外
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  except Exception as e:
31
- return f"ファイルのダウンロードに失敗しました: {e}"
32
-
33
- # Content-Dispositionからfilenameを抽出
34
- # 例: Content-Disposition: attachment; filename="model.safetensors"
35
- content_disp = response.headers.get("content-disposition", "")
36
- filename = None
37
- if content_disp:
38
- # filename="..." という���分を正規表現で抽出
39
- match = re.search(r'filename="?([^"]+)"?', content_disp)
40
- if match:
41
- filename = match.group(1)
42
-
43
- if not filename:
44
- # ファイル名がヘッダに無い場合のfallback
45
- filename = "downloaded_file.bin"
46
-
47
- # ダウンロードファイルをローカル一時ファイルに保存
48
- with open(filename, "wb") as f:
49
- f.write(response.content)
50
-
51
- # 選択されたリポジトリを決定
52
  if repo_type == "model":
53
  target_repo = MODEL_REPO
54
  else:
55
  target_repo = LORA_REPO
56
 
57
  if not target_repo:
58
- return f"{repo_type}用リポジトリが環境変数で設定されていません。"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- # Hugging Face Hub にアップロード
61
  try:
62
- api.upload_file(
63
- path_or_fileobj=filename,
64
- path_in_repo=filename,
65
  repo_id=target_repo,
66
  token=HF_TOKEN,
67
- repo_type="dataset", # dataset リポジトリとして扱う
68
- commit_message=f"Add {filename} from {url}"
 
 
 
 
69
  )
70
- return f"ファイル '{filename}' を '{target_repo}' にアップロードしました。"
71
  except Exception as e:
72
- return f"アップロード中にエラーが発生しました: {e}"
73
- finally:
74
- # 必要ならローカルファイル削除などの後処理
75
- pass
76
 
77
- # Gradio UI構築 (前回とほぼ同様)
 
 
78
  with gr.Blocks() as demo:
79
- gr.Markdown("## Civitai経由ファイルダウンロード&アップロードツール")
80
- gr.Markdown("Civitai APIのURLを指定して、'model'または'lora'リポジトリへアップロードします。")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- url_input = gr.Textbox(label="CivitaiモデルAPIのURL", placeholder="例: https://civitai.com/api/download/models/xxxxx?type=Model&format=SafeTensor")
83
- repo_choice = gr.Radio(choices=["model", "lora"], label="アップロード先タイプの選択", value="model")
84
- run_button = gr.Button("実行")
85
- output = gr.Textbox(label="結果メッセージ", interactive=False)
86
 
87
- run_button.click(download_and_upload, inputs=[url_input, repo_choice], outputs=output)
 
 
 
 
88
 
89
- if __name__ == "__main__":
90
- demo.launch()
 
1
  import os
 
 
2
  import gradio as gr
3
+ import requests
4
+ import re
5
+
6
+ from huggingface_hub import HfApi, list_repo_files
7
+ import datasets # pip install datasets
8
+ from datasets import Dataset
9
 
 
10
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
11
+ MODEL_REPO = os.environ.get("MODEL_REPO", None) # => "username/my_dataset_repo"
12
  LORA_REPO = os.environ.get("LORA_REPO", None)
13
+ CIVITAI_TOKEN = os.environ.get("CIVITAI_TOKEN", None)
14
 
15
  api = HfApi()
16
 
17
+ #################################
18
+ # ファイルアップロード部分 (既存)
19
+ #################################
20
  def download_and_upload(url, repo_type):
21
+ """
22
+ 既存コード。Civitai APIからファイルをダウンロードし、
23
+ Datasetリポジトリのfiles/以下にアップロードするイメージ。
24
+ """
25
+ # (詳しくは省略。前回のコードを参照)
26
+
27
+ #################################
28
+ # メタデータ操作部分
29
+ #################################
30
 
31
+ def load_metadata(repo_type):
32
+ """
33
+ ロードボタンで呼ばれ、Datasetリポジトリ内のmetadataを取得してUIへ表示。
34
+ metadataが存在しない場合は作成する。
35
+ """
36
+ if repo_type == "model":
37
+ target_repo = MODEL_REPO
38
+ else:
39
+ target_repo = LORA_REPO
40
+
41
+ if not target_repo:
42
+ return None, f"{repo_type}リポジトリが設定されていません。"
43
 
 
 
44
  try:
45
+ # list_repo_filesでリポジトリにmetadata.arrowがあるか確認
46
+ files_in_repo = list_repo_files(repo_id=target_repo, repo_type="dataset", token=HF_TOKEN)
47
+ has_metadata = any("metadata/" in f for f in files_in_repo)
48
+
49
+ if has_metadata:
50
+ # 既存のmetadataデータセットをロード
51
+ ds = datasets.load_dataset(
52
+ path=target_repo, # "username/dataset_name"
53
+ data_dir="metadata", # metadata/下にあるarrowデータを読み込む
54
+ use_auth_token=HF_TOKEN,
55
+ repo_type="dataset"
56
+ )
57
+ # ds はDictionary形式( split名 -> Dataset )を返す。例えば ds["train"] が本体。
58
+ dset = ds["train"]
59
+ # Dataframe表示用に2次元リストに変換
60
+ # カラム: "filename", "order" など
61
+ df_data = []
62
+ for row in dset:
63
+ df_data.append([row["filename"], row.get("order", 0)])
64
+ return df_data, f"メタデータをロードしました({len(dset)}ファイル)"
65
+ else:
66
+ # metadataが無い → 初期化する
67
+ # すでにfiles/下にファイルがあるかもしれないため、それらをリストアップ
68
+ all_files = [f for f in files_in_repo if not f.startswith(".")]
69
+
70
+ # filesディレクトリに限る
71
+ file_list = [f for f in all_files if f.startswith("files/")]
72
+
73
+ # 初期メタデータ作成
74
+ # "filename" 列と "order" 列を持つDatasetにする
75
+ metadata_dict = {
76
+ "filename": file_list,
77
+ "order": list(range(len(file_list)))
78
+ }
79
+ dset = Dataset.from_dict(metadata_dict)
80
+ # push_to_hub で metadata/ 以下に格納
81
+ dset.push_to_hub(
82
+ repo_id=target_repo,
83
+ token=HF_TOKEN,
84
+ split="train",
85
+ repo_type="dataset",
86
+ private=False,
87
+ embed_remote_files=False,
88
+ max_shard_size="50MB", # メタデータなので小さいはず
89
+ dataset_type=None, # arrowデフォルト
90
+ data_dir="metadata", # ここがmetadataディレクトリ
91
+ # push_to_hub は datasets>=2.11.0 以降推奨
92
+ )
93
+ # UI表示用の2次元リスト
94
+ df_data = [[fn, i] for fn, i in zip(file_list, range(len(file_list)))]
95
+ return df_data, "メタデータを新規作成しました。"
96
  except Exception as e:
97
+ return None, f"ロード失敗: {e}"
98
+
99
+ def apply_reorder(table_data, repo_type):
100
+ """
101
+ UIで編集したDataframe (filename, order) を受け取り、
102
+ Datasetを再構築してpush_to_hub。ファイルの物理名は変えず、メタデータだけ更新。
103
+ """
104
+ if not table_data or len(table_data) == 0:
105
+ return "テーブルが空です。"
106
+
 
 
 
 
 
 
 
 
 
 
 
107
  if repo_type == "model":
108
  target_repo = MODEL_REPO
109
  else:
110
  target_repo = LORA_REPO
111
 
112
  if not target_repo:
113
+ return f"{repo_type}リポジトリが設定されていません。"
114
+
115
+ # table_data: [[filename1, order1], [filename2, order2], ...]
116
+ # Datasetに再変換
117
+ filenames = []
118
+ orders = []
119
+ for row in table_data:
120
+ if len(row) < 2:
121
+ continue
122
+ filenames.append(row[0])
123
+ # orderをintに変換
124
+ try:
125
+ orders.append(int(row[1]))
126
+ except:
127
+ orders.append(0)
128
+
129
+ # ここでファイル名自体は変えず、並び順(order)のカラムだけ変える
130
+ metadata_dict = {"filename": filenames, "order": orders}
131
+ dset = Dataset.from_dict(metadata_dict)
132
 
 
133
  try:
134
+ # push_to_hubで上書きコミット
135
+ dset.push_to_hub(
 
136
  repo_id=target_repo,
137
  token=HF_TOKEN,
138
+ split="train",
139
+ repo_type="dataset",
140
+ private=False,
141
+ embed_remote_files=False,
142
+ data_dir="metadata", # metadataディレクトリに保存
143
+ commit_message="Update metadata order"
144
  )
145
+ return f"メタデータを更新しました({len(dset)}ファイル)。"
146
  except Exception as e:
147
+ return f"並び替えのコミットに失敗: {e}"
 
 
 
148
 
149
+ ##########################
150
+ # Gradio UI定義
151
+ ##########################
152
  with gr.Blocks() as demo:
153
+ gr.Markdown("# データセットリポジトリ管理(ファイル名そのままで並び順編集)")
154
+
155
+ with gr.Row():
156
+ url_input = gr.Textbox(label="CivitaiモデルAPIのURL", placeholder="例: https://civitai.com/api/download/models/xxx?type=Model&format=SafeTensor")
157
+ repo_choice = gr.Radio(choices=["model", "lora"], label="アップロード先タイプ", value="model")
158
+ upload_button = gr.Button("アップロード実行")
159
+ upload_result = gr.Textbox(label="アップロード結果")
160
+
161
+ # 既存のアップロード処理を呼ぶ
162
+ upload_button.click(
163
+ download_and_upload,
164
+ inputs=[url_input, repo_choice],
165
+ outputs=upload_result
166
+ )
167
+
168
+ gr.Markdown("## メタデータによる並び替え管理")
169
+
170
+ load_button = gr.Button("ロード(メタデータ)")
171
+ file_table = gr.Dataframe(
172
+ headers=["filename", "order"],
173
+ row_count=0,
174
+ col_count=2,
175
+ datatype=["str", "number"],
176
+ wrap=True,
177
+ label="ファイル + 並び順メタデータ"
178
+ )
179
+ load_result = gr.Textbox(label="ロード結果")
180
+
181
+ load_button.click(
182
+ fn=load_metadata,
183
+ inputs=[repo_choice],
184
+ outputs=[file_table, load_result]
185
+ )
186
 
187
+ reorder_button = gr.Button("並び順を反映")
188
+ reorder_result = gr.Textbox(label="並び替え実行結果")
 
 
189
 
190
+ reorder_button.click(
191
+ fn=apply_reorder,
192
+ inputs=[file_table, repo_choice],
193
+ outputs=reorder_result
194
+ )
195
 
196
+ demo.queue()