묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! FastAPI 입문
HTT
HTTP Response 처리하는 강의에서 7:53초, response 타입을 -> ~으로 정의하는 부분에서 오류가 발생하내요;; 왜이런지
-
해결됨실전! FastAPI 입문
섹션2. HTTP Response 처리 에서 from_orm 관련 오류가 나서 질문드립니다.
섹션2. HTTP Response 처리 에서 from_orm 관련 오류가 나서 질문드립니다.The from_orm method is deprecated; set model_config["from_attributes"]=True and use model_validate instead. 라는 에러와 함께 서버를 작동시켜도 Swagger에서 GET함수가 반영되지 않고 status code 500으로 Error가 발생하는데 해결법을 혹시 아실까요? 구글링을 해봐도 정보가 잘 나오지 않네요ㅠif order and order == "DESC": return ListToDoResponse( todos=[ToDoSchema.from_orm(todo) for todo in todos[::-1]] )
-
해결됨실전! FastAPI 입문
파이썬 가상환경 질문
파이썬 가상환경 구축영상에서, 터미널에서 가상환경 구축하셨는데, 어느 터미널에서 실행하는지도 안알려주시고 알려주시면 좋겠습니다. 설명이 너무 빈약하네요...;; 일단 파이참은 설치했는데 어떻게 하는지 자세히 설명 부탁드립니다.
-
해결됨실전! FastAPI 입문
api 데이터 모델링 시, pandantic?
강의를 보고 문서를 보고 정리하는 과정 중에 헷갈리는 점이 있어서 질문 드려봅니다. 저희 코드에서 schema안에 response , request 의 스키마는pydantic의 basemodel로 설계가 되어있고 ,database Orm에는 유저 모델과 todo를 만들었는데, 이 부분은 sql alcemy의 base declaritve를 사용한걸로 기억합니다.(모델 폴더와 스키마 폴더가 헷갈립니다..)백엔드 설계를 할때, 데이터 구조 그리고 erd등 관계도 설정 후에 모델링을 fast api로 할때는 , 저희 강의 때 한 것처럼 orm안에 해준 것처럼 하는 방식일까요? pydantic으로 schema(폴더명 때문에 헷갈리는 부분일 수도.)에서는 단순히 req,res 에 있어서 타입을 검증하기 위한 모델을 설계한 것이라고 보면 될까요? 강의를 듣고, 실제로 백엔드 api 만들어서 프로젝트 구성해보려 하는 과정에서 질문이 있어서 드려봅니다. 1 to many는 아래처럼 하고 , m to m인 경우도 아래 와 비슷한 형식으로 모델링을 하는 걸까요? 강의에서는 맛보기로 간단하게 소개형식이지만 실제로 프로젝트를 한다고 했을땐, 어떻게 작성하는지 궁금합니다.user_id = Column(Integer, ForeignKey("user.id")) Repository 는 mvc의 컨트롤러라고 생각하면 될까요? 모델링 할때, SQLModel로 하는 방법과 강의에서 나온 Base상속방법의 차이는 무엇일까요? 구글링해도 잘 나오지 않네요.. 둘다 상관없다면, 어떠한 것이 선호가 되는지 왜 강의에서는 base상속을 했는지 이유가 있으실까요? SQL Model도 fastapi 저자가 만든 것인고 pydantic기반이라고 들었습니다. 번외로.. 저희가 배운걸로는 declartive 를 상속받는데, 아래와 같은 형식으로도 모델링을 하기도 하나요? from sqlmodel import SQLModel, Field class User(SQLModel, table = True): nickname: str = Field(primary_key = True) password: str
-
해결됨실전! FastAPI 입문
TODO 테스트 코드 작성
저의 경우는 아래와 같이 해주어야 테스트 코드가 통과됩니다. 그 이후는 sql 도커의 데이터가 5개가 있어서 실제는 5개이기 때문이라 생각되어지는데요.강의를 보면서 테스트코드 감을 못잡앗는데, 궁금한 점은 테스트 코드에서 user 변수에다가 id1 이고 test란 이름의 유저네임을 넣어주고 거기다가, todos를 목업으로 2개를 넣어줬는데, 왜 마지막에 assert할때는 user.todos에 넣어준 배열로 하는게 아닌 실제 db들어간 5개의 데이터로 assert로 체크하더라구요. 그러면 아래 mocker patch해준 부분이 제대로 안먹는건가요? 흠..user = User(id=1, username="test", password="hashed") user.todos = [ ToDo(id=1, contents="FastAPI Section 0", is_done=True), ToDo(id=2, contents="FastAPI Section 1", is_done=False), ] mocker.patch.object(UserRepository, "get_user_by_username", return_value=user) def test_get_todos(client, mocker): access_token: str = UserService().create_jwt(username="test") headers = {"Authorization": f"Bearer {access_token}"} user = User(id=1, username="test", password="hashed") user.todos = [ ToDo(id=1, contents="FastAPI Section 0", is_done=True), ToDo(id=2, contents="FastAPI Section 1", is_done=False), ] mocker.patch.object(UserRepository, "get_user_by_username", return_value=user) # order=ASC response = client.get("/todos", headers=headers) assert response.status_code == 200 assert response.json() == { "todos": [ {"id": 1, "contents": "FastAPI Section 0", "is_done": True}, {"id": 2, "contents": "FastAPI Section 0", "is_done": True}, {"id": 3, "contents": "string", "is_done": True}, {"id": 4, "contents": "string", "is_done": True}, {"id": 5, "contents": "string", "is_done": True}, ] } # order=DESC response = client.get("/todos?order=DESC", headers=headers) assert response.status_code == 200 assert response.json() == { "todos": [ {"id": 5, "contents": "string", "is_done": True}, {"id": 4, "contents": "string", "is_done": True}, {"id": 3, "contents": "string", "is_done": True}, {"id": 2, "contents": "FastAPI Section 0", "is_done": True}, {"id": 1, "contents": "FastAPI Section 0", "is_done": True}, ] }
-
해결됨실전! FastAPI 입문
회원가입 test Api Assertion Error
해결완료...user: User = User.create(username=request.username, hashed_password=hashed_password)저 부분에서 username 안하고, positional Arugment처럼User.create(request.username)이런 식으로 코드를 썻네요.. 파이썬에서는 named Argument형식을 맞춰야 하나요? test api user 코드 입니다.def test_user_sign_up(client, mocker): hash_password = mocker.patch.object( UserService, "hash_password", return_value="hashed" ) user_create = mocker.patch.object( User, "create", return_value=User(id=None, username="test", password="hashed") ) mocker.patch.object( UserRepository, "save_user", return_value=User(id=1, username="test", password="hashed"), ) body = {"username": "test", "password": "plain"} response = client.post("/users/sign-up", json=body) hash_password.assert_called_once_with(plain_password="plain") user_create.assert_called_once_with(username="test", hashed_password="hashed") assert response.status_code == 201 assert response.json() == {"id": 1, "username": "test"} 깃 헙 나온 코드로도 해봤지만, 여전히user_create.assert_called_once_with()이 부분에서 에러가 납니다. 주석처리하면 잘 통과 되구요.아래가 에러 메세지 내용이고, 혹시 오타 있을까봐 깃허브 코드 그대로 가져와도 동일하네요.test_users_api.py:5 (test_user_sign_up){'hashed_password': 'hashed'} != {'hashed_password': 'hashed', 'username': 'test'}Expected :{'hashed_password': 'hashed', 'username': 'test'}Actual :{'hashed_password': 'hashed'}expected는 적었떤 username="test"가 나와야 하는데 , 실제는 없나봅니다. 그래서 user_create.assert_called_once_with(hashed_password="hashed") 이런식을 변경하면, 아래처럼 여전히 통과 하지 못하네요 ('test',) != ()Expected :()Actual :('test',)
-
해결됨실전! FastAPI 입문
DI 주입
현재구조는 todo.py ( controller 역할 ) @router.get("/", status_code=200) def get_todos_handler( order: str | None = None, todo_repo: ToDoRepository = Depends(ToDoRepository), ) -> TodoListSchema: todos: List[ToDo] = todo_repo.get_todos() if order and order == "DESC": return TodoListSchema( todos=[ToDoSchema.from_orm(todo) for todo in todos[::-1]] ) return TodoListSchema( todos=[ToDoSchema.from_orm(todo) for todo in todos] )repository.py ( service 와 repository 역할 ) 로 되어있다면 class ToDoRepository: def __int__(self, session: Session): self.session = session def get_todos(self) -> List[ToDo]: return list(self.session.scalars(select(ToDo)))만약 controller, service , repository 로 구조를 변경한다고 했을때도 controller 에서 부터 todo_repo: ToDoRepository = Depends(ToDoRepository)를 작성해서 service -> repository 까지 끌고와야 할까요 ??
-
해결됨실전! FastAPI 입문
패키지 와 폴더
테스트 코드 까지 강의를 들었습니다.패키지와 폴더의 차이 자세히 이해가 가지 않습니다.패키지로 해도 되고 폴더로 해도되면 모두 패키지 폴더로 생성해도 되지않나 생각이 드는데요어떻게 이해하면 되며 어떤 상황에서 패키지와 폴더를 사용하면 될까요 ??강사님이 패키지를 자주 사용하지 않고 폴더만 을 사용하시다가 패키지는 필요할때만 사용하시는것 같아서 그이유가 있으실까요 ?
-
해결됨실전! FastAPI 입문
update 테스트 코드
update 코드를 @app.patch("/todos/{todo_id}", status_code=status.HTTP_200_OK) def update_todo_handler( todo_id: int, is_done: bool = Body(..., embed=True), session: Session = Depends(get_db), ): todo: ToDo | None = get_todo_by_todo_id(session=session, todo_id=todo_id) if todo: todo.done() if is_done is True else todo.undone() todo: ToDo = update_todo(session=session, todo=todo) return ToDoSchema.from_orm(todo) return HTTPException(status_code=404, detail="Todo not found") 위와 같이 작성하고 난뒤에 , 테스트 코드 200 을 제외한 우선 404 기준으로만 작성했을때# 404 mocker.patch("main.get_todo_by_todo_id", return_value=None) response = client.patch("/todos/1", json={"is_done": True}) assert response.json()['status_code'] == 404 assert response.json()['detail'] == "Todo not found" 다음과 같이 작성했을때 통과가 됐습니다. 하지만 위의 작성된 코드는 영상과 다른 코드입니다.저렇게 정확히 키값을 설정을 해줘야만 통과가 되더라구요.제가 어디를 놓치고 있는걸까요 ?
-
해결됨실전! FastAPI 입문
Django 와 Fast API
머신러닝 이라던지 딥러닝 프로젝트를 서버에 배포하게 될때는 Fast API 를 선호하게 되고 , 백엔드 서버 배포시에는 그럼 Django 를 추천하시나요?
-
해결됨실전! FastAPI 입문
'Session' object has no attribute 'scalars' 오류 발생합니다.
강사님 안녕하세요. 파이썬 콘솔에서는 list(session.scalars(select(ToDo))) 이 코드가 잘 실행되었는데, main.py 코드 모두 작성 후 스웨거에서 get /todos 에서 실행하면,터미널에 AttributeError: 'Session' object has no attribute 'scalars'오류가 뜹니다. ㅠㅠ
-
해결됨실전! FastAPI 입문
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") 오류
OS: macOSpython 3.10 버전을 사용하고 있고,sqlalchemy 2.0.19, pymysql 1.1.0 등등 최신 패키지 사용중입니다.from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker DATABASE_URL = "mysql+pymysql://root:todos@127.0.0.1/todos" engine = create_engine(DATABASE_URL, echo=True) SessionFactory = sessionmaker(autocommit=False, autoflush=False, bind=engine) connection.py 는 위와 같이 동일하게 작성했고,session.scalar(select(1)); 실행시 아래와 같은 오류가 발생하여 더 이상 진행을 할 수가 없습니다.Traceback (most recent call last): File "/Users/someone/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/232.8660.197/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode coro = func() File "<input>", line 1, in <module> File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2296, in scalar return self._execute_internal( File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2131, in _execute_internal conn = self._connection_for_bind(bind) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1998, in _connection_for_bind return trans._connection_for_bind(engine, execution_options) File "<string>", line 2, in _connection_for_bind File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go ret_value = fn(self, *arg, **kw) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1123, in _connection_for_bind conn = bind.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3264, in connect return self._connection_cls(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 147, in __init__ Connection._handle_dbapi_exception_noconnection( File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2426, in _handle_dbapi_exception_noconnection raise sqlalchemy_exception.with_traceback(exc_info[2]) from e File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 145, in __init__ self._dbapi_connection = engine.raw_connection() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3288, in raw_connection return self.pool.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 452, in connect return _ConnectionFairy._checkout(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 1267, in _checkout fairy = _ConnectionRecord.checkout(pool) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 716, in checkout rec = pool._do_get() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 169, in _do_get with util.safe_reraise(): File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 147, in __exit__ raise exc_value.with_traceback(exc_tb) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 167, in _do_get return self._create_connection() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 393, in _create_connection return _ConnectionRecord(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 678, in __init__ self.__connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 902, in __connect with util.safe_reraise(): File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 147, in __exit__ raise exc_value.with_traceback(exc_tb) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 898, in __connect self.dbapi_connection = connection = pool._invoke_creator(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/create.py", line 637, in connect return dialect.connect(*cargs, **cparams) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 615, in connect return self.loaded_dbapi.connect(*cargs, **cparams) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 358, in __init__ self.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 664, in connect self._request_authentication() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 976, in _request_authentication auth_packet = _auth.caching_sha2_password_auth(self, auth_packet) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/_auth.py", line 267, in caching_sha2_password_auth pkt = _roundtrip(conn, data) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/_auth.py", line 120, in _roundtrip pkt = conn._read_packet() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 772, in _read_packet packet.raise_for_error() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error err.raise_mysql_exception(self._data) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception raise errorclass(errno, errval) sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") (Background on this error at: https://sqlalche.me/e/20/e3q8) Check the PassWord Hashing Method: If the MySQL server is using caching_sha2_password but the client (like PyMySQL) doesn't support it, it can give rise to such issues. You can switch the MySQL user's password hashing method to mysql_native_password.이런 글도 있어서 따라하고 새로 비밀번호를 todos 로 넣어줬는데도 마찬가지네요. 더 참고할만한 내용이 있을까요?
-
해결됨실전! FastAPI 입문
백엔드 구축관련
안녕하세요 본 강의 완강후 백엔드 구축이 가능한지요?
-
해결됨실전! FastAPI 입문
AssertionError: Expected 'undone' to be called once. Called 0 times.
def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") mocker.patch( "main.update_todo", return_value=ToDo(id=1, contents="todo", is_done=False), ) # API 호출 여부 response = client.patch("/todos/1", json={"is_done": False}) undone.assert_called_once_with() assert response.status_code == 200 # 성공 assert response.json() == {"id": 1, "contents": "todo", "is_done": False} # 성공 # Resetting the mock before the next scenario # 404 mocker.patch( "main.get_todo_by_todo_id", return_value=None, ) response = client.patch("/todos/1", json={"is_done": True}) assert response.status_code == 404 assert response.json() == {"detail": "ToDo Not Found"} pytest 시 아래와 같은 에러가 발생합니다. 강사님 코드와 상이한 부분도 없고 로직도 맞게 작성한 것 같은데 undone이 한번도 호출이 되지 않았다고 합니다.During handling of the above exception, another exception occurred: client = <starlette.testclient.TestClient object at 0xffff89948640>, mocker = <pytest_mock.plugin.MockerFixture object at 0xffff89004e50> def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") > print(undone.assert_called_once_with()) E AssertionError: Expected 'undone' to be called once. Called 0 times. tests/test_main.py:106: AssertionError ========================================================== short test summary info ========================================================== FAILED tests/test_main.py::test_update_todo - AssertionError: Expected 'undone' to be called once. Called 0 times. ======================================================== 1 failed, 5 passed in 0.18s ======================================================== #
-
해결됨실전! FastAPI 입문
Depends() 안에 callable한 것을 넣는 경우와 안 넣는 경우
4:24 초에 user_repo: UserRepository = Depends()이런 식으로 여기서는 Depends() 안에 아무것도 넣어주지 않는데, 그냥 Depends() 자체만으로는 어떤 의미가 있나요?
-
해결됨실전! FastAPI 입문
(실습) MySQL 컨테이너 실행
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=todos -e MYSQL_DATABASE=todos -d -v todos:/db -–name todos mysql:8.0터미널에서 위 명령어 실행하면,docker: Invalid containerPort: 3306 -e.이런 오류가 발생합니다. ㅠㅠ 참고로 docker 처음 써보는 초급입니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
userRepositorySpySave 왜 ? 0 이 안나와? 는 보십시오.
```typescriptasync create({ email, password, mobileNumber }) { const user = await this.userRepository.findOne({ where: { email } }); if (user) throw new ConflictException('이미 등록된 이메일 입니다.'); return await this.userRepository.save({ email, password, mobileNumber }); }일때 findOne({ where: { email } }) { const users = this.mydb.filter((el) => el.email === email); if (users.length) return { ...users[0] }; return null; }입니다.
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part8: Entity Framework Core
C#으로 DB를 만든다음에 어떻게 외부에서 사용하나요??
이런식으로 데이터를 만들고 EC2 컴퓨터에다가 이 데이터를 옮기거나 하는 방법이 있나요?제 생각은 만든 파일을 메세지나 S3에 끌어다 넣고 올리는줄 알았는데상위 폴더를 열어서 파일을 가져갈까 생각해 봤는데 열수가 없다고 해요SQL Server 폴더에 들어가려고 해도 경로를 주지를 않아서만약에 이 데이터를 만든 걸 다른 곳에서 사용하고 싶을 때는 어떻게 해요 하나요? ㅜㅜ
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part8: Entity Framework Core
sql server 개체 탐색기가 보이지 않습니다
안녕하세요 SqlServer까지 다 설치하고 껏다켰는데도 view에 SQL Server object explorer가 생기지 않는 이유가 무엇일까요..
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part8: Entity Framework Core
17:33 Guild Update1vM시 질문입니다.
Guild guild = db.Guilds .Include(g => g.Members) .Single(g => g.GuildID = id); //.... guild.Members = new List<Player>(){ new Player() { Name = "Rookiss"} }; 위의 명령을 그대로 실행시켰는데 갑자기 DELETE관련 에러가 발생해서 보니 Player를 생성은 하는데 기존 Player테이블의 모든 데이터도 삭제가 되는 것 같습니다. 에러가 발생한 것은 모든 Player의 데이터를 삭제하려니 Item이 FK로 참조하고 있기 때문에 .ThenInclude(p => p.Item)또한 포함시켜야하는 것이었구요. 실제로 ThenInclude를 추가해서 실행해보니 에러 없이 잘 작동되고, Player테이블을 확인해보니 모든 Player가 삭제되었습니다. 이게 EFCore가 업데이트 되면서 정책이 바뀐건지, 아니면 제가 어디서 실수를 한건지 모르겠습니다.