GayanSilva commited on
Commit
d47e55c
β€’
1 Parent(s): a2f518f

Upload 6 files

Browse files
Files changed (6) hide show
  1. .gitignore +4 -0
  2. README.md +1 -13
  3. _langchain.py +38 -0
  4. app.py +163 -0
  5. eleven_labs.py +75 -0
  6. requirements.txt +81 -0
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .env
2
+ .venv
3
+ __pycache__
4
+ *.mp3
README.md CHANGED
@@ -1,13 +1 @@
1
- ---
2
- title: Eleven
3
- emoji: πŸ“‰
4
- colorFrom: indigo
5
- colorTo: blue
6
- sdk: streamlit
7
- sdk_version: 1.21.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ Check out step-by-step tutorial on [lablab.ai tutorials](https://lablab.ai/tutorials/).
 
 
 
 
 
 
 
 
 
 
 
 
_langchain.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import openai
2
+ from langchain.prompts import (
3
+ ChatPromptTemplate,
4
+ MessagesPlaceholder,
5
+ SystemMessagePromptTemplate,
6
+ HumanMessagePromptTemplate
7
+ )
8
+ from langchain.chains import ConversationChain
9
+ from langchain.chat_models import ChatOpenAI
10
+ from langchain.memory import ConversationBufferMemory
11
+ import os
12
+
13
+
14
+ os.environ['OPENAI_API_KEY'] = 'api-key'
15
+
16
+
17
+ prompt = ChatPromptTemplate.from_messages([
18
+ SystemMessagePromptTemplate.from_template("The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know."),
19
+ MessagesPlaceholder(variable_name="history"),
20
+ HumanMessagePromptTemplate.from_template("{input}")
21
+ ])
22
+
23
+
24
+ llm = ChatOpenAI(temperature=0, openai_api_key=os.environ.get("OPENAI_API_KEY"))
25
+ memory = ConversationBufferMemory(return_messages=True)
26
+ conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)
27
+
28
+
29
+ def get_response(prompt, podcaster, guest,):
30
+ _prompt = f"""
31
+
32
+ Generate a podcast with {podcaster} and {guest}. They are discussing about {prompt}.
33
+
34
+ """
35
+
36
+ response = conversation.predict(input=_prompt)
37
+
38
+ return response
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Import from standard library
2
+ import os
3
+ import logging
4
+
5
+ # Import from 3rd party libraries
6
+ import streamlit as st
7
+
8
+ # Import modules from the local package
9
+ from eleven_labs import with_custom_voice, with_premade_voice, get_voices
10
+ from _langchain import get_response
11
+
12
+
13
+ def generate_podcast_text(prompt, podcaster, guest):
14
+ return get_response(prompt=prompt, podcaster=podcaster, guest=guest)
15
+
16
+
17
+ def generate_podcast(voice, prompt, podcaster, guest):
18
+
19
+ if prompt == "":
20
+ st.session_state.text_error = "Please enter a prompt."
21
+ return
22
+
23
+ with text_spinner_placeholder:
24
+ with st.spinner("Please wait while we process your query..."):
25
+ g_podcast = generate_podcast_text(prompt=prompt, podcaster=podcaster, guest=guest)
26
+
27
+ st.session_state.podcast_generate = (g_podcast)
28
+
29
+ with text_spinner_placeholder:
30
+ with st.spinner("Please wait while we process your query..."):
31
+
32
+ if st.session_state.input_file_path != "":
33
+ audio_path = with_custom_voice(podcaster=podcaster, guest=guest, description=prompt, prompt=st.session_state.podcast_generate, file_path=st.session_state.input_file_path)
34
+
35
+ if audio_path != "":
36
+ st.session_state.output_file_path = audio_path
37
+
38
+ else:
39
+
40
+ audio_path = with_premade_voice(prompt=st.session_state.podcast_generate, voice=voice)
41
+
42
+ if audio_path != "":
43
+ st.session_state.output_file_path = audio_path
44
+
45
+
46
+
47
+
48
+ # Configure logger
49
+ logging.basicConfig(format="\n%(asctime)s\n%(message)s", level=logging.INFO, force=True)
50
+
51
+
52
+ # Configure Streamlit page and state
53
+ st.set_page_config(page_title="iPodcast", page_icon="🎧")
54
+
55
+
56
+ # Store the initial value of widgets in session state
57
+ if "podcast_generate" not in st.session_state:
58
+ st.session_state.podcast_generate = ""
59
+
60
+ if "output_file_path" not in st.session_state:
61
+ st.session_state.output_file_path = ""
62
+
63
+ if "input_file_path" not in st.session_state:
64
+ st.session_state.input_file_path = ""
65
+
66
+ if "text_error" not in st.session_state:
67
+ st.session_state.text_error = ""
68
+
69
+ if "visibility" not in st.session_state:
70
+ st.session_state.visibility = "visible"
71
+
72
+
73
+
74
+ # Force responsive layout for columns also on mobile
75
+ st.write(
76
+ """
77
+ <style>
78
+ [data-testid="column"] {
79
+ width: calc(50% - 1rem);
80
+ flex: 1 1 calc(50% - 1rem);
81
+ min-width: calc(50% - 1rem);
82
+ }
83
+ </style>
84
+ """,
85
+ unsafe_allow_html=True,
86
+ )
87
+
88
+
89
+
90
+ # Render Streamlit page
91
+
92
+
93
+ # title of the app
94
+ st.title("Eleven Labs + Langchain Tutorial")
95
+
96
+
97
+ # brief description of the app
98
+ st.markdown(
99
+ "This is a demo of the Eleven Labs + Langchain Tutorial."
100
+ )
101
+
102
+
103
+ # header
104
+ # st.header("This is a demo of the Eleven Labs + Langchain Tutorial")
105
+
106
+
107
+ # file upload if you want to use custom voice
108
+ file = st.file_uploader(label="Upload file", type=["mp3",])
109
+ if file is not None:
110
+ filename = "sample.mp3"
111
+ with open(filename, "wb") as f:
112
+ f.write(file.getbuffer())
113
+ st.session_state.input_file_path = "sample.mp3"
114
+
115
+
116
+ # selectbox
117
+ voice = st.selectbox('Choose your voice', (i for i in get_voices()))
118
+
119
+
120
+ col1, col2 = st.columns(2)
121
+
122
+ with col1:
123
+ podcaster = st.text_input(label="Podcaster", placeholder="Ex. Lex Fridman")
124
+
125
+ with col2:
126
+ guest = st.text_input(label="Guest", placeholder="Ex. Elon Musk")
127
+
128
+
129
+
130
+ # textarea
131
+ prompt = st.text_area(label="Podcast info", placeholder="Ex. Elon Musk joins Lex Fridman in conversation about AI, Autopilot, Neuralink, Tesla, and his personal history.", height=100)
132
+
133
+
134
+ # button
135
+ st.button(
136
+ label="Generate Podcast",
137
+ help="Click to generate podcast",
138
+ key="generate_podcast",
139
+ type="primary",
140
+ on_click=generate_podcast,
141
+ args=(voice, prompt, podcaster, guest,),
142
+ )
143
+
144
+
145
+ text_spinner_placeholder = st.empty()
146
+ if st.session_state.text_error:
147
+ st.error(st.session_state.text_error)
148
+
149
+
150
+ if st.session_state.podcast_generate:
151
+ st.markdown("""---""")
152
+ st.subheader("Read Podcast")
153
+ st.text_area(label="You may read podcast while audio being generated.", value=st.session_state.podcast_generate,)
154
+
155
+
156
+ if st.session_state.output_file_path:
157
+ st.markdown("""---""")
158
+ st.subheader("Listen to Podcast")
159
+
160
+ with open(st.session_state.output_file_path, "rb") as audio_file:
161
+ audio_bytes = audio_file.read()
162
+
163
+ st.audio(audio_bytes, format='audio/mp3', start_time=0)
eleven_labs.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from elevenlabs import clone, generate, play, set_api_key, VOICES_CACHE, voices
2
+ from elevenlabs.api import History
3
+ import os
4
+
5
+ os.environ['ELEVENLABS_API_KEY'] = ''
6
+
7
+ set_api_key(os.environ.get("ELEVENLABS_API_KEY"))
8
+
9
+
10
+ def with_custom_voice(podcaster, guest, description, prompt, file_path):
11
+ name = f'Podcast between {podcaster} and {guest}'
12
+ temp = name.replace(' ', '_')
13
+ audio_path = f'{temp}.mp3'
14
+
15
+ voice = clone(
16
+ name=f'Podcast between {podcaster} and {guest}',
17
+ description=description,
18
+ files=[file_path,],
19
+ )
20
+
21
+ audio = generate(text=prompt, voice=voice)
22
+
23
+ play(audio)
24
+
25
+ try:
26
+ with open(audio_path, 'wb') as f:
27
+ f.write(audio)
28
+
29
+ return audio_path
30
+
31
+ except Exception as e:
32
+ print(e)
33
+
34
+ return ""
35
+
36
+
37
+ def with_premade_voice(prompt, voice):
38
+ audio_path = f'{voice}.mp3'
39
+
40
+ audio = generate(
41
+ text=prompt,
42
+ voice=voice,
43
+ model="eleven_monolingual_v1"
44
+ )
45
+
46
+ play(audio)
47
+
48
+ try:
49
+ with open(audio_path, 'wb') as f:
50
+ f.write(audio)
51
+
52
+ return audio_path
53
+
54
+ except Exception as e:
55
+ print(e)
56
+
57
+ return ""
58
+
59
+
60
+ def get_voices():
61
+ names = []
62
+
63
+ v_list = voices()
64
+
65
+ for v in v_list:
66
+ names.append(v.name)
67
+
68
+ return names
69
+
70
+
71
+ # usage
72
+ # if __name__ == '__main__':
73
+ # print(get_voices())
74
+
75
+ # print(with_premade_voice(prompt='Hi! My name is Bella, nice to meet you!', voice='Bella'))
requirements.txt ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohttp==3.8.4
2
+ aiosignal==1.3.1
3
+ altair==5.0.1
4
+ appnope==0.1.3
5
+ asttokens==2.2.1
6
+ async-timeout==4.0.2
7
+ attrs==23.1.0
8
+ backcall==0.2.0
9
+ blinker==1.6.2
10
+ cachetools==5.3.1
11
+ certifi==2023.5.7
12
+ charset-normalizer==3.1.0
13
+ click==8.1.3
14
+ dataclasses-json==0.5.7
15
+ decorator==5.1.1
16
+ elevenlabs==0.2.17
17
+ executing==1.2.0
18
+ frozenlist==1.3.3
19
+ gitdb==4.0.10
20
+ GitPython==3.1.31
21
+ idna==3.4
22
+ importlib-metadata==6.6.0
23
+ ipython==8.14.0
24
+ jedi==0.18.2
25
+ Jinja2==3.1.2
26
+ jsonschema==4.17.3
27
+ langchain==0.0.189
28
+ markdown-it-py==2.2.0
29
+ MarkupSafe==2.1.3
30
+ marshmallow==3.19.0
31
+ marshmallow-enum==1.5.1
32
+ matplotlib-inline==0.1.6
33
+ mdurl==0.1.2
34
+ multidict==6.0.4
35
+ mypy-extensions==1.0.0
36
+ numexpr==2.8.4
37
+ numpy==1.24.3
38
+ openai==0.27.7
39
+ openapi-schema-pydantic==1.2.4
40
+ packaging==23.1
41
+ pandas==2.0.2
42
+ parso==0.8.3
43
+ pexpect==4.8.0
44
+ pickleshare==0.7.5
45
+ Pillow==9.5.0
46
+ prompt-toolkit==3.0.38
47
+ protobuf==4.23.2
48
+ ptyprocess==0.7.0
49
+ pure-eval==0.2.2
50
+ pyarrow==12.0.0
51
+ pydantic==1.10.8
52
+ pydeck==0.8.1b0
53
+ Pygments==2.15.1
54
+ Pympler==1.0.1
55
+ pyrsistent==0.19.3
56
+ python-dateutil==2.8.2
57
+ pytz==2023.3
58
+ pytz-deprecation-shim==0.1.0.post0
59
+ PyYAML==6.0
60
+ requests==2.31.0
61
+ rich==13.4.1
62
+ six==1.16.0
63
+ smmap==5.0.0
64
+ SQLAlchemy==2.0.15
65
+ stack-data==0.6.2
66
+ streamlit==1.23.1
67
+ tenacity==8.2.2
68
+ toml==0.10.2
69
+ toolz==0.12.0
70
+ tornado==6.3.2
71
+ tqdm==4.65.0
72
+ traitlets==5.9.0
73
+ typing-inspect==0.9.0
74
+ typing_extensions==4.6.3
75
+ tzdata==2023.3
76
+ tzlocal==4.3
77
+ urllib3==2.0.2
78
+ validators==0.20.0
79
+ wcwidth==0.2.6
80
+ yarl==1.9.2
81
+ zipp==3.15.0