잘 쓰고 있었다. 어느날 갑자기 아마존에서 $3을 가져가겠다고 문자가 왔다. 헉~~~~ EC2는 프리티어 아닌가? 왜 돈을 달라고 하지?????
AWS 에 로그인하여 '서비스 찾기' 에서 빌링 시스템을 검색하여 확인해 봤다.
'Billing' 페이지에 들어간 후 '서비스별 이번 달 현재까지 소비' 부분의 '청구서 세부 정보'를 클릭한 후 요금이 청구된 달을 선택하면 요금이 적용된 세부 정보를 볼 수가 있다.
나한테 발생한 요금은 아래와 같다.
실행되고 있지 않은 EC2에 연결되어 있는 Elastic IP Addresses 에서 요금이 발생 한 것이다. 시간당 0.005 $로...
나는 EC2에 Elastic IP Address를 연결만 해 놓으면 요금이 발생하지 않는 줄 알았다. 그게 아니였다.
Elastic IP Address에 연결된 EC2를 stop 시키면 이 역시 요금이 발생하는 것이었다.
Elastic IP Address는 요금이 발생하는 서비스이다. Elastic IP Address는 동적으로 IP가 할당되는 인스턴스를 위한 정적 IPv4 주소 서비스로 AWS 계정과 연결된다. 이 자원은 유니크한 자원이기 때문에 생성 후 인스턴스와 연결을 하지 않으면 요금이 발생한다. Elastic IP Address를 사용하면 EC2를 정적 IP로 사용할 수 있고 EC2에 연결해 놓았기 때문에 EC2를 무료로 사용하는 기간동안은 요금이 발생하지 않는다. 하지만 EC2를 사용하지 않고 stop 시키는 동안에도 Elastic IP Address 자원을 사용하고 있는 것이기 때문에 요금이 발생한다. 이 번에 아마존이 나한테 돈을 가져간 사유가 바로 이 것이다. EC2와 Elastic IP Address를 연결한 후 EC2를 stop 시켜 놓았던 것이다. 그래서 앞으로 일년 동안 EC2를 멈추지 않기로 했다. ㅋㅋㅋ
Pycharm을 Free 버전을 사용 중이었다. AWS 무료 버전 하나 만들고 FTP client로 연결하여 사용 중이었다. Pycharm으로 작업 후 FTP를 이용해서 AWS에 파일을 업로드하고 실행 시키고...생각보다 귀찮은 작업이었다.
FTP가 가능한 무료 ide 를 찾다가 vs code를 발견했다. python만하는게 아니라 주로 C/C++을 하고 정말 일있으면 JAVA도 하고( 사실 자바는 현재 잘 안함 ㅋ ), 급하면 C#도 하고 현재 python도 하고 있으니 여러개를 동시에 할 수있는 vs code가 딱이었다. FTP도 되지 않는가.
vs code를 다운받고 'FTP-simple'를 설치했다. 'F1'을 눌러 FTP-simple config를 설정하려고 하는데, 이런!!! 이상한 에러가 난다.
'Running the contributed command:'ftp.config' failed'
아무리 찾아도 해결 책이 없으 한 동안 방치했다 다시 vs code를 실행하니 FTP Connection config 설정 error가 사라졌다. ㅋ~~~~
REST API는 규약이자 형식이며 지침이다. 프로토콜 조차도 되지 않는다. 프로토콜은 지키지 않으면 동작을 안하지만 REST API는 지키지 않는다고 동작을 안하는 것은 아니다. 그럼에도 불구하고 우리는 REST API를 지켜야 한다.
함수명과 인자값, 리턴값으로 무슨일을 하는 함수인지 알 수 있는 함수명 명명 규칙과 비슷하다. 안지킨다고 제재를 가하진 않지만 일하기에 불편을 감수해야 한다. 물론 혼자하는 일이라면 불편을 감수해도 괜찮다. 하지만 SW는 이제 혼자할 수 있는 규모를 벗어난 큰일이 되어 버렸기 때문에 우리는 항상 팀작업을 한다. 팀작업 아래에서는 규약과 형식을 지키는 것이 중요하다. 안지키면 지금도 욕먹지만 미래의 누군가에게도 오지게 욕을 먹는다.
Flask의 Blueprint는 쉽게 말해 모듈을 나누는 역할을 한다. 한 모듈에 거대하게 집중되어 있는 REST API method를 상상해보자 한 파일만 천 라인이 넘어간다면 보기 힘들 것이다. Blueprint를 이용해서 REST API의 URI에 맞게 모듈을 나누어 관리를 쉽게 하는 것도 좋은 방법일 것이다. 필요할 때 분리된 모듈을 버전별로 관리할 수도 있다.
Blueprint를 사용하기 전의 폴더 구조와 사용후의 폴더 구조를 설명했으니 이젠 바뀐 코드를 보자
webapp 폴더 아래의 __init__.py 파일
Flask 객체인 app만 선언했다.
api_v1 패키지와 패키지 안에 선언한 api 모듈을 추가한다.
app에 resgister_blueprint 메소드를 사용하여 api 모듈을 등록한다. 이제 app으로 전달되어 오는 requests를 api 모듈로도 보낼 수 있는 준비를 했다. url_brefix는 Blueprint로 등록한 모듈에 requests URL이 전달 될 때 URI에 자동으로 붙는 URI이다. 잘 동작을 안한다. 내가 실수한 것인지 버전 차이인지는 찾아보고 있는 중이다. url_brefix가 잘 동작한다면 api의 버전관리가 무지 편해질 것 같다. 필요 없거나 버그가 있는 api는 폐기하고 Blueprint 등록하는 곳에서 url_brefix 만 변경해주면 될 것이기 때문이다.
app_start.py 파일
app_start.py 모듈에 있던 login, register, registerinfo 등등의 requests 함수들이 모두 사라졌다. Blueprint로 해당 모듈을 생성하고 해당 모듈로 모두 분리했다.
REST는 정보들을 주고 받는데 있어서 사용되는 형식이자 규약이다. 처음에는 REST를 기능 또는 기술로 인식을 하고 있었다. 기술이나 제품이 아니라 형식이기 때문에 어떤 프레임워크를 쓰든 형식에 맞춰서 사용만 하면 오만가지에서 다 사용할 수 있다.
REST의 가장 중요한 특성은 각 동작이 어떤 동작이나 정보를 위한 것인지를 요청하는 모습 자체로 추론이 가능하다는 것이다. 요청을 보낸 주소만으로도 이 요청이 어떤 요청인지 파악이 가능하도록 만들어야 한다.
REST API는 리소스를 중심으로 디자인 한다.(무슨 말인지?) REST는 말 그대로 규약으로 지키지 않는다고 웹이 동작하지 않는 것은 아니다. 단지 RESTful하지 않은 API라는 소리를 들을 뿐...
http 기반이기 때문에 주소가 나오고 주소의 '/' 뒤에 식별자들이 나오는데 식별자로 리소스를 명을 사용한다. 세부항목으로는 해당 리소스의 ID를 사용하면 된다.
리소스를 중심으로 디자인한다는 말은 URI는 리소스 중심으로 만들고(URI에 리소스 동작에 대한 설명은 없어야 한다) 리소스에 대한 동작은 HTTP의 method로 지원해야 한다. 각 CRUD method는 각각의 의미가 있기 때문에 각 의미에 맞추어 코드를 개발하면 된다.
그렇기 때문에 리소스 URI는 동사(리소스에 대한 작업)가 아닌 명사(리소스)를 기반으로 기술되어야 한다.
Front-end / back-end 는 물론이고 리액트, 디장고, 부트스트랩 등등 모르는 용어가 너무 많다.
새로운 분야로 들어갈 때 용어정리만 해도 반은 먹고 들어가고 어디가서 전문가인척 대화도 할 수 있다고 생각한다. ㅋ~
back-end는 python의 Flask와 DJango로 퉁치고 있는데 front-end가 뭔지 살펴보다 부트스크랩을 사용해 봤다.
front-end는 결국 HTML / CSS / Java Script 등으로 이루어 져 있다고 생각했는데 부트스트랩이 뭐지? 프레임워크인가?
부트스트랩는 한마디로 '웹사이트 개발시의 프레임워크' 로 정의할 수 있다. 그렇다 순수하게 front-end단의 웹사이트/웹페이지 개발에 필요한 프레임워크가 부트스트랩이다. 즉 부트스트랩은 HTML/CSS/Java Sctrip의 개발을 편하고 쉽게 할 수 있도록 라이브러리를 모아놓은 프레임워크이다.
그럼 어떻게 사용하나? 부트스트랩은 웹사이트 개발시에 가장 많이 사용하는 HTML/CSS/JS를 미리 만들어 놓았고 사용자는 다운로드 또는 CDN 방식으로 링크해서 그냥 사용하면 된다.
예를 들어 버튼을 하나 만들고 CSS를 적용한다고 생각해보자. 일일이 개발자가 HTML의 모든 태그, class, id에 CSS를 만들어 주면 상당한 코딩을 해야 할 것이다. ( 물론 나같은 사람은 코딩양보다는 디자인이 쾅이라 부트스트랩을 사용할 것이다. )
부트스트랩을 사용한다면 아래와 같이 링크만 걸어주면 된다.
코드에서 보듯이 부트스트랩 CSS를 링크로 걸어주고 CSS를 적용할 클스만 추가하면 된다. 버튼의 class 에 부트스트랩을 적용해 주었다. 이제 버튼은 부트스트랩의 디자인이 적용되어 이쁘게 표현될 것이다.
Working with Models, SQLAlchemy, and Hyperlinked APIs in Flask
In this chapter, we will expand the capabilities of the RESTful API that we started in the previous chapter. We will use SQLAlchemy as our ORM to work with a PostgreSQL database, and we will take advantage of advanced features included in Flask and Flask-RESTful that will allow us to easily organize code for complex APIs, such as models and blueprints.
We will go through the following topics in this chapter:
Design a RESTful API to interact with a PostgreSQL 10.5 database
Understand the tasks performed by each HTTP method
Install packages with therequirements.txtfile to simplify our common tasks
Create the database
Configure the database
Write code for the models with their relationships
Use schemas to validate, serialize, and deserialize models
Combine blueprints with resourceful routing
Understand and configure resourceful routing
Register the blueprint and run migrations
Verify the contents of the PostgreSQL database
Create and retrieve related resources
Designing a RESTful API to interact with a PostgreSQL 10.5 database
So far, our RESTful API has performed CRUD operations on a simple in-memory dictionary that acted as a data repository. The dictionary is never persisted and, therefore, the data is lost whenever we restart our Flask development server.
Now, we want to create a more complex RESTful API with Flask RESTful to interact with a database model that allows us to work with notifications that are grouped into notification categories. In our previous RESTful API, we used a string attribute to specify the notification category for a notification. In this case, we want to be able to easily retrieve all the notifications that belong to a specific notification category and, therefore, we will have a relationship between a notification and a notification category.
We must be able to perform CRUD operations on different related resources and resource collections. The following table enumerates the resources and the class name that we will create to represent the model:
The notification category (NotificationCategory) just requires the following data:
An integer identifier
A string name
We need the following data for a notification (Notification):
An integer identifier
A foreign key to a notification category (NotificationCategory)
A string message
ATTL(short forTime to Live), that is, a duration in seconds that will indicate the amount of time the notification message has to be displayed on the OLED display
A creation date and time. The timestamp will be added automatically when adding a new notification to the collection
An integer counter that indicates the times when the notification message has been displayed on the OLED display
A bool value indicating whether the notification message was displayed at least once on the OLED display
We will take advantage of many packages related to Flask RESTful and SQLAlchemy that make it easier to serialize and deserialize data, perform validations, and integrate SQLAlchemy with Flask and Flask RESTful. This way, we will reduce the boilerplate code.