가장 인기있는 스크립트언어


<aside> 💡

파이썬

프레임워크

작동방식

표준문법

with 함수() as 변수

표준라이브러리

Path()

</aside>

<aside> 💡

Python

</aside>

표준모듈 (문서) 설명
os 운영 체제 관련 기능을 제공합니다.
time 시간 관련 기능을 제공합니다.
random 난수 생성과 관련된 기능을 제공합니다.
functools 고차 함수와 관련된 기능을 제공합니다.
itertools 반복자 생성 함수를 제공합니다.
collections 고성능 컨테이너 데이터 타입을 제공합니다.
unittest 단위 테스트 프레임워크를 제공합니다.
logging 로깅 기능을 제공합니다.
threading 멀티스레딩 관련 기능을 제공합니다.
sqlite3 SQLite 데이터베이스를 처리하는 기능을 제공합니다.
urllib URL 관련 기능을 제공합니다.
http HTTP 프로토콜 관련 기능을 제공합니다.
re 정규 표현식을 처리하는 기능을 제공합니다.
json JSON 데이터를 처리하는 기능을 제공합니다.
datetime 날짜와 시간 관련 기능을 제공합니다.
math 수학적 함수와 상수를 포함합니다.
sys 파이썬 인터프리터와 관련된 기능을 제공합니다.
패키지(라이브러리) 설명
NumPy
pandas
matplotlib
SciPy
ScikitLearn

"""
장문주석
입니다.
"""

class emptyClass(상속희망시부모클래스넣기):
		pass # 아예 비어있으면 에러

class webServer():
    def __init__(self): # 생성자
        super().__init__() # 부모클래스의 생성자호출인데, 상속받은게 없다면 아무일도 일어나지않음 (관례적호출)
        self._protectedVariable = 1 # protected접근지정자 표시
        self.__privateVariable = 1 # private접근지정자 강제 (기본은 public)
        self.debugMode = False # 맴버변수선언
        self.setDefaultValue()  # 단문주석입니다.
        self.webApp = Flask(__name__)
        self.webApp.config['TEMPLATES_AUTO_RELOAD'] = True
        
        self.webControlConfig = configparser.ConfigParser()
        self.apiServerConfig = configparser.ConfigParser()
        self.setFlaskRoute()
        
        self.createLogger()
        self.flaskServerStart()
		
		def __del__(self): # 명시적 소멸자
				pass # 명시하는 순간, 암묵적 소멸기능 미작동으로 주의요망
    
    def createLogger(self): # 맴버함수선언
        logFormat = logging.Formatter('%(asctime)s - %(levelname)s > %(message)s')
        self.webServer_logger = logging.getLogger("webServer") # 해당이름의 싱글톤생성, 로그출력시 해당이름출력
        self.webServer_logger.setLevel(logging.DEBUG)
        self.webServer_logger_Handler = logging.FileHandler("C:/glim/nffrollpressWebServer/log/webServer.log")
        self.webServer_logger_Handler.setFormatter(logFormat)
        self.webServer_logger.addHandler(self.webServer_logger_Handler)

    def setFlaskRoute(self):
		    # 어노테이션-라우팅설정이기 때문에 실제실행되지는 않고 선언만 하는 느낌,
		    # 실제 함수의 중첩선언이라면 설령 같은 클래스라하더라도 외부에서 직접 호출은 불가하다
        @self.webApp.route("/")
        def index(): 
            ret = self.webSelfTest() 
            if ret == True:
                ret = render_template(self.indexPage,version = self.version)
            return ret 
...

if __name__ =='__main__': # 직접실행문법, 임포트되어 실행시 __main__은 해당 모듈이름가짐
    webServer()

class apiServer():
    def __init__(self):
        super().__init__()
        self.setDefaultValue()
        self.webAppAPI = Flask(__name__) # 기본 Flask 객체 생성
        self.apiServer = Api(self.webAppAPI) # Flask확장기능(url스타일 아키텍쳐) from flask_restful import Resource, Api, reqparse
        CORS(self.webAppAPI, resources={r'*': {'origins': '*'}}) # 다중 도메인의 서버 동시이용 허용
        apiClass.connectionDB() # 자체클래스
        self.setFlaskRoute()
        self.flaskServerStart()
        self.apiServerDataLoad()

    def apiServerDataLoad(self):
        ret = False
        if os.path.isfile(self.configFilePath + self.apiServerConfigFileName):
            self.apiServerConfig.clear()
            self.apiServerConfig = configparser.ConfigParser()
            self.apiServerConfig.read(self.configFilePath + self.apiServerConfigFileName)
            ret = True

        return ret

    def setFlaskRoute(self):
        @self.webAppAPI.route("/")
        def index():
            if not apiClass._DB_Status:
            # Database 연결 불가
                ret = render_template(self.errorPage, # Flask 웹 프레임워크 템플릿렌더링
                imageFileName = self.errorImageFileName,
                title = self.errorTitle_DB_Connection_Error, 
                subTitle = self.errorSubTitle_DB_Connection_Error, 
                contents = self.errorContents_DB_Connection_Error,
                redirectPage = self.refreshPage, 
                displayButtonName = self.refreshButtonDisplay)
            else:
            # 정상 페이지
                ret = render_template(self.indexPage, 
                    imageFileName = self.successImageFileName,
                    title = self.successTitle_apiServer_Index, 
                    subTitle = self.successSubTitle_apiServer_Index, 
                    contents = self.successContents_apiServer_Index,
                    redirectPage = "/")
            return ret

        @self.webAppAPI.errorhandler(404)
        def errorHandler(error):
            ret = render_template(self.errorPage, 
                imageFileName = self.errorImageFileName,
                title = self.errorTitle_404, 
                subTitle = self.errorSubTitle_404, 
                contents = self.errorContents_404,
                redirectPage = self.refreshPage, 
                displayButtonName = self.refreshButtonDisplay)
            
            return ret
        
        # Flask 서버에 API Resource 추가. 두번째인자url로 GET등의 요청이 오면 첫번째인자의 함수중에 해당하는 것을 실행, 매칭안되면 405error
        self.apiServer.add_resource(apiClass.DB_Status, apiClass.DB_Status.accessAPI_Address)
        self.apiServer.add_resource(...
        self.apiServer.add_resource(...
        ...
        ...
        
-----------
# 아래 함수명과 HTTP매서드명의 매칭이 flask 프레임워크의 Resource클래스에 의해 강제되고있음
# 하단 Resource 클래스 구현부 참고
from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class ExampleResource(Resource):
    def get(self):
        # HTTP GET 메서드 처리
        return {'message': 'GET request received'}
    
    def post(self):
        # HTTP POST 메서드 처리
        return {'message': 'POST request received'}
    
    def put(self):
        # HTTP PUT 메서드 처리
        return {'message': 'PUT request received'}
    
    def delete(self):
        # HTTP DELETE 메서드 처리
        return {'message': 'DELETE request received'}
    
    def patch(self):
        # HTTP PATCH 메서드 처리
        return {'message': 'PATCH request received'}
    
    def options(self):
        # HTTP OPTIONS 메서드 처리
        return {'message': 'OPTIONS request received'}
    
    def head(self):
        # HTTP HEAD 메서드 처리
        return '', 204  # HEAD 요청은 보통 응답 본문을 포함하지 않음

# 리소스와 URL 경로 연결
api.add_resource(ExampleResource, '/example')

if __name__ == '__main__':
    app.run(debug=True)

-----------
"""
< 동작 원리 >
	0. add_resource() 로 Resource클래스 내부의 map에 url과 목적클래스를 등록합니다.
	1. 클라이언트가 서버에 HTTP 요청을 보냅니다. ( GET 등등등 )
	2. Flask-RESTful은 Resource클래스 내부의 에서 요청된 URL과 매칭되는 를 찾습니다.
	3. 매칭된 리소스 클래스의 dispatch_request() 메서드가 호출됩니다.
	4. dispatch_request 메서드는 HTTP 메서드(GET, POST, PUT, DELETE 등)에 해당하는 리소스 클래스의 메서드를 찾아 호출합니다.

"""
class Resource(MethodView):
    """
    Represents an abstract RESTful resource. Concrete resources should
    extend from this class and expose methods for each supported HTTP
    method. If a resource is invoked with an unsupported HTTP method,
    the API will return a response with status 405 Method Not Allowed.
    Otherwise the appropriate method is called and passed all arguments
    from the url rule used when adding the resource to an Api instance. See
    :meth:`~flask_restful.Api.add_resource` for details.
    """
    representations = None
    method_decorators = []

    def dispatch_request(self, *args, **kwargs):

        # Taken from flask
        #noinspection PyUnresolvedReferences
        
        # HTTP 요청 메서드 이름을 소문자로 변환한 후, 리소스 클래스에서 해당 이름의 메서드를 찾습니다.
        meth = getattr(self, request.method.lower(), None)
        
        # 만약 요청 메서드가 HEAD이고, head 메서드가 정의되어 있지 않다면, get 메서드를 대신 사용합니다.
        if meth is None and request.method == 'HEAD':
            meth = getattr(self, 'get', None)
            
        # 해당 메서드가 존재하지 않는다면, 405 Method Not Allowed 상태 코드를 반환합니다.
        assert meth is not None, 'Unimplemented method %r' % request.method

				# Mapping : 아마도 class-url정보는 여기에 등록됨
        if isinstance(self.method_decorators, Mapping): 
            decorators = self.method_decorators.get(request.method.lower(), [])
        else:
            decorators = self.method_decorators

        for decorator in decorators:
            meth = decorator(meth)

        resp = meth(*args, **kwargs)

        if isinstance(resp, ResponseBase):  # There may be a better way to test
            return resp

        representations = self.representations or OrderedDict()

        #noinspection PyUnresolvedReferences
        mediatype = request.accept_mimetypes.best_match(representations, default=None)
        if mediatype in representations:
            data, code, headers = unpack(resp)
            resp = representations[mediatype](data, code, headers)
            resp.headers['Content-Type'] = mediatype
            return resp

        return resp        
<body>
<div id="navbarContainer"><div data-include-path="{{ url_for('static', filename='html/sidebar_row.html') }}"></div></div>
<script>
    window.addEventListener('load', function() { // 'load' 이벤트에 대해 다음함수 실행
        var allElements = document.getElementsByTagName('*'); // 현재문서의 모든 태그네임 획득
        Array.prototype.forEach.call(allElements, function(el) { // 현재문서의 모든 태그를 담은 객체에 대해(.call) 개별 태그를 인자로하여(el) 다음함수 수행 
            var includePath = el.dataset.includePath; // 개별태그의 data-include-path 확인
            if (includePath) {
                var xhttp = new XMLHttpRequest(); // AJAX 비동기통신지원 객체
                xhttp.onreadystatechange = function () { // xhttp의 ready상태 바뀌면 다음함수 실행 (객체가 알아서)
                    if (this.readyState == 4 && this.status == 200) {
                        el.outerHTML = this.responseText; // 서버가 보내온 Text로 순회중인 태그의 outerHTML을 교체
                        document.querySelector('.index-page').classList.add('active');
                        document.querySelector('.form-switch').style.display = 'block';
                        releaseDate = '{{version}}';
                        setReleaseDate(releaseDate); } };
                xhttp.open('GET', includePath, true); // url로 비동기(true) GET요청 세팅
                xhttp.send(); // 서버로 전송 }
        });
        getDefectValue_Timer();
    });
</script>
<div class="container">
    <div class="headerSection mb-2">
        <div class="currentLOT shadow p-1 me-2 bg-body rounded text-center placeholder-glow" id="currentLOT">
            <div class="placeholder col-12 bg-secondary rounded"></div>
        </div>
        <div class="currentMeter shadow p-1 me-2 bg-body rounded text-center placeholder-glow" id="currentMeter">
            <div class="placeholder col-12 bg-secondary rounded"></div>
        </div>
        <div class="currentDefectCount shadow p-1 me-2 bg-body rounded text-center placeholder-glow" id="currentDefectCount">
            <div class="placeholder col-12 bg-secondary rounded"></div>
        </div>
    </div>
</div>
</body>