Midjourney 유료

StableDiffusion 오픈소스

 

prompt 기반 이미지 생성 AI

 

stable diffusion collecting package (WebUI .ver)

mpmath, typing-extensions, sympy, pillow, numpy, networkx, MarkupSafe, fsspec, filelock, jinja2, torch, torchvision

gradio

 

gradio로  로컬서버 열고 jinja로 와꾸 짜놓음

 

https://huggingface.co/models?pipeline_tag=text-to-image&sort=downloads

 

Models - Hugging Face

Active filters: text-to-image Clear all

huggingface.co

 

모델 ckpt ( = checkpoint) 파일 구하는 사이트.

프로젝트 폴더 들어가보면 친절하게 여기다가 ckpt파일 넣으라고 텍스트로 적어놓음

 

.safetensor 라는 확장자도 있는데 그냥 체크포인트 파일을 안정성있게 바꿔놓은 파일.

그냥 같은 체크포인트 파일이니까 같은데다 넣어서 쓰면된다.

 

 

 

[Midjourney]

 

프롬프트  옵션

--ar 16:9 비율 (aspect ratio)

--no fish 뒤에오는 객체 제거

 

 

<캐릭터 시트 만드는 프롬프트>

### Women, full body, front view, side view, back(=rear) view --niji 6

TurnTable 캐릭터 원화 제작

일관성있는 캐릭터 시트 제작 가능

 

<표정 + 동작 추가>

<캐릭터 시트 만드는 프롬프트>, (full body), different poses, different positions and expression

Vary (subtle)로 추가 생성

 

Remix 기능으로 기존 생성된 이미지에 편집하는 형식으로 새로운 이미지 생성 가능

 

로고도 만들수있음

 

 

[ComfyUI]

StableDiffusion 보다 비 개발자 친화적인? 노드 기반, 스테이블디퓨전을 사용하는 인터페이스.

스테이블디퓨전 깔아서 사용중이면 딱히 쓸 필요는 없지만 노드기반이라 이쪽이 편한 사람은 쓰면 좋음

 

프로젝트 폴더/

ComfyUI 실행 커맨드  :  python3 main.py

StableDiffusion 커맨드 : ./webui.sh

 

 

mongoDB는 bson 형식으로 된 objectId를 document의 기본값으로 사용하므로 먼저 해당 라이브러리를 설치해준다

from bson.objectid import ObjectId

 

 

꺼내쓸 때

        commentfind = list(db.comment.find({'posting': id_receive}))
        for a in commentfind:
            a['_id'] = str(a['_id'])

 

기본으로 넣어주는 objectId까지 꺼내와서 string으로 형변환해서 쓰면 id값만 남는다

 

 

찾을 때

        id_receive = '31o32j3h1iwqeqe523'

        commentfind = db.comment.find_one({'_id': ObjectId(id_receive)})

        if commentfind is not None and commentfind['password'] == pwd_receive:
            db.comment.delete_one({'_id': ObjectId(id_receive)})
            return jsonify({"msg": "댓글 삭제 완료"})

 

ObjectId() 메소드에 id값을 넣어 형변환 해주면 된다

 

 

넣을 때는 기본값이라 지가 알아서 드간다 신경 쓸 필요없음

따로 id filed 값을 관계된 테이블의 속성으로 저장하지 않으려면

mongodb의 outer join을 해서 사용해야 하는데 나중에 해봐야겠다

프론트와 데이터 주고 받을 때

api 사용할 때

DB에 낑겨넣을 때

제일 많이 사용하는 형태라 어떻게 만들지 고민해봤다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    for location in locations:
        a = location.select_one('div > div.header-wrap > div.header-inner-wrap > h2')
        b = location.select_one('div > div.content-wrap > div.description-wrap > p')
 
        if a is not None or b is not None:
            title = a.text
            desc = b.text
 
            # print(title + '\n' + desc + '\n' + image + '\n')
            # 반복문 돌아가며 딕셔너리 배열로 만들기
            locationlist += [{
                'title': title,
                'desc': desc
            }]
 
cs

 

[ {'title':'title','desc':'desc'}, {'title':'title','desc':'desc'}, {'title':'title','desc':'desc'} ]

위와 같은 형태로 만들어진다

 

배열끼리 합칠 때 그냥 + 하면 되길래 해봤는데 된다

 

왜 되는거지...

 

다른 분이 만든걸 봤는데 list에 append 메소드를 사용한다.

append도 사용해 봐야겠다

 

서버에 파일 저장, DB에 이름을 저장해 꺼내쓸 때를 위한 서버 코드를 만들어보았다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
import os
import random
import string
import requests
from flask import Flask, render_template, request, jsonify, redirect, session
 
 
@app.route("/post", methods=["POST""GET"])
def post():
    # 요청은 form에서 동기화 방식으로 처리됩니다. form 속성의 enctype을 file 전송에 적합한 multipart/form-data으로 변경해주세요.
    # 비동기 처리를 원하면 ajax 같은거 쓰셈
    if request.method == 'POST':
 
        # file은 request.files로 받아 옵니다
        title_receive = request.form['title']
        desc_receive = request.form['desc']
        writerid_receive = request.form['writerid']
        star_receive = request.form['star']
        file_receive = request.files['file']
 
        path = "./static/images/"
 
        # 파일 이름에 랜덤 문자열 삽입
        length_of_string = 8
        random_string = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length_of_string))
        receive_filename = file_receive.filename
        index_temp = receive_filename.find(".")
        filename = receive_filename[:index_temp] + random_string + receive_filename[index_temp:]
 
        # 이미지 업로드 경로가 존재 하지 않을 경우 생성
        if not os.path.exists(path):
            os.mkdir(path)
 
        # 설정한 저장 경로에 파일 이름으로 저장
        file_receive.save(path + filename)
 
        # DB에 보낼 데이터 dict 저장
        doc = {
            'title': title_receive,
            'desc': desc_receive,
            'writerid': writerid_receive,
            'star'int(star_receive),
            'file': filename
        }
 
        # DB에 저장
        db.posting.insert_one(doc)
 
        success_msg = "포스팅 완료되었습니다"
 
        return render_template("gangneung/post.html", success_msg=success_msg)
 
    return render_template("gangneung/post.html")
 
cs

 

파일 네임을 경로로 만들어 나쁜 짓을 꾸미는 못된 악당을 막으려면

from werkzeug import secure_filename

라이브러리 넣어주고

파일 이름에 랜덤 문자열 삽입해주기 전에 secure_filename(filename) 을 쓰면 된다

특문 같은걸 마음대로 바꿔버리는 메소드이니 몇 번 테스트해보길 권장

 

string.ascii_letters는 아스키 코드에 기반한 a-f, A-F 가 문자열로 들어있다 (아스키 기반이기에 로컬 설정에서 자유롭다)

string.digit은 0~9 들어있는 배열이고 그 둘을 합쳐서 문자열로 만든담에 random.choice 메소드로 한개씩 야무지게 뽑아낸다

 

하지만 이렇게 작성하면 "."이 여러개 들어간 파일의 경우 처리가 안되므로 rfind() 서비스메소드를 활용해 마지막 "."을 가져오는 방법을 사용하면서 조건문으로 확장자 타입을 처리해줘야 한다

 

참고 : https://docs.python.org/ko/3/library/string.html?highlight=string#module-string

 

이_언어는_+_하면_왠만하면_되서_신기해

 

'Development > Python' 카테고리의 다른 글

pymongo로 mongoDB objectId 사용하기  (0) 2022.09.03
반복문 돌려가며 Dictionarys in Array 로 만들기  (0) 2022.08.28
Flask session 사용  (0) 2022.08.21
git-bash 서버 환경설정 (ubuntu, python-flask)  (0) 2022.07.24
Flask  (0) 2022.07.23
1
from flask import Flask, session
cs

 

import 해서 쓴다

 

 

1
2
3
app.secret_key = 'secretkey'
session.permanent = True
app.permanent_session_lifetime = timedelta(seconds=10)
cs

 

secret_key를 어렵게 해서 만들어 줘야만 함

 

session.permanent는 session의 사용시간을 영구적으로 사용할지에 대한 옵션이다

-기본값 False

(그런데 True로 안해주면 lifetime 제어가 안먹히더라)

 

app.permanent_session_lifetime = timedelta(seconds=10) 은 세션의 사용시간 설정이다

-minuts, hour 등의 옵션이 있다

 

 

1
2
3
4
if 'username' in session:  # session안에 username이 있으면 로그인
    return render_template('index_login.html', current_user=session['username'])
 
session.pop('username'None)
cs

 

사용하는 걸 보면 알 수 있는 것처럼 List 타입 사용하는 것처럼 쓰면 된다 

아마 중복이 되면 안될테니 Set 타입의 컬렉션일 듯하다

 

session이라 붙여놓고 cookie에 들어오길래 진정한 정체가 뭔지 알 수 없는 이상한 기능이다

(session은 서버에서 저장, cookie는 사용자 브라우저에 저장)

 

브라우저 개발자 도구를 통해 확인해 보니 GC가 동작하지 않는지, 아니면 느려서 그런지

그도 아니면 그냥 key 값만 남기고 value는 빈문자열인 상태로 메모리에 상주하는지 로그아웃 구현 후에도 계속 남아있다

(어차피 session이라면 브라우저 종료 시 사라지겠지만 개발자도구에 cookie라고 표기 되어있는게 찜찜함)

 

 

그래서

1
2
3
4
def do_logout():
    session.pop('username'None)
    app.permanent_session_lifetime = timedelta(seconds=0)
    return jsonify({'msg''세션이 종료 되었습니다!'})
cs

 

데스노트 조작으로 없애버림

 

찾아보니 킹택갓버플로우에도 session.permanent와 app.permanent_session_lifetime을 전역으로 사용하지 않고 쿼리마다 사용하라고 응답해주는 글이 있더라

 

흠터레스팅

왜 되는건지 모르겠네

# 원격 접속 (원격접속키 OS@공개ip주소)
ssh -i 키파일붙여넣기 ubuntu@공개ip

# python3 -> python   // python3 명령어를 python으로 사용할 수 있게 하는 명령어
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

# pip3 설치
sudo apt-get update
sudo apt-get install -y python3-pip

# pip3 대신 pip 라고 입력하기 위한 명령어
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

# port forwarding  // 80포트(http)로 들어오는 요청을 5000포트로 넘겨주는 명령어
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000

→ 80포트: HTTP 접속을 위한 기본포트
→ 5000포트: flask 기본포트

# pip 설치 명령어
pip install 라이브러리|프레임워크

# 파이썬 파일 실행
python app.py

## **nohup 설정하기**
- 원격 접속을 종료하더라도 서버가 계속 돌아가게 하기
nohup python app.py &

- 서버 종료하기 - 강제종료하는 방법
ps -ef | grep 'python app.py' | awk '{print $2}' | xargs kill

 

 

코드 변경 후 og태그 초기화 주소

- 페이스북 og 태그 초기화 하기: [https://developers.facebook.com/tools/debug/](https://developers.facebook.com/tools/debug/)
- 카카오톡 og 태그 초기화 하기: [https://developers.kakao.com/tool/clear/og](https://developers.kakao.com/tool/clear/og)

 

 

CLI 자주 쓰는 명령어

ls: 내 위치의 모든 파일을 보여준다.

pwd: 내 위치(폴더의 경로)를 알려준다.

mkdir: 내 위치 아래에 폴더를 하나 만든다.

cd [갈 곳]: 나를 [갈 곳] 폴더로 이동시킨다.

cd .. : 나를 상위 폴더로 이동시킨다.

cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기

rm -rf [지울 것]: 지우기

sudo [실행 할 명령어] : 명령어를 관리자 권한으로 실행한다.
sudo su : 관리가 권한으로 들어간다. (나올때는 exit으로 나옴)

'Development > Python' 카테고리의 다른 글

반복문 돌려가며 Dictionarys in Array 로 만들기  (0) 2022.08.28
Flask, mongoDb 사용하여 파일 저장 기능 만들기  (0) 2022.08.28
Flask session 사용  (0) 2022.08.21
Flask  (0) 2022.07.23
python, mongoDb  (0) 2022.07.22

Flask Web Framework

파이썬으로 웹 개발을 하기 위한 프레임워크 중 하나.

서버를 쉽게 만들 수 있다.

django와 함께 파이썬 웹 프레임워크의 양대산맥이며 각기 장단점이 존재한다.

 

Flask - 가볍고 자유로움 (모듈의 선택폭이 넓음)

Django - 편리하고 생산성이 높음(자체 내장 기능으로 익숙해지면 DB 관리가 쉽다)

 

django가 상대적으로  사용자 수는 많아 소스 구하기는 쉽다고 한다.

 

 

 

Flask 기본 폴더구조 

Projects

  ㄴstatic 폴더 (이미지, css파일)

  ㄴtemplates 폴더 (html파일)

  ㄴapp.py 파일

 

 

flask 시작 코드)

1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
 
@app.route('/')
def home():
   return 'This is Home!'
 
if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)
cs

http://localhost:5000/ 에 접속해서 로컬(개인) 호스트 작업이 가능하다.

 

 

flask url 나누기)

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask
app = Flask(__name__)
 
@app.route('/')
def home():
   return 'This is Home!'
 
@app.route('/mypage')
def mypage():  
   return 'This is My Page!'
 
if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)
cs

 

 

flask html 파일 불러오기)

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask, render_template
app = Flask(__name__)
 
## URL 별로 함수명이 같거나,
## route('/') 등의 주소가 같으면 안됩니다.
 
@app.route('/')
def home():
   return render_template('index.html')
 
if __name__ == '__main__':
   app.run('0.0.0.0', port=5000, debug=True)
cs

 

 

데이터 주고 받는 법

0) jquery import  (html)

1
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
cs

 

1) request,  jsonify import  (python)

1
from flask import Flask, render_template, request, jsonify
cs

 

GET 요청 API코드  (python)

1
2
3
4
5
@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success''msg''이 요청은 GET!'})
cs

 

GET 요청 확인 Ajax코드  (html)

1
2
3
4
5
6
7
8
$.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
    }
  })
cs

 

POST 요청 API코드  (python)

1
2
3
4
5
@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success''msg''이 요청은 POST!'})
cs

 

POST 요청 확인 Ajax코드  (html)

1
2
3
4
5
6
7
8
$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
    }
  })
cs

 

 

HTTP 요청 메서드

프론트에서 백으로 넘겨줄 데이터가 없을 때는 GET

프론트에서 백으로 넘겨줄 데이터가 있을 때는 POST를 자주 사용한다.

웹 개발용 python 라이브러리

 

 

 

requests

python에서 ajax처럼 데이터를 받기 위한 라이브러리

 

사용 예)

1
2
3
4
5
6
7
8
9
import requests # requests 라이브러리 설치 필요
 
= requests.get('URL')
rjson = r.json()
 
gus = rjson['RealtimeCityAir']['row']
 
for gu in gus:
    print(gu['MSRSTE_NM'], gu['IDEX_MVL'])
cs

 

 

 

bs4 > BeautifulSoup

html 긁어올 때 사용

 

사용 예)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
from bs4 import BeautifulSoup
 
# URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
 
# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')
 
# select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr')
 
# movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    if a_tag is not None:
        # a의 text를 찍어본다.
        print (a_tag.text)
cs

선택자 사용 법)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')
 
soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')
 
# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')
 
# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
cs

태그 안의 텍스트를 찍고 싶을 땐 → 태그.text

태그 안의 속성을 찍고 싶을 땐 → 태그['속성']

 

 

 

pymongo > MongoClient

mongodb 제어

 

사용 예)

1
2
3
4
5
6
7
8
9
10
from pymongo import MongoClient
client = MongoClient('여기에 URL 입력')
db = client.mydb
 
doc = {
    'name':'bob',
    'age':27
}
 
db.users.insert_one(doc)
cs

사용 예2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
 
# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})
 
# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))
 
# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
 
# 지우기 - 예시
db.users.delete_one({'name':'bobby'})
cs

 

 

 

dnspython

python용 dnstoolkit

https://www.dnspython.org/examples/

+ Recent posts