Spaces:
Sleeping
Sleeping
MilanCalegari
commited on
Commit
·
15c6b6b
1
Parent(s):
59bdd41
feat: add action
Browse filesfix: add packages and update requirements
fix: path for spaces
fix: path for spaces
fix: path for spaces
fix: path for spaces
fix: all paths
fix: all paths
fix : update get_cards
fix : update get_cards
fix : update with relative path
fix : update with relative path
fix : update with relative path
fix: path
fix: path
- .github/workflows/deploy_space.yaml +21 -0
- app.py +49 -22
- modules/tarot/card.py +11 -2
- packages.txt +1 -0
- requirements.txt +0 -1
- scripts/get_cards.py +66 -20
.github/workflows/deploy_space.yaml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Sync to Hugging Face hub
|
2 |
+
on:
|
3 |
+
push:
|
4 |
+
branches: [main]
|
5 |
+
|
6 |
+
# to run this workflow manually from the Actions tab
|
7 |
+
workflow_dispatch:
|
8 |
+
|
9 |
+
jobs:
|
10 |
+
sync-to-hub:
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
steps:
|
13 |
+
- uses: actions/checkout@v3
|
14 |
+
with:
|
15 |
+
fetch-depth: 0
|
16 |
+
lfs: true
|
17 |
+
- name: Push to hub
|
18 |
+
env:
|
19 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
20 |
+
HF_USERNAME: ${{ secrets.HF_USERNAME }}
|
21 |
+
run: git push https://$HF_USERNAME:[email protected]/spaces/rmcalegari/Arcana main
|
app.py
CHANGED
@@ -1,20 +1,41 @@
|
|
1 |
import streamlit as st
|
2 |
import yaml
|
|
|
|
|
3 |
|
4 |
from modules.llm.card_interpreter import CardInterpreter
|
5 |
from modules.tarot.card import TarotDeck
|
6 |
from modules.utils.commom import CardReadingMethod, label4method
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
# Initialize deck and interpreter
|
9 |
deck = TarotDeck()
|
10 |
deck.get_cards()
|
11 |
interpreter = CardInterpreter()
|
12 |
|
13 |
-
st.set_page_config(
|
14 |
-
page_title="Tarot Reading",
|
15 |
-
page_icon="🔮",
|
16 |
-
layout="centered"
|
17 |
-
)
|
18 |
|
19 |
st.title("🔮 Tarot Reading")
|
20 |
|
@@ -27,7 +48,7 @@ with st.sidebar:
|
|
27 |
max_value=1.0,
|
28 |
value=yaml.safe_load(open("config.yaml"))["reverse_probability"],
|
29 |
step=0.1,
|
30 |
-
help="Probability of a card appearing reversed (0.0 to 1.0)"
|
31 |
)
|
32 |
# TODO: Add Portuguese language support and translation
|
33 |
# language = st.selectbox(
|
@@ -40,7 +61,9 @@ reversed_prob -= 1
|
|
40 |
|
41 |
# User interface texts
|
42 |
welcome_text = "### Welcome to your Tarot Reading"
|
43 |
-
instructions_text =
|
|
|
|
|
44 |
method_text = "Choose your reading method:"
|
45 |
context_text = "What would you like to know about? (Optional)"
|
46 |
context_placeholder = "Ex: I need guidance about finding my life purpose..."
|
@@ -52,7 +75,7 @@ spinner_texts = {
|
|
52 |
"consult": "🧙♂️ Consulting ancient wisdom...",
|
53 |
"cards": "### Your Cards:",
|
54 |
"reading": "### Your Reading:",
|
55 |
-
"default_context": "General daily reading"
|
56 |
}
|
57 |
|
58 |
# Display welcome message and instructions
|
@@ -65,39 +88,43 @@ method = st.selectbox(
|
|
65 |
[
|
66 |
CardReadingMethod.PAST_PRESENT_FUTURE.value,
|
67 |
CardReadingMethod.CELTIC_CROSS.value,
|
68 |
-
CardReadingMethod.HAND_OF_ERIS.value
|
69 |
-
]
|
70 |
)
|
71 |
|
72 |
# Reading context input
|
73 |
-
context = st.text_area(
|
74 |
-
context_text,
|
75 |
-
placeholder=context_placeholder
|
76 |
-
)
|
77 |
|
78 |
if st.button(draw_button):
|
79 |
# Shuffle and draw cards
|
80 |
with st.spinner(spinner_texts["shuffle"]):
|
81 |
deck.shuffle(reversed_prob)
|
82 |
-
|
83 |
with st.spinner(spinner_texts["channel"]):
|
84 |
cards = deck.draw(CardReadingMethod(method))
|
85 |
-
|
86 |
# Display cards
|
87 |
st.markdown(spinner_texts["cards"])
|
88 |
-
|
89 |
cols = st.columns(len(cards))
|
90 |
for idx, (card, col) in enumerate(zip(cards, cols)):
|
91 |
with col:
|
92 |
with st.spinner(spinner_texts["reveal"]):
|
93 |
-
st.image(
|
94 |
-
|
|
|
|
|
|
|
95 |
# Generate and display interpretation
|
96 |
with st.spinner(spinner_texts["consult"]):
|
97 |
if context:
|
98 |
-
interpretation = interpreter.generate_interpretation(
|
|
|
|
|
99 |
else:
|
100 |
-
interpretation = interpreter.generate_interpretation(
|
101 |
-
|
|
|
|
|
102 |
st.markdown(spinner_texts["reading"])
|
103 |
st.write(interpretation)
|
|
|
1 |
import streamlit as st
|
2 |
import yaml
|
3 |
+
from scripts.get_cards import get_cards
|
4 |
+
import os
|
5 |
|
6 |
from modules.llm.card_interpreter import CardInterpreter
|
7 |
from modules.tarot.card import TarotDeck
|
8 |
from modules.utils.commom import CardReadingMethod, label4method
|
9 |
|
10 |
+
# Usar o mesmo método de obtenção do caminho base
|
11 |
+
base_dir = os.path.dirname(os.path.abspath(__file__))
|
12 |
+
data_dir = os.path.join(base_dir, "data")
|
13 |
+
json_file = os.path.join(data_dir, "tarot-images.json")
|
14 |
+
|
15 |
+
print(f"App base directory: {base_dir}")
|
16 |
+
print(f"App data directory: {data_dir}")
|
17 |
+
print(f"App looking for JSON file at: {json_file}")
|
18 |
+
|
19 |
+
# Verificar arquivos
|
20 |
+
try:
|
21 |
+
print("Attempting to download cards...")
|
22 |
+
get_cards()
|
23 |
+
print("Cards downloaded successfully")
|
24 |
+
|
25 |
+
if not os.path.exists(json_file):
|
26 |
+
raise FileNotFoundError(f"JSON file not found at {json_file}")
|
27 |
+
|
28 |
+
except Exception as e:
|
29 |
+
st.error(f"Error downloading tarot data: {str(e)}")
|
30 |
+
print(f"Detailed error: {e}")
|
31 |
+
st.stop()
|
32 |
+
|
33 |
# Initialize deck and interpreter
|
34 |
deck = TarotDeck()
|
35 |
deck.get_cards()
|
36 |
interpreter = CardInterpreter()
|
37 |
|
38 |
+
st.set_page_config(page_title="Tarot Reading", page_icon="🔮", layout="centered")
|
|
|
|
|
|
|
|
|
39 |
|
40 |
st.title("🔮 Tarot Reading")
|
41 |
|
|
|
48 |
max_value=1.0,
|
49 |
value=yaml.safe_load(open("config.yaml"))["reverse_probability"],
|
50 |
step=0.1,
|
51 |
+
help="Probability of a card appearing reversed (0.0 to 1.0)",
|
52 |
)
|
53 |
# TODO: Add Portuguese language support and translation
|
54 |
# language = st.selectbox(
|
|
|
61 |
|
62 |
# User interface texts
|
63 |
welcome_text = "### Welcome to your Tarot Reading"
|
64 |
+
instructions_text = (
|
65 |
+
"Please select a reading method and provide a context for your consultation."
|
66 |
+
)
|
67 |
method_text = "Choose your reading method:"
|
68 |
context_text = "What would you like to know about? (Optional)"
|
69 |
context_placeholder = "Ex: I need guidance about finding my life purpose..."
|
|
|
75 |
"consult": "🧙♂️ Consulting ancient wisdom...",
|
76 |
"cards": "### Your Cards:",
|
77 |
"reading": "### Your Reading:",
|
78 |
+
"default_context": "General daily reading",
|
79 |
}
|
80 |
|
81 |
# Display welcome message and instructions
|
|
|
88 |
[
|
89 |
CardReadingMethod.PAST_PRESENT_FUTURE.value,
|
90 |
CardReadingMethod.CELTIC_CROSS.value,
|
91 |
+
CardReadingMethod.HAND_OF_ERIS.value,
|
92 |
+
],
|
93 |
)
|
94 |
|
95 |
# Reading context input
|
96 |
+
context = st.text_area(context_text, placeholder=context_placeholder)
|
|
|
|
|
|
|
97 |
|
98 |
if st.button(draw_button):
|
99 |
# Shuffle and draw cards
|
100 |
with st.spinner(spinner_texts["shuffle"]):
|
101 |
deck.shuffle(reversed_prob)
|
102 |
+
|
103 |
with st.spinner(spinner_texts["channel"]):
|
104 |
cards = deck.draw(CardReadingMethod(method))
|
105 |
+
|
106 |
# Display cards
|
107 |
st.markdown(spinner_texts["cards"])
|
108 |
+
|
109 |
cols = st.columns(len(cards))
|
110 |
for idx, (card, col) in enumerate(zip(cards, cols)):
|
111 |
with col:
|
112 |
with st.spinner(spinner_texts["reveal"]):
|
113 |
+
st.image(
|
114 |
+
card.image_pth,
|
115 |
+
caption=f"{label4method[CardReadingMethod(method)][idx]}: {card.name}",
|
116 |
+
)
|
117 |
+
|
118 |
# Generate and display interpretation
|
119 |
with st.spinner(spinner_texts["consult"]):
|
120 |
if context:
|
121 |
+
interpretation = interpreter.generate_interpretation(
|
122 |
+
cards, context, CardReadingMethod(method)
|
123 |
+
)
|
124 |
else:
|
125 |
+
interpretation = interpreter.generate_interpretation(
|
126 |
+
cards, None, CardReadingMethod(method)
|
127 |
+
)
|
128 |
+
|
129 |
st.markdown(spinner_texts["reading"])
|
130 |
st.write(interpretation)
|
modules/tarot/card.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import json
|
2 |
import random
|
3 |
|
@@ -6,7 +7,15 @@ from ..utils.commom import Card, CardReadingMethod
|
|
6 |
|
7 |
class TarotDeck:
|
8 |
def __init__(self):
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
self.cards_json = json.load(f)
|
11 |
|
12 |
def get_cards(self):
|
@@ -15,7 +24,7 @@ class TarotDeck:
|
|
15 |
name = card_data["name"]
|
16 |
number = int(card_data["number"])
|
17 |
is_major_arcana = card_data["arcana"]
|
18 |
-
image_pth = f"
|
19 |
|
20 |
card = Card(
|
21 |
name=name,
|
|
|
1 |
+
import os
|
2 |
import json
|
3 |
import random
|
4 |
|
|
|
7 |
|
8 |
class TarotDeck:
|
9 |
def __init__(self):
|
10 |
+
base_dir = os.path.dirname(
|
11 |
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
12 |
+
)
|
13 |
+
data_dir = os.path.join(base_dir, "data")
|
14 |
+
json_file = os.path.join(data_dir, "tarot-images.json")
|
15 |
+
|
16 |
+
print(f"TarotDeck looking for JSON at: {json_file}")
|
17 |
+
|
18 |
+
with open(json_file) as f:
|
19 |
self.cards_json = json.load(f)
|
20 |
|
21 |
def get_cards(self):
|
|
|
24 |
name = card_data["name"]
|
25 |
number = int(card_data["number"])
|
26 |
is_major_arcana = card_data["arcana"]
|
27 |
+
image_pth = f"home/user/app/data/cards/{card_data['img']}"
|
28 |
|
29 |
card = Card(
|
30 |
name=name,
|
packages.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
python3-dev
|
requirements.txt
CHANGED
@@ -53,7 +53,6 @@ toml==0.10.2
|
|
53 |
torch==2.5.1
|
54 |
tornado==6.4.2
|
55 |
tqdm==4.67.1
|
56 |
-
tractian-python-sdk==12.8.0
|
57 |
transformers==4.47.1
|
58 |
typing_extensions==4.12.2
|
59 |
tzdata==2024.2
|
|
|
53 |
torch==2.5.1
|
54 |
tornado==6.4.2
|
55 |
tqdm==4.67.1
|
|
|
56 |
transformers==4.47.1
|
57 |
typing_extensions==4.12.2
|
58 |
tzdata==2024.2
|
scripts/get_cards.py
CHANGED
@@ -1,28 +1,74 @@
|
|
1 |
import os
|
2 |
-
import shutil
|
3 |
import zipfile
|
4 |
|
5 |
import requests
|
6 |
|
7 |
|
8 |
def get_cards():
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
get_cards()
|
|
|
1 |
import os
|
|
|
2 |
import zipfile
|
3 |
|
4 |
import requests
|
5 |
|
6 |
|
7 |
def get_cards():
|
8 |
+
base_dir = os.path.dirname(
|
9 |
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
10 |
+
)
|
11 |
+
data_dir = os.path.join(base_dir, "data")
|
12 |
+
os.makedirs(data_dir, exist_ok=True)
|
13 |
+
|
14 |
+
print(f"Base directory: {base_dir}")
|
15 |
+
print(f"Data directory: {data_dir}")
|
16 |
+
|
17 |
+
url = "https://www.kaggle.com/api/v1/datasets/download/lsind18/tarot-json"
|
18 |
+
zip_file = os.path.join(data_dir, "tarot-json.zip")
|
19 |
+
|
20 |
+
try:
|
21 |
+
# Download with curl-like headers
|
22 |
+
response = requests.get(
|
23 |
+
url,
|
24 |
+
allow_redirects=True,
|
25 |
+
headers={"User-Agent": "curl/7.64.1", "Accept": "*/*"},
|
26 |
+
)
|
27 |
+
response.raise_for_status()
|
28 |
+
|
29 |
+
with open(zip_file, "wb") as f:
|
30 |
+
f.write(response.content)
|
31 |
+
|
32 |
+
# Extrair e renomear se necessário
|
33 |
+
with zipfile.ZipFile(zip_file, "r") as zip_ref:
|
34 |
+
# Listar conteúdo do ZIP
|
35 |
+
files = zip_ref.namelist()
|
36 |
+
json_files = [f for f in files if f.endswith(".json")]
|
37 |
+
|
38 |
+
print(f"Arquivos encontrados no ZIP: {files}")
|
39 |
+
print(f"Arquivos JSON encontrados: {json_files}")
|
40 |
+
|
41 |
+
if json_files:
|
42 |
+
# Extrair todos os arquivos
|
43 |
+
zip_ref.extractall(data_dir)
|
44 |
+
|
45 |
+
# Renomear o primeiro arquivo JSON encontrado para tarot-images.json
|
46 |
+
old_path = os.path.join(data_dir, json_files[0])
|
47 |
+
new_path = os.path.join(data_dir, "tarot-images.json")
|
48 |
+
print(f"Renomeando de {old_path} para {new_path}")
|
49 |
+
|
50 |
+
if old_path != new_path:
|
51 |
+
if os.path.exists(old_path):
|
52 |
+
os.rename(old_path, new_path)
|
53 |
+
else:
|
54 |
+
print(f"ERRO: Arquivo original {old_path} não encontrado!")
|
55 |
+
else:
|
56 |
+
raise Exception("No JSON file found in the ZIP archive")
|
57 |
+
|
58 |
+
os.remove(zip_file)
|
59 |
+
|
60 |
+
# Verificar se o arquivo final existe
|
61 |
+
if os.path.exists(new_path):
|
62 |
+
print(f"Arquivo final encontrado em: {new_path}")
|
63 |
+
else:
|
64 |
+
print(f"ERRO: Arquivo final não encontrado em: {new_path}")
|
65 |
+
|
66 |
+
print("Files downloaded and extracted successfully!")
|
67 |
+
|
68 |
+
except Exception as e:
|
69 |
+
print(f"Error downloading/extracting files: {e}")
|
70 |
+
raise
|
71 |
+
|
72 |
+
|
73 |
+
if __name__ == "__main__":
|
74 |
get_cards()
|