Spaces:
Sleeping
Sleeping
manishgupta006
commited on
Commit
•
5d3b777
1
Parent(s):
7083b2f
all files added
Browse files- .gitignore +142 -0
- 0.1 +34 -0
- README.md +56 -7
- app.py +178 -0
- assets/app-design.png +0 -0
- assets/examples/cheetah-deer.jpg +0 -0
- assets/examples/man-child-pet-dog.jpg +0 -0
- assets/examples/man-child.jpeg +0 -0
- assets/examples/men-fighting.jpg +0 -0
- assets/examples/teacher-school.jpg +0 -0
- assets/story-teller-app.png +0 -0
- assets/story-teller-examples.png +0 -0
- assets/title.jpg +0 -0
- config.py +64 -0
- model.py +87 -0
- mongo_utils.py +57 -0
- myenv/bin/Activate.ps1 +247 -0
- myenv/bin/activate +63 -0
- myenv/bin/pip.exe +0 -0
- myenv/bin/pip3.11.exe +0 -0
- myenv/bin/pip3.exe +0 -0
- myenv/bin/python.exe +0 -0
- myenv/bin/python3.11.exe +0 -0
- myenv/bin/python3.exe +0 -0
- myenv/bin/python3w.exe +0 -0
- myenv/bin/pythonw.exe +0 -0
- myenv/pyvenv.cfg +5 -0
- requirements.txt +5 -0
- style.css +11 -0
- test.py +13 -0
.gitignore
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# MY CHNAGES
|
2 |
+
secrets.toml
|
3 |
+
scratch*.ipynb
|
4 |
+
experiments.ipynb
|
5 |
+
venv*/
|
6 |
+
*.excalidraw
|
7 |
+
.vscode*
|
8 |
+
.vscode*/
|
9 |
+
.examples/
|
10 |
+
.swp
|
11 |
+
.aws-sam/
|
12 |
+
|
13 |
+
# Byte-compiled / optimized / DLL files
|
14 |
+
__pycache__/
|
15 |
+
*.py[cod]
|
16 |
+
*$py.class
|
17 |
+
|
18 |
+
# C extensions
|
19 |
+
*.so
|
20 |
+
|
21 |
+
# Distribution / packaging
|
22 |
+
.Python
|
23 |
+
build/
|
24 |
+
develop-eggs/
|
25 |
+
dist/
|
26 |
+
downloads/
|
27 |
+
eggs/
|
28 |
+
.eggs/
|
29 |
+
lib/
|
30 |
+
lib64/
|
31 |
+
parts/
|
32 |
+
sdist/
|
33 |
+
var/
|
34 |
+
wheels/
|
35 |
+
pip-wheel-metadata/
|
36 |
+
share/python-wheels/
|
37 |
+
*.egg-info/
|
38 |
+
.installed.cfg
|
39 |
+
*.egg
|
40 |
+
MANIFEST
|
41 |
+
|
42 |
+
# PyInstaller
|
43 |
+
# Usually these files are written by a python script from a template
|
44 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
45 |
+
*.manifest
|
46 |
+
*.spec
|
47 |
+
|
48 |
+
# Installer logs
|
49 |
+
pip-log.txt
|
50 |
+
pip-delete-this-directory.txt
|
51 |
+
|
52 |
+
# Unit test / coverage reports
|
53 |
+
htmlcov/
|
54 |
+
.tox/
|
55 |
+
.nox/
|
56 |
+
.coverage
|
57 |
+
.coverage.*
|
58 |
+
.cache
|
59 |
+
nosetests.xml
|
60 |
+
coverage.xml
|
61 |
+
*.cover
|
62 |
+
*.py,cover
|
63 |
+
.hypothesis/
|
64 |
+
.pytest_cache/
|
65 |
+
|
66 |
+
# Translations
|
67 |
+
*.mo
|
68 |
+
*.pot
|
69 |
+
|
70 |
+
# Django stuff:
|
71 |
+
*.log
|
72 |
+
local_settings.py
|
73 |
+
db.sqlite3
|
74 |
+
db.sqlite3-journal
|
75 |
+
|
76 |
+
# Flask stuff:
|
77 |
+
instance/
|
78 |
+
.webassets-cache
|
79 |
+
|
80 |
+
# Scrapy stuff:
|
81 |
+
.scrapy
|
82 |
+
|
83 |
+
# Sphinx documentation
|
84 |
+
docs/_build/
|
85 |
+
|
86 |
+
# PyBuilder
|
87 |
+
target/
|
88 |
+
|
89 |
+
# Jupyter Notebook
|
90 |
+
.ipynb_checkpoints
|
91 |
+
|
92 |
+
# IPython
|
93 |
+
profile_default/
|
94 |
+
ipython_config.py
|
95 |
+
|
96 |
+
# pyenv
|
97 |
+
.python-version
|
98 |
+
|
99 |
+
# pipenv
|
100 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
101 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
102 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
103 |
+
# install all needed dependencies.
|
104 |
+
#Pipfile.lock
|
105 |
+
|
106 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
107 |
+
__pypackages__/
|
108 |
+
|
109 |
+
# Celery stuff
|
110 |
+
celerybeat-schedule
|
111 |
+
celerybeat.pid
|
112 |
+
|
113 |
+
# SageMath parsed files
|
114 |
+
*.sage.py
|
115 |
+
|
116 |
+
|
117 |
+
# Environments
|
118 |
+
.env
|
119 |
+
.venv
|
120 |
+
env/
|
121 |
+
venv*/
|
122 |
+
ENV/
|
123 |
+
env.bak/
|
124 |
+
venv.bak/
|
125 |
+
|
126 |
+
# Spyder project settings
|
127 |
+
.spyderproject
|
128 |
+
.spyproject
|
129 |
+
|
130 |
+
# Rope project settings
|
131 |
+
.ropeproject
|
132 |
+
|
133 |
+
# mkdocs documentation
|
134 |
+
/site
|
135 |
+
|
136 |
+
# mypy
|
137 |
+
.mypy_cache/
|
138 |
+
.dmypy.json
|
139 |
+
dmypy.json
|
140 |
+
|
141 |
+
# Pyre type checker
|
142 |
+
.pyre/
|
0.1
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Requirement already satisfied: langchain in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (0.0.354)
|
2 |
+
Requirement already satisfied: PyYAML>=5.3 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (6.0.2)
|
3 |
+
Requirement already satisfied: SQLAlchemy<3,>=1.4 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (2.0.32)
|
4 |
+
Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (3.10.3)
|
5 |
+
Requirement already satisfied: dataclasses-json<0.7,>=0.5.7 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (0.6.7)
|
6 |
+
Requirement already satisfied: jsonpatch<2.0,>=1.33 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (1.33)
|
7 |
+
Requirement already satisfied: langchain-community<0.1,>=0.0.8 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (0.0.20)
|
8 |
+
Requirement already satisfied: langchain-core<0.2,>=0.1.5 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (0.1.23)
|
9 |
+
Requirement already satisfied: langsmith<0.1.0,>=0.0.77 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (0.0.87)
|
10 |
+
Requirement already satisfied: numpy<2,>=1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (1.26.4)
|
11 |
+
Requirement already satisfied: pydantic<3,>=1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (2.8.2)
|
12 |
+
Requirement already satisfied: requests<3,>=2 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (2.29.0)
|
13 |
+
Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain) (8.5.0)
|
14 |
+
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (2.3.5)
|
15 |
+
Requirement already satisfied: aiosignal>=1.1.2 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)
|
16 |
+
Requirement already satisfied: attrs>=17.3.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (24.2.0)
|
17 |
+
Requirement already satisfied: frozenlist>=1.1.1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)
|
18 |
+
Requirement already satisfied: multidict<7.0,>=4.5 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.5)
|
19 |
+
Requirement already satisfied: yarl<2.0,>=1.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)
|
20 |
+
Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (3.21.3)
|
21 |
+
Requirement already satisfied: typing-inspect<1,>=0.4.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (0.9.0)
|
22 |
+
Requirement already satisfied: jsonpointer>=1.9 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from jsonpatch<2.0,>=1.33->langchain) (3.0.0)
|
23 |
+
Requirement already satisfied: anyio<5,>=3 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain-core<0.2,>=0.1.5->langchain) (4.4.0)
|
24 |
+
Requirement already satisfied: packaging<24.0,>=23.2 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from langchain-core<0.2,>=0.1.5->langchain) (23.2)
|
25 |
+
Requirement already satisfied: annotated-types>=0.4.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from pydantic<3,>=1->langchain) (0.7.0)
|
26 |
+
Requirement already satisfied: pydantic-core==2.20.1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from pydantic<3,>=1->langchain) (2.20.1)
|
27 |
+
Requirement already satisfied: typing-extensions>=4.6.1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from pydantic<3,>=1->langchain) (4.12.2)
|
28 |
+
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from requests<3,>=2->langchain) (3.3.2)
|
29 |
+
Requirement already satisfied: idna<4,>=2.5 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from requests<3,>=2->langchain) (3.7)
|
30 |
+
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from requests<3,>=2->langchain) (1.26.19)
|
31 |
+
Requirement already satisfied: certifi>=2017.4.17 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from requests<3,>=2->langchain) (2024.7.4)
|
32 |
+
Requirement already satisfied: greenlet!=0.4.17 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from SQLAlchemy<3,>=1.4->langchain) (3.0.3)
|
33 |
+
Requirement already satisfied: sniffio>=1.1 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from anyio<5,>=3->langchain-core<0.2,>=0.1.5->langchain) (1.3.1)
|
34 |
+
Requirement already satisfied: mypy-extensions>=0.3.0 in c:\users\itsja\appdata\local\programs\python\python311\lib\site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain) (1.0.0)
|
README.md
CHANGED
@@ -1,13 +1,62 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
-
license:
|
11 |
---
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
+
title: Picture to Story Generator
|
3 |
+
emoji: 📖
|
4 |
+
colorFrom: yellow
|
5 |
+
colorTo: red
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 3.46.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
+
license: mit
|
11 |
---
|
12 |
|
13 |
+
<a href="https://huggingface.co/spaces/sssingh/pic-to-story" target="_blank"><img src="https://img.shields.io/badge/click_here_to_open_gradio_app-orange?style=for-the-badge&logo=dependabot"/></a>
|
14 |
+
|
15 |
+
|
16 |
+
# The Storyteller
|
17 |
+
***A Large Language Model Based App to Generate Stories from Pictures***
|
18 |
+
|
19 |
+
<img src="https://github.com/sssingh/pic-to-story/blob/main/assets/title.jpg?raw=true" width="1000" height="350"/><br><br>
|
20 |
+
|
21 |
+
>This application employs a Image2Text model hosted by Huggingface, which is a modified adaptation of the Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation (BLIP) model. First, it generates a descriptive caption for an image. Then, it utilizes this caption to construct a prompt, which is subsequently used with OpenAI's GPT-3.5 to create engaging stories based on the provided picture.
|
22 |
+
|
23 |
+
## App Flow
|
24 |
+
|
25 |
+
<img src="https://github.com/sssingh/pic-to-story/blob/main/assets/app-design.png?raw=true" width="1000" height="450"/><br><br>
|
26 |
+
|
27 |
+
BLIP Image2Text model details can be found [here](https://huggingface.co/Sof22/image-caption-large-copy)
|
28 |
+
|
29 |
+
## App Details
|
30 |
+
|
31 |
+
* It's important to note that this sample demonstration app is hosted on the free tiers of Huggingface Spaces, which means it is functional but may exhibit slower performance.
|
32 |
+
* Additionally, when using the app for the first time or after an extended period (more than 1 hour), you might encounter an "Internal Error" message or receive a story unrelated to the provided image. This is a normal occurrence during the model loading process. Please wait a few seconds and try again; it should function as intended.
|
33 |
+
* Please be aware that due to cost and resource constraints, the app currently has a maximum story length limit of 200 words per request.
|
34 |
+
|
35 |
+
App UI is shown below:
|
36 |
+
|
37 |
+
<img src="https://github.com/sssingh/pic-to-story/blob/main/assets/story-teller-app.png?raw=true" width="1000" height="450"/><br><br>
|
38 |
+
|
39 |
+
**Dark Mode Toggle**: Activate it to switch between dark and light mode.
|
40 |
+
**Image Selector**: Click on it to pick an image from your computer, or drag and drop an image onto it directly. Click the 'X' to clear the selection and resets the app.
|
41 |
+
**Story Genre Dropdown**: Select the desired story genre from the dropdown list.
|
42 |
+
**Story Writing Style Dropdown**: Select the desired story writing style from the dropdown list.
|
43 |
+
**Story Length (in words) Slider**: Adjust the slider to specify the desired length of the generated story.
|
44 |
+
**Creativity Index Slider**: Modify the slider to indicate the desired level of creativity for the generated story. A range between 0.5 and 0.7 is recommended. Setting it to 1.0 results in highly creative, sometimes amusing output.
|
45 |
+
**Generate Story Button**: Press this button to initiate the story generation process.
|
46 |
+
**Clear Button**: Clears all settings and resets the app to its default state.
|
47 |
+
**Story Text Area**: This is where the generated story will be displayed.
|
48 |
+
**Example Section Expander**: Click to expand the section and access built-in examples for quick testing. Simply select an example, click "Generate Story," and no image upload will be necessary.
|
49 |
+
|
50 |
+
The app includes pre-defined examples for your convenience, allowing you to quickly test its capabilities. Explore the examples section, choose one, and click "Generate Story" without needing to upload an image.
|
51 |
+
|
52 |
+
<img src="https://github.com/sssingh/pic-to-story/blob/main/assets/story-teller-examples.png?raw=true" width="1000" height="350"/><br><br>
|
53 |
+
|
54 |
+
# Project Source
|
55 |
+
[👉 Visit GitHub Repo](https://github.com/sssingh/pic-to-story)
|
56 |
+
|
57 |
+
# Contact Me
|
58 |
+
[![email](https://img.shields.io/badge/Gmail-D14836?style=for-the-badge&logo=gmail&logoColor=white)](mailto:sunil@sunilssingh.me)
|
59 |
+
[![twitter](https://img.shields.io/badge/twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/@thesssingh)
|
60 |
+
[![linkedin](https://img.shields.io/badge/linkedin-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/sssingh/)
|
61 |
+
[![website](https://img.shields.io/badge/web_site-8B5BE8?style=for-the-badge&logo=ko-fi&logoColor=white)](https://sunilssingh.me)
|
62 |
+
|
app.py
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import model
|
3 |
+
from config import app_config
|
4 |
+
import mongo_utils as mongo
|
5 |
+
|
6 |
+
|
7 |
+
def clear():
|
8 |
+
return None, 50, 0.7, None, None
|
9 |
+
|
10 |
+
|
11 |
+
def create_interface():
|
12 |
+
js_enable_darkmode = """() =>
|
13 |
+
{
|
14 |
+
document.querySelector('body').classList.add('dark');
|
15 |
+
}"""
|
16 |
+
js_toggle_darkmode = """() =>
|
17 |
+
{
|
18 |
+
if (document.querySelectorAll('.dark').length) {
|
19 |
+
document.querySelector('body').classList.remove('dark');
|
20 |
+
} else {
|
21 |
+
document.querySelector('body').classList.add('dark');
|
22 |
+
}
|
23 |
+
}"""
|
24 |
+
|
25 |
+
with gr.Blocks(
|
26 |
+
title=app_config.title, theme=app_config.theme, css=app_config.css
|
27 |
+
) as app:
|
28 |
+
# enable darkmode
|
29 |
+
app.load(fn=None, inputs=None, outputs=None, _js=js_enable_darkmode)
|
30 |
+
with gr.Row():
|
31 |
+
darkmode_checkbox = gr.Checkbox(
|
32 |
+
label="Dark Mode", value=True, interactive=True
|
33 |
+
)
|
34 |
+
# toggle darkmode on/off when checkbox is checked/unchecked
|
35 |
+
darkmode_checkbox.change(
|
36 |
+
None, None, None, _js=js_toggle_darkmode, api_name=False
|
37 |
+
)
|
38 |
+
with gr.Row():
|
39 |
+
with gr.Column():
|
40 |
+
gr.Markdown(
|
41 |
+
"""
|
42 |
+
# The Storyteller
|
43 |
+
**This app can craft captivating narratives from captivating images,
|
44 |
+
potentially surpassing even Shakespearean standards.
|
45 |
+
<br>
|
46 |
+
Select an `Image` that inspires a story, choose a `Story Genre`,
|
47 |
+
`Story Writing Style`, `Story Length (up to 200 words)`, and
|
48 |
+
adjust the `Creativity Index` to enhance its creative flair. Then
|
49 |
+
hit `Generate Story` button.
|
50 |
+
Alternatively, just select one the pre-configured `Examples`**
|
51 |
+
<br>
|
52 |
+
Visit the [project's repo](https://github.com/sssingh/pic-to-story)
|
53 |
+
<br>
|
54 |
+
***Please exercise patience, as the models employed are extensive
|
55 |
+
and may require a few seconds to load. If you encounter an unrelated
|
56 |
+
story, it is likely still loading; wait a moment and try again.***
|
57 |
+
"""
|
58 |
+
)
|
59 |
+
with gr.Column():
|
60 |
+
max_count = gr.Textbox(
|
61 |
+
label="Max allowed OpenAI requests:",
|
62 |
+
value=app_config.openai_max_access_count,
|
63 |
+
)
|
64 |
+
curr_count = gr.Textbox(
|
65 |
+
label="Used up OpenAI requests:",
|
66 |
+
value=app_config.openai_curr_access_count,
|
67 |
+
)
|
68 |
+
available_count = gr.Textbox(
|
69 |
+
label="Available OpenAI requests:",
|
70 |
+
value=app_config.openai_max_access_count
|
71 |
+
- app_config.openai_curr_access_count,
|
72 |
+
)
|
73 |
+
with gr.Row():
|
74 |
+
with gr.Column():
|
75 |
+
image = gr.Image(
|
76 |
+
type="filepath",
|
77 |
+
)
|
78 |
+
with gr.Row():
|
79 |
+
with gr.Column():
|
80 |
+
genre = gr.Dropdown(
|
81 |
+
label="Story Genre: ",
|
82 |
+
value="Poetry",
|
83 |
+
choices=app_config.genre,
|
84 |
+
)
|
85 |
+
style = gr.Dropdown(
|
86 |
+
label="Story Writing Style:",
|
87 |
+
value="Cinematic",
|
88 |
+
choices=app_config.writing_style_list,
|
89 |
+
)
|
90 |
+
with gr.Column():
|
91 |
+
# Word Count Slider
|
92 |
+
word_count = gr.Slider(
|
93 |
+
label="Story Length (words):",
|
94 |
+
minimum=30,
|
95 |
+
maximum=200,
|
96 |
+
value=50,
|
97 |
+
step=10,
|
98 |
+
)
|
99 |
+
creativity = gr.Slider(
|
100 |
+
label="Creativity Index:",
|
101 |
+
minimum=0.3,
|
102 |
+
maximum=1.0,
|
103 |
+
value=0.7,
|
104 |
+
step=0.1,
|
105 |
+
)
|
106 |
+
with gr.Row():
|
107 |
+
submit_button = gr.Button(
|
108 |
+
value="Generate Story", elem_classes="orange-button"
|
109 |
+
)
|
110 |
+
clear_button = gr.ClearButton(elem_classes="gray-button")
|
111 |
+
with gr.Column():
|
112 |
+
story = gr.Textbox(
|
113 |
+
label="Story:",
|
114 |
+
placeholder="Generated story will appear here.",
|
115 |
+
lines=21,
|
116 |
+
)
|
117 |
+
with gr.Row():
|
118 |
+
with gr.Accordion("Expand for examples:", open=False):
|
119 |
+
gr.Examples(
|
120 |
+
examples=[
|
121 |
+
[
|
122 |
+
"assets/examples/cheetah-deer.jpg",
|
123 |
+
"Horror",
|
124 |
+
"Narrative",
|
125 |
+
80,
|
126 |
+
0.5,
|
127 |
+
],
|
128 |
+
[
|
129 |
+
"assets/examples/man-child-pet-dog.jpg",
|
130 |
+
"Fiction",
|
131 |
+
"Formal",
|
132 |
+
100,
|
133 |
+
0.6,
|
134 |
+
],
|
135 |
+
[
|
136 |
+
"assets/examples/man-child.jpeg",
|
137 |
+
"Children Literature",
|
138 |
+
"Symbolic",
|
139 |
+
120,
|
140 |
+
1.0,
|
141 |
+
],
|
142 |
+
[
|
143 |
+
"assets/examples/men-fighting.jpg",
|
144 |
+
"Comedy",
|
145 |
+
"Experimental",
|
146 |
+
60,
|
147 |
+
0.6,
|
148 |
+
],
|
149 |
+
[
|
150 |
+
"assets/examples/teacher-school.jpg",
|
151 |
+
"Surrealism",
|
152 |
+
"Non-linear",
|
153 |
+
100,
|
154 |
+
0.7,
|
155 |
+
],
|
156 |
+
],
|
157 |
+
fn=model.generate_story,
|
158 |
+
inputs=[image, genre, style, word_count, creativity],
|
159 |
+
outputs=[story, max_count, curr_count, available_count],
|
160 |
+
run_on_click=True,
|
161 |
+
)
|
162 |
+
submit_button.click(
|
163 |
+
fn=model.generate_story,
|
164 |
+
inputs=[image, genre, style, word_count, creativity],
|
165 |
+
outputs=[story, max_count, curr_count, available_count],
|
166 |
+
)
|
167 |
+
clear_button.click(
|
168 |
+
fn=clear, inputs=[], outputs=[image, word_count, creativity, story]
|
169 |
+
)
|
170 |
+
image.clear(fn=clear, inputs=[], outputs=[image, word_count, creativity, story])
|
171 |
+
|
172 |
+
return app
|
173 |
+
|
174 |
+
|
175 |
+
if __name__ == "__main__":
|
176 |
+
mongo.fetch_curr_access_count()
|
177 |
+
app = create_interface()
|
178 |
+
app.launch()
|
assets/app-design.png
ADDED
assets/examples/cheetah-deer.jpg
ADDED
assets/examples/man-child-pet-dog.jpg
ADDED
assets/examples/man-child.jpeg
ADDED
assets/examples/men-fighting.jpg
ADDED
assets/examples/teacher-school.jpg
ADDED
assets/story-teller-app.png
ADDED
assets/story-teller-examples.png
ADDED
assets/title.jpg
ADDED
config.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dataclasses import dataclass
|
3 |
+
|
4 |
+
|
5 |
+
@dataclass
|
6 |
+
class AppConfig:
|
7 |
+
title = "Picture to Story Generator"
|
8 |
+
theme = "freddyaboulton/dracula_revamped"
|
9 |
+
css = "style.css"
|
10 |
+
openai_max_access_count = 200
|
11 |
+
openai_curr_access_count = None
|
12 |
+
mongo_client = None
|
13 |
+
db = "mydb"
|
14 |
+
collection = "pic2story-openai-access-counter"
|
15 |
+
key = "current_count"
|
16 |
+
HF_TOKEN = os.getenv("HF_TOKEN")
|
17 |
+
# OPENAI_KEY = os.getenv("OPENAI_KEY")
|
18 |
+
# I2T_API_URL = os.getenv("I2T_API_URL")
|
19 |
+
# MONGO_CONN_STR = os.getenv("MONGO_CONN_STR")
|
20 |
+
genre_list = genre = [
|
21 |
+
"Adventure",
|
22 |
+
"Children Literature",
|
23 |
+
"Comedy",
|
24 |
+
"Drama",
|
25 |
+
"Fantasy",
|
26 |
+
"Fiction",
|
27 |
+
"Horror",
|
28 |
+
"Mystery",
|
29 |
+
"Non-fiction",
|
30 |
+
"Poetry",
|
31 |
+
"Romance",
|
32 |
+
"Satire",
|
33 |
+
"Surrealism",
|
34 |
+
"Urban Fantasy",
|
35 |
+
]
|
36 |
+
writing_style_list = [
|
37 |
+
"Cinematic",
|
38 |
+
"Conversational",
|
39 |
+
"Descriptive",
|
40 |
+
"Experimental",
|
41 |
+
"First-Person",
|
42 |
+
"Formal",
|
43 |
+
"Informal",
|
44 |
+
"Metaphorical",
|
45 |
+
"Minimalist",
|
46 |
+
"Narrative",
|
47 |
+
"Non-linear",
|
48 |
+
"Objective",
|
49 |
+
"Sensory",
|
50 |
+
"Stream of Consciousness",
|
51 |
+
"Symbolic",
|
52 |
+
"Third-Person Limited",
|
53 |
+
"Third-Person Omniscient",
|
54 |
+
]
|
55 |
+
OPENAI_KEY = "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"
|
56 |
+
# I2T_API_URL = (
|
57 |
+
# "https://api-inference.huggingface.co/models/Sof22/image-caption-large-copy"
|
58 |
+
# )
|
59 |
+
I2T_API_URL = ("https://api-inference.huggingface.co/models/Salesforce/blip2-opt-2.7b")
|
60 |
+
MONGO_CONN_STR = "mongodb+srv://sssingh:Topsycret1@cluster0.fcwxggj.mongodb.net/"
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
app_config = AppConfig()
|
model.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from langchain.chat_models import ChatOpenAI, ChatOllama #model server
|
3 |
+
from langchain_groq import ChatGroq
|
4 |
+
from langchain.chains import LLMChain
|
5 |
+
from langchain.prompts import (
|
6 |
+
PromptTemplate,
|
7 |
+
SystemMessagePromptTemplate,
|
8 |
+
HumanMessagePromptTemplate,
|
9 |
+
ChatPromptTemplate,
|
10 |
+
)
|
11 |
+
from config import app_config
|
12 |
+
import mongo_utils as mongo
|
13 |
+
GROQ_API_KEY = "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"
|
14 |
+
|
15 |
+
def __image2text(image):
|
16 |
+
"""Generates a short description of the image"""
|
17 |
+
headers = {"Authorization": app_config.HF_TOKEN}
|
18 |
+
try:
|
19 |
+
response = requests.post(app_config.I2T_API_URL, headers=headers, data=image)
|
20 |
+
response = response.json()[0]["generated_text"]
|
21 |
+
except Exception as e:
|
22 |
+
print(e)
|
23 |
+
return response
|
24 |
+
|
25 |
+
|
26 |
+
def __text2story(image_desc, genre, style, word_count, creativity):
|
27 |
+
""" "Generates a short story based on image description text prompt"""
|
28 |
+
## chat LLM model
|
29 |
+
# story_model = ChatOpenAI(
|
30 |
+
# model="gpt-3.5-turbo",
|
31 |
+
# openai_api_key=app_config.OPENAI_KEY,
|
32 |
+
# temperature=creativity,
|
33 |
+
# )
|
34 |
+
|
35 |
+
story_model = ChatGroq(model="llama3-8b-8192",
|
36 |
+
temperature=0.0,
|
37 |
+
api_key=GROQ_API_KEY)
|
38 |
+
|
39 |
+
## chat message prompts
|
40 |
+
sys_prompt = PromptTemplate(
|
41 |
+
template="""You are an expert story writer, write a maximum of {word_count}
|
42 |
+
words long story in {genre} genre in {style} writing style, based on the user
|
43 |
+
provided story-context.
|
44 |
+
""",
|
45 |
+
input_variables=["word_count", "genre", "style"],
|
46 |
+
)
|
47 |
+
system_msg_prompt = SystemMessagePromptTemplate(prompt=sys_prompt)
|
48 |
+
human_prompt = PromptTemplate(
|
49 |
+
template="story-context: {context}", input_variables=["context"]
|
50 |
+
)
|
51 |
+
human_msg_prompt = HumanMessagePromptTemplate(prompt=human_prompt)
|
52 |
+
chat_prompt = ChatPromptTemplate.from_messages(
|
53 |
+
[system_msg_prompt, human_msg_prompt]
|
54 |
+
)
|
55 |
+
## LLM chain
|
56 |
+
story_chain = LLMChain(llm=story_model, prompt=chat_prompt)
|
57 |
+
response = story_chain.run(
|
58 |
+
genre=genre, style=style, word_count=word_count, context=image_desc
|
59 |
+
)
|
60 |
+
return response
|
61 |
+
|
62 |
+
|
63 |
+
def generate_story(image_file, genre, style, word_count, creativity):
|
64 |
+
"""Generates a story given an image"""
|
65 |
+
# read image as bytes arrayS
|
66 |
+
with open(image_file, "rb") as f:
|
67 |
+
input_image = f.read()
|
68 |
+
# generate caption for image
|
69 |
+
image_desc = __image2text(image=input_image)
|
70 |
+
|
71 |
+
print("++++++++++++++++++++++++++++++++++++++")
|
72 |
+
print(image_desc)
|
73 |
+
print("++++++++++++++++++++++++++++++++++++++")
|
74 |
+
# generate story from caption
|
75 |
+
story = __text2story(
|
76 |
+
image_desc=image_desc,
|
77 |
+
genre=genre,
|
78 |
+
style=style,
|
79 |
+
word_count=word_count,
|
80 |
+
creativity=creativity,
|
81 |
+
)
|
82 |
+
# increment the openai access counter and compute count stats
|
83 |
+
mongo.increment_curr_access_count()
|
84 |
+
max_count = app_config.openai_max_access_count
|
85 |
+
curr_count = app_config.openai_curr_access_count
|
86 |
+
available_count = max_count - curr_count
|
87 |
+
return story, max_count, curr_count, available_count
|
mongo_utils.py
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pymongo
|
2 |
+
from config import app_config
|
3 |
+
|
4 |
+
|
5 |
+
# Generic functions
|
6 |
+
def get_db_client():
|
7 |
+
"""Returns MongoDB client object, connect to MongoDB Atlas instances if required"""
|
8 |
+
try:
|
9 |
+
if app_config.mongo_client == None:
|
10 |
+
client = pymongo.MongoClient(app_config.MONGO_CONN_STR)
|
11 |
+
app_config.mongo_client = client
|
12 |
+
except Exception as e:
|
13 |
+
print(e)
|
14 |
+
return app_config.mongo_client
|
15 |
+
|
16 |
+
|
17 |
+
def fetch_document(client, db, collection):
|
18 |
+
"""Get a single document from the provided db and collection"""
|
19 |
+
try:
|
20 |
+
document = client[db][collection].find_one()
|
21 |
+
except Exception as e:
|
22 |
+
print(e)
|
23 |
+
return document
|
24 |
+
|
25 |
+
|
26 |
+
def update_document(client, db, collection, key, value):
|
27 |
+
"""Update the passed key in the document for provided db and collection"""
|
28 |
+
try:
|
29 |
+
document = fetch_document(client, db, collection)
|
30 |
+
client[db][collection].update_one(
|
31 |
+
{"_id": document["_id"]},
|
32 |
+
{"$set": {key: value}},
|
33 |
+
)
|
34 |
+
except Exception as e:
|
35 |
+
print(e)
|
36 |
+
|
37 |
+
|
38 |
+
# Use case specific functions
|
39 |
+
def fetch_curr_access_count():
|
40 |
+
client = get_db_client()
|
41 |
+
curr_count = fetch_document(
|
42 |
+
client=client, db=app_config.db, collection=app_config.collection
|
43 |
+
)[app_config.key]
|
44 |
+
app_config.openai_curr_access_count = curr_count
|
45 |
+
|
46 |
+
|
47 |
+
def increment_curr_access_count():
|
48 |
+
client = get_db_client()
|
49 |
+
updated_count = app_config.openai_curr_access_count + 1
|
50 |
+
update_document(
|
51 |
+
client=client,
|
52 |
+
db=app_config.db,
|
53 |
+
collection=app_config.collection,
|
54 |
+
key=app_config.key,
|
55 |
+
value=updated_count,
|
56 |
+
)
|
57 |
+
app_config.openai_curr_access_count = updated_count
|
myenv/bin/Activate.ps1
ADDED
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<#
|
2 |
+
.Synopsis
|
3 |
+
Activate a Python virtual environment for the current PowerShell session.
|
4 |
+
|
5 |
+
.Description
|
6 |
+
Pushes the python executable for a virtual environment to the front of the
|
7 |
+
$Env:PATH environment variable and sets the prompt to signify that you are
|
8 |
+
in a Python virtual environment. Makes use of the command line switches as
|
9 |
+
well as the `pyvenv.cfg` file values present in the virtual environment.
|
10 |
+
|
11 |
+
.Parameter VenvDir
|
12 |
+
Path to the directory that contains the virtual environment to activate. The
|
13 |
+
default value for this is the parent of the directory that the Activate.ps1
|
14 |
+
script is located within.
|
15 |
+
|
16 |
+
.Parameter Prompt
|
17 |
+
The prompt prefix to display when this virtual environment is activated. By
|
18 |
+
default, this prompt is the name of the virtual environment folder (VenvDir)
|
19 |
+
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
20 |
+
|
21 |
+
.Example
|
22 |
+
Activate.ps1
|
23 |
+
Activates the Python virtual environment that contains the Activate.ps1 script.
|
24 |
+
|
25 |
+
.Example
|
26 |
+
Activate.ps1 -Verbose
|
27 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
28 |
+
and shows extra information about the activation as it executes.
|
29 |
+
|
30 |
+
.Example
|
31 |
+
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
32 |
+
Activates the Python virtual environment located in the specified location.
|
33 |
+
|
34 |
+
.Example
|
35 |
+
Activate.ps1 -Prompt "MyPython"
|
36 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
37 |
+
and prefixes the current prompt with the specified string (surrounded in
|
38 |
+
parentheses) while the virtual environment is active.
|
39 |
+
|
40 |
+
.Notes
|
41 |
+
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
42 |
+
execution policy for the user. You can do this by issuing the following PowerShell
|
43 |
+
command:
|
44 |
+
|
45 |
+
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
46 |
+
|
47 |
+
For more information on Execution Policies:
|
48 |
+
https://go.microsoft.com/fwlink/?LinkID=135170
|
49 |
+
|
50 |
+
#>
|
51 |
+
Param(
|
52 |
+
[Parameter(Mandatory = $false)]
|
53 |
+
[String]
|
54 |
+
$VenvDir,
|
55 |
+
[Parameter(Mandatory = $false)]
|
56 |
+
[String]
|
57 |
+
$Prompt
|
58 |
+
)
|
59 |
+
|
60 |
+
<# Function declarations --------------------------------------------------- #>
|
61 |
+
|
62 |
+
<#
|
63 |
+
.Synopsis
|
64 |
+
Remove all shell session elements added by the Activate script, including the
|
65 |
+
addition of the virtual environment's Python executable from the beginning of
|
66 |
+
the PATH variable.
|
67 |
+
|
68 |
+
.Parameter NonDestructive
|
69 |
+
If present, do not remove this function from the global namespace for the
|
70 |
+
session.
|
71 |
+
|
72 |
+
#>
|
73 |
+
function global:deactivate ([switch]$NonDestructive) {
|
74 |
+
# Revert to original values
|
75 |
+
|
76 |
+
# The prior prompt:
|
77 |
+
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
78 |
+
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
79 |
+
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
80 |
+
}
|
81 |
+
|
82 |
+
# The prior PYTHONHOME:
|
83 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
84 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
85 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
86 |
+
}
|
87 |
+
|
88 |
+
# The prior PATH:
|
89 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
90 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
91 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
92 |
+
}
|
93 |
+
|
94 |
+
# Just remove the VIRTUAL_ENV altogether:
|
95 |
+
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
96 |
+
Remove-Item -Path env:VIRTUAL_ENV
|
97 |
+
}
|
98 |
+
|
99 |
+
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
100 |
+
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
101 |
+
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
102 |
+
}
|
103 |
+
|
104 |
+
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
105 |
+
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
106 |
+
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
107 |
+
}
|
108 |
+
|
109 |
+
# Leave deactivate function in the global namespace if requested:
|
110 |
+
if (-not $NonDestructive) {
|
111 |
+
Remove-Item -Path function:deactivate
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
<#
|
116 |
+
.Description
|
117 |
+
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
118 |
+
given folder, and returns them in a map.
|
119 |
+
|
120 |
+
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
121 |
+
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
122 |
+
then it is considered a `key = value` line. The left hand string is the key,
|
123 |
+
the right hand is the value.
|
124 |
+
|
125 |
+
If the value starts with a `'` or a `"` then the first and last character is
|
126 |
+
stripped from the value before being captured.
|
127 |
+
|
128 |
+
.Parameter ConfigDir
|
129 |
+
Path to the directory that contains the `pyvenv.cfg` file.
|
130 |
+
#>
|
131 |
+
function Get-PyVenvConfig(
|
132 |
+
[String]
|
133 |
+
$ConfigDir
|
134 |
+
) {
|
135 |
+
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
136 |
+
|
137 |
+
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
138 |
+
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
139 |
+
|
140 |
+
# An empty map will be returned if no config file is found.
|
141 |
+
$pyvenvConfig = @{ }
|
142 |
+
|
143 |
+
if ($pyvenvConfigPath) {
|
144 |
+
|
145 |
+
Write-Verbose "File exists, parse `key = value` lines"
|
146 |
+
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
147 |
+
|
148 |
+
$pyvenvConfigContent | ForEach-Object {
|
149 |
+
$keyval = $PSItem -split "\s*=\s*", 2
|
150 |
+
if ($keyval[0] -and $keyval[1]) {
|
151 |
+
$val = $keyval[1]
|
152 |
+
|
153 |
+
# Remove extraneous quotations around a string value.
|
154 |
+
if ("'""".Contains($val.Substring(0, 1))) {
|
155 |
+
$val = $val.Substring(1, $val.Length - 2)
|
156 |
+
}
|
157 |
+
|
158 |
+
$pyvenvConfig[$keyval[0]] = $val
|
159 |
+
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
return $pyvenvConfig
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
<# Begin Activate script --------------------------------------------------- #>
|
168 |
+
|
169 |
+
# Determine the containing directory of this script
|
170 |
+
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
171 |
+
$VenvExecDir = Get-Item -Path $VenvExecPath
|
172 |
+
|
173 |
+
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
174 |
+
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
175 |
+
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
176 |
+
|
177 |
+
# Set values required in priority: CmdLine, ConfigFile, Default
|
178 |
+
# First, get the location of the virtual environment, it might not be
|
179 |
+
# VenvExecDir if specified on the command line.
|
180 |
+
if ($VenvDir) {
|
181 |
+
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
182 |
+
}
|
183 |
+
else {
|
184 |
+
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
185 |
+
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
186 |
+
Write-Verbose "VenvDir=$VenvDir"
|
187 |
+
}
|
188 |
+
|
189 |
+
# Next, read the `pyvenv.cfg` file to determine any required value such
|
190 |
+
# as `prompt`.
|
191 |
+
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
192 |
+
|
193 |
+
# Next, set the prompt from the command line, or the config file, or
|
194 |
+
# just use the name of the virtual environment folder.
|
195 |
+
if ($Prompt) {
|
196 |
+
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
197 |
+
}
|
198 |
+
else {
|
199 |
+
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
200 |
+
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
201 |
+
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
202 |
+
$Prompt = $pyvenvCfg['prompt'];
|
203 |
+
}
|
204 |
+
else {
|
205 |
+
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
206 |
+
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
207 |
+
$Prompt = Split-Path -Path $venvDir -Leaf
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
Write-Verbose "Prompt = '$Prompt'"
|
212 |
+
Write-Verbose "VenvDir='$VenvDir'"
|
213 |
+
|
214 |
+
# Deactivate any currently active virtual environment, but leave the
|
215 |
+
# deactivate function in place.
|
216 |
+
deactivate -nondestructive
|
217 |
+
|
218 |
+
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
219 |
+
# that there is an activated venv.
|
220 |
+
$env:VIRTUAL_ENV = $VenvDir
|
221 |
+
|
222 |
+
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
223 |
+
|
224 |
+
Write-Verbose "Setting prompt to '$Prompt'"
|
225 |
+
|
226 |
+
# Set the prompt to include the env name
|
227 |
+
# Make sure _OLD_VIRTUAL_PROMPT is global
|
228 |
+
function global:_OLD_VIRTUAL_PROMPT { "" }
|
229 |
+
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
230 |
+
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
231 |
+
|
232 |
+
function global:prompt {
|
233 |
+
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
234 |
+
_OLD_VIRTUAL_PROMPT
|
235 |
+
}
|
236 |
+
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
237 |
+
}
|
238 |
+
|
239 |
+
# Clear PYTHONHOME
|
240 |
+
if (Test-Path -Path Env:PYTHONHOME) {
|
241 |
+
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
242 |
+
Remove-Item -Path Env:PYTHONHOME
|
243 |
+
}
|
244 |
+
|
245 |
+
# Add the venv to the PATH
|
246 |
+
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
247 |
+
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
myenv/bin/activate
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file must be used with "source bin/activate" *from bash*
|
2 |
+
# you cannot run it directly
|
3 |
+
|
4 |
+
deactivate () {
|
5 |
+
# reset old environment variables
|
6 |
+
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
7 |
+
PATH="${_OLD_VIRTUAL_PATH:-}"
|
8 |
+
export PATH
|
9 |
+
unset _OLD_VIRTUAL_PATH
|
10 |
+
fi
|
11 |
+
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
12 |
+
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
13 |
+
export PYTHONHOME
|
14 |
+
unset _OLD_VIRTUAL_PYTHONHOME
|
15 |
+
fi
|
16 |
+
|
17 |
+
# Call hash to forget past commands. Without forgetting
|
18 |
+
# past commands the $PATH changes we made may not be respected
|
19 |
+
hash -r 2> /dev/null
|
20 |
+
|
21 |
+
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
22 |
+
PS1="${_OLD_VIRTUAL_PS1:-}"
|
23 |
+
export PS1
|
24 |
+
unset _OLD_VIRTUAL_PS1
|
25 |
+
fi
|
26 |
+
|
27 |
+
unset VIRTUAL_ENV
|
28 |
+
unset VIRTUAL_ENV_PROMPT
|
29 |
+
if [ ! "${1:-}" = "nondestructive" ] ; then
|
30 |
+
# Self destruct!
|
31 |
+
unset -f deactivate
|
32 |
+
fi
|
33 |
+
}
|
34 |
+
|
35 |
+
# unset irrelevant variables
|
36 |
+
deactivate nondestructive
|
37 |
+
|
38 |
+
VIRTUAL_ENV=$(cygpath "C:\Users\itsja\Documents\AI_IMG\pic-to-story\myenv")
|
39 |
+
export VIRTUAL_ENV
|
40 |
+
|
41 |
+
_OLD_VIRTUAL_PATH="$PATH"
|
42 |
+
PATH="$VIRTUAL_ENV/bin:$PATH"
|
43 |
+
export PATH
|
44 |
+
|
45 |
+
# unset PYTHONHOME if set
|
46 |
+
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
47 |
+
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
48 |
+
if [ -n "${PYTHONHOME:-}" ] ; then
|
49 |
+
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
50 |
+
unset PYTHONHOME
|
51 |
+
fi
|
52 |
+
|
53 |
+
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
54 |
+
_OLD_VIRTUAL_PS1="${PS1:-}"
|
55 |
+
PS1="(myenv) ${PS1:-}"
|
56 |
+
export PS1
|
57 |
+
VIRTUAL_ENV_PROMPT="(myenv) "
|
58 |
+
export VIRTUAL_ENV_PROMPT
|
59 |
+
fi
|
60 |
+
|
61 |
+
# Call hash to forget past commands. Without forgetting
|
62 |
+
# past commands the $PATH changes we made may not be respected
|
63 |
+
hash -r 2> /dev/null
|
myenv/bin/pip.exe
ADDED
Binary file (108 kB). View file
|
|
myenv/bin/pip3.11.exe
ADDED
Binary file (108 kB). View file
|
|
myenv/bin/pip3.exe
ADDED
Binary file (108 kB). View file
|
|
myenv/bin/python.exe
ADDED
Binary file (157 kB). View file
|
|
myenv/bin/python3.11.exe
ADDED
Binary file (157 kB). View file
|
|
myenv/bin/python3.exe
ADDED
Binary file (157 kB). View file
|
|
myenv/bin/python3w.exe
ADDED
Binary file (157 kB). View file
|
|
myenv/bin/pythonw.exe
ADDED
Binary file (157 kB). View file
|
|
myenv/pyvenv.cfg
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
home = C:\msys64\mingw64\bin
|
2 |
+
include-system-site-packages = false
|
3 |
+
version = 3.11.9
|
4 |
+
executable = C:\msys64\mingw64\bin\python.exe
|
5 |
+
command = C:\msys64\mingw64\bin\python.exe -m venv C:\Users\itsja\Documents\AI_IMG\pic-to-story\myenv
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio==3.45.*
|
2 |
+
requests==2.29.*
|
3 |
+
langchain==0.0.*
|
4 |
+
openai==0.27.*
|
5 |
+
pymongo[tls, srv]==4.4.*
|
style.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.orange-button {
|
2 |
+
background-color: rgb(21, 255, 0) !important;
|
3 |
+
}
|
4 |
+
|
5 |
+
.gray-button {
|
6 |
+
background-color: #411d5a !important;
|
7 |
+
}
|
8 |
+
|
9 |
+
footer {
|
10 |
+
visibility: hidden;
|
11 |
+
}
|
test.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import openai
|
2 |
+
|
3 |
+
openai.api_key = 'fake-api'
|
4 |
+
openai.base_url = "http://localhost:3040/v1/"
|
5 |
+
|
6 |
+
completion = openai.chat.completions.create(
|
7 |
+
model="gpt-3.5-turbo",
|
8 |
+
messages=[
|
9 |
+
{"role": "user", "content": "How do I list all files in a directory using Python?"},
|
10 |
+
],
|
11 |
+
)
|
12 |
+
|
13 |
+
print(completion.choices[0].message.content)
|