{"id":17864017,"url":"https://github.com/jomingyu/flask-large-application-example","last_synced_at":"2025-03-21T02:31:30.078Z","repository":{"id":48837990,"uuid":"90575739","full_name":"JoMingyu/Flask-Large-Application-Example","owner":"JoMingyu","description":"This is how I structure my large Flask applications.","archived":false,"fork":false,"pushed_at":"2023-02-16T01:34:05.000Z","size":790,"stargazers_count":117,"open_issues_count":1,"forks_count":13,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-17T19:52:23.683Z","etag":null,"topics":["flask","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoMingyu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-08T01:51:59.000Z","updated_at":"2024-11-12T08:04:28.000Z","dependencies_parsed_at":"2024-10-28T09:14:43.372Z","dependency_job_id":"73d34b1c-dee6-4484-a259-1d69c61e0402","html_url":"https://github.com/JoMingyu/Flask-Large-Application-Example","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoMingyu%2FFlask-Large-Application-Example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoMingyu%2FFlask-Large-Application-Example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoMingyu%2FFlask-Large-Application-Example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoMingyu%2FFlask-Large-Application-Example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoMingyu","download_url":"https://codeload.github.com/JoMingyu/Flask-Large-Application-Example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244725552,"owners_count":20499628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flask","python"],"created_at":"2024-10-28T09:08:11.202Z","updated_at":"2025-03-21T02:31:29.746Z","avatar_url":"https://github.com/JoMingyu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flask-Large-Application-Example \n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JoMingyu/Flask-Large-Application-Example/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JoMingyu/Flask-Large-Application-Example/?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/5df22321aa484650abb918f7a512274a)](https://www.codacy.com/app/JoMingyu/Flask-Large-Application-Example?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=JoMingyu/Flask-Large-Application-Example\u0026amp;utm_campaign=Badge_Grade)[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)\n\nThis is how I structure my large Flask applications.\n\n## About\n마이크로 웹 프레임워크인 Flask는 항상 개발자에게 구조에 대한 고민을 하게 만듭니다. 이 저장소는 제가 Flask를 배우기 시작했던 고등학교 1학년 때부터 지금까지의 시간동안 Flask 어플리케이션의 구조에 대해 고민한 흔적입니다. 근데 뭐 계속 개선하다 보니까 Flask에게만 특별히 적용할 수 있는 구조라기 보단 다른 웹 프레임워크들에서도 써먹을 수 있는 기반이 될 수도 있을 것 같네요.\n\n구조가 막 빡세다고 좋아지는 건 아닌 것 같아서, 조금 편하려고 복잡도를 높여버리는 모습은 지양했습니다. 이 레포의 '최신 버전'은 항상 제 기준에선 가장 편한 구조인데, 모두에게 그렇지도 않고 저도 자주 마음이 바뀝니다. 별거 아닌 코드에 커밋이 백단위인 게 이런 이유니까, 그냥 이거 가져가서 본인한테 맞게 커스텀하시면 좋을 것 같습니당 ㅎㅎ\n\n## 컨셉\n### application factory가 필요하다.([app/\\_\\_init\\_\\_.py](app/__init__.py))\nlocal에서 실행해보는 용도, 테스트 클라이언트를 얻는 용도, 배포 단에서 사용하는 용도 등으로 app 객체가 필요한데, 그들은 모두 extension 초기화 - view들 라우팅 - hook 달아주는 것은 똑같고, 단지 주입되는 config가 다른 것밖에 차이가 없습니다. create_app에서 config class들을 받도록 했습니다.\n\n### extension들은 lazy하게 초기화한다.([app/extensions.py](app/extensions.py), [app/\\_\\_init\\_\\_.py의 register_extensions](app/__init__.py#L7-L10))\n어떤 config를 주입할지는 create_app 함수가 호출된 후 정해지므로, config에 의해 초기화가 진행되는 extension들은 lazy하게 초기화하도록 했습니다. \n\n### config를 따로 패키지화해서, 선택지를 두어 관리한다.([config/](config))\n1. Flask에서 config는 class로 다루는 게 가장 좋다고 생각합니다.\n2. Config는 정적이어야 합니다. Config class 내에서 if절이 있는 형태는 좋지 않다고 생각합니다. 환경 변수에 따라 서로 다른 config를 주입해야 한다면, 각각에 맞게 class를 나누어 준비한 후 create_app을 호출하는 단에서 config를 상황에 맞게 전달하도록 만드는 게 좋다고 봅니다. \n3. 선택지마다 모듈을 만들어 두었습니다. 예를 들어, Local DB를 바라보도록 하는 config/Remote DB를 바라보도록 하는 config를 db_config라는 모듈에 LocalDBConfig, RemoteDBConfig 클래스로 준비한다.\n\n### 상수 config는 따로 관리되어야 한다.([constants/](constants))\nDRY한 코드를 작성하기 위해 리터럴을 지양해야 합니다. 게시글 목록 API에서 반환해주는 게시글 기본 갯수나, 특정 API의 사용 가능 시간같은 것들을 예로 들 수 있습니다. 이런 상수 config들은 따로 관리해야 하는 것은 맞지만, 굳이 app 객체에 주입할 필요가 없습니다. 따로 모듈만 만들어 두면 됨.\n\n### blueprint와 flask_restful이 필요하다.([app/views/\\__init\\__.py](app/views/__init__.py))\n다른 복잡한 이유가 아니라, 더 구조적인 라우팅을 위해 blueprint의 url prefix, [flask_restful의 MethodView 확장](app/views/sample/sample.py)이 도움을 주기 때문입니다.\n\n### context-dependent한 데이터는 따로 property class화 시킨다.([app/context.py](app/context.py))\nrequest, g 처럼 contenxt-dependent한 객체는 attribute가 dynamic하기 때문에, known attribute를 가지는 객체를 만들어 중계해주는 게 좋습니다. 휴먼 에러 예방에 도움이 되더라구요.\n\n### request context를 hook하는 친구들은 hook 패키지에 따로 관리한다.([app/hooks/](app/hooks))\n### view function이 호출되기 전의 전처리는 view decorator가 하는 것이 맞다.([app/decorators/](app/decorators))\n\n## I Referred\n### People\n\u003ca href=\"https://github.com/JungWinter\"\u003e정겨울님\u003c/a\u003e\n\n### Repository\n- https://github.com/imwilsonxu/fbone\n- https://github.com/cookiecutter-flask/cookiecutter-flask\n- https://github.com/JackStouffer/Flask-Foundation\n- https://github.com/alexandre-old/flask-rest-template\n- https://github.com/dpgaspar/Flask-AppBuilder\n- https://github.com/hack4impact/flask-base\n- https://github.com/gothinkster/flask-realworld-example-app\n- https://github.com/alexandre-old/flask-rest-template\n- https://github.com/JoMingyu/Flask-Large-Application-Example\n- https://github.com/yoshiya0503/Hermetica\n- https://github.com/realpython/cookiecutter-flask-skeleton\n- https://github.com/swaroopch/flask-boilerplate\n\n### Website\n\u003ca href=\"https://exploreflask.com/en/latest/\"\u003eExplore Flask - Explore Flask 1.0 documentation\u003c/a\u003e  \n\u003ca href=\"http://exploreflask.com/en/latest/organizing.html\"\u003eOrganizing your project - Explore Flask 1.0 documentation\u003c/a\u003e  \n\u003ca href=\"http://flask.pocoo.org/docs/0.12/patterns/\"\u003ePatterns of Flask - Flask Documentation (0.12)\u003c/a\u003e  \n\u003ca href=\"http://flask.pocoo.org/docs/0.12/patterns/packages/\"\u003eLarger Applications - Flask Documentation (0.12)\u003c/a\u003e  \n\u003ca href=\"http://flask.pocoo.org/snippets/category/application-structure/\"\u003eApplication Structure | Flask(A Python Microframework)\u003c/a\u003e  \n\n\u003ca href=\"https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications\"\u003eHow To Structure Large Flask Applications | DigitalOcean\u003c/a\u003e  \n\u003ca href=\"https://damyanon.net/post/flask-series-structure/\"\u003eHow to Structure a Flask Application\u003c/a\u003e  \n\u003ca href=\"https://www.gitbook.com/book/ecod/flask-large-app-how-to/details\"\u003eFlask Large App How to - GitBook\u003c/a\u003e  \n\u003ca href=\"https://libsora.so/posts/flask-project-structure/\"\u003eFlask Project 구조 예제 - /usr/lib/libsora.so\u003c/a\u003e  \n\u003ca href=\"https://stackoverflow.com/questions/14415500/common-folder-file-structure-in-flask-app\"\u003eStackOverflow - Common folder/file structure in Flask app\u003c/a\u003e\n\n### Presentation\n\u003ca href=\"http://slides.skien.cc/flask-hacks-and-best-practices/\"\u003eFlask Hacks and Best Practices\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjomingyu%2Fflask-large-application-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjomingyu%2Fflask-large-application-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjomingyu%2Fflask-large-application-example/lists"}