Initial commit

This commit is contained in:
sykweon
2025-01-17 09:40:10 +09:00
commit d9f9cdd39b
12 changed files with 456 additions and 0 deletions

197
.gitignore vendored Executable file
View File

@@ -0,0 +1,197 @@
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,python
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,python
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python
src/__pycache__/web_server.cpython-39.pyc
src/common/__pycache__/const.cpython-39.pyc

3
README.md Executable file
View File

@@ -0,0 +1,3 @@
# AI IMAGE GENERATOR WEB MONITOR
AI 이미지 생성 웹 모니터

3
requirements.txt Executable file
View File

@@ -0,0 +1,3 @@
fastapi==0.83.0
uvicorn==0.16.0
jinja2==3.0.3

2
src/common/const.py Executable file
View File

@@ -0,0 +1,2 @@
# WEB SERVER PORT
SERVICE_PORT = 51001

65
src/static/css/style.css Executable file
View File

@@ -0,0 +1,65 @@
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #ece9e6, #ffffff);
color: #444;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.title_zone {
margin-bottom: 25px;
text-align: center;
}
.title {
font-size: 36px;
font-weight: bold;
color: #323232;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
}
.img_generator_model_zone_1, .img_generator_model_zone_2 {
background-color: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 10px;
padding: 25px;
margin: 30px;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
width: 35%;
text-align: center;
}
.model_name {
font-size: 20px;
margin-bottom: 15px;
color: #555;
}
.input_txt_box {
width: calc(100% - 20px);
padding: 12px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 14px;
box-sizing: border-box;
}
.generator_btn_zone {
text-align: center;
}
.generator_btn {
background-color: #646464;
color: #fff;
border: none;
padding: 10px 25px;
font-size: 15px;
border-radius: 5px;
cursor: pointer;
}

33
src/static/js/api.js Executable file
View File

@@ -0,0 +1,33 @@
/*
@File: api.js
@Date: 2025-01-16
@author: DaoolDNS
@brief: AI 이미지 생성 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
*/
//post data func
function postData(url = '', data = {}) {
return fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then((response) => {
if(response.status == 422) {
throw new Error('Unprocessable Entity(Code: 422)')
}
return response.json()
})
.catch(error => console.error(error)) // parses JSON response into native JavaScript objects
}

17
src/static/js/config.js Executable file
View File

@@ -0,0 +1,17 @@
/*
@File: config.js
@Date: 2025-01-16
@author: A2TEC
@brief: G 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
*/
const REST_SERVER = {
IP: "192.168.200.230",
PORT: 51000
}
const DALLE3_REQUEST_URL = "/api/services/imageGenerate/dalle3"
const IMAGEN_REQUEST_URL = "/api/services/imageGenerate/imagen"

12
src/static/js/const.js Executable file
View File

@@ -0,0 +1,12 @@
/*
@File: const.js
@Date: 2025-01-16
@author: A2TEC
@brief: G 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
*/
const inputTxtBox1 = $('#input_txt_box_1')
const inputTxtBox2 = $('#input_txt_box_2')

4
src/static/js/jquery.min.js vendored Executable file

File diff suppressed because one or more lines are too long

35
src/static/js/utility.js Executable file
View File

@@ -0,0 +1,35 @@
/*
@File: utility.js
@Date: 2025-01-16
@author: DaoolDNS
@brief: AI 이미지 생성 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
*/
let apiRequestBody = { "prompt": "" }
function generatorBtn1() {
try {
const apiUrl = `http://${REST_SERVER.IP}:${REST_SERVER.PORT}${DALLE3_REQUEST_URL}`
apiRequestBody.prompt = inputTxtBox1.val()
postData(apiUrl, apiRequestBody)
}
catch (error) {
console.error(`Error: ${error.name}`)
}
}
function generatorBtn2() {
try {
const apiUrl = `http://${REST_SERVER.IP}:${REST_SERVER.PORT}${IMAGEN_REQUEST_URL}`
apiRequestBody.prompt = inputTxtBox2.val()
postData(apiUrl, apiRequestBody)
}
catch (error) {
console.error(`Error: ${error.name}`)
}
}

48
src/templates/index.html Executable file
View File

@@ -0,0 +1,48 @@
<!---
@File: index.html
@Date: 2025-01-16
@author: A2TEC
@brief: G 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
-->
<!DOCTYPE html>
<html lang="en">
<!-- <head> -->
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ImageGenerator</title>
<script src="static/js/jquery.min.js"></script>
<script src="static/js/config.js"></script>
<link rel="stylesheet" href="static/css/style.css" type="text/css">
</head>
<body>
<div class="title_zone">
<span class="title">AI Image Generator</span>
</div>
<div class="img_generator_model_zone_1">
<span class="model_name">DALL-E 3</span>
<div>
<input type="text" id="input_txt_box_1" class="input_txt_box" placeholder="입력하세요.">
</div>
<div class="generator_btn_zone">
<button onclick="generatorBtn1()" id="generator_1_btn" class="generator_btn">Create</button>
</div>
</div>
<div class="img_generator_model_zone_2">
<span class="model_name">Imagen</span>
<div>
<input type="text" id="input_txt_box_2" class="input_txt_box" placeholder="입력하세요.">
</div>
<div class="generator_btn_zone">
<button onclick="generatorBtn2()" id="generator_1_btn" class="generator_btn">Create</button>
</div>
</div>
<script src="static/js/const.js"></script>
<script src="static/js/api.js"></script>
<script src="static/js/utility.js"></script>
</body>
</html>

37
src/web_server.py Executable file
View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
"""
@File: web_server.py
@Date: 2025-01-16
@author: DaoolDNS
@brief: AI 이미지 생성 웹 서버
@section MODIFYINFO 수정정보
- 수정자/수정일 : 수정내역
- 2025-01-16/ksy : base
"""
import uvicorn
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from common.const import SERVICE_PORT
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
"""
메인화면 접속
:return: index.html
"""
return templates.TemplateResponse("index.html", {"request": request})
if __name__ == '__main__':
uvicorn.run("web_server:app", host='0.0.0.0', port=SERVICE_PORT)