codeflowhub 1.2.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/PKG-INFO +1 -1
  2. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/flow.py +32 -1
  3. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/service/airflow_exporter.py +28 -2
  4. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub.egg-info/PKG-INFO +1 -1
  5. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/setup.py +1 -1
  6. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/LICENSE +0 -0
  7. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/README.md +0 -0
  8. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/__init__.py +0 -0
  9. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/action.py +0 -0
  10. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/airflow/__init__.py +0 -0
  11. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/airflow/xcom.py +0 -0
  12. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/base.py +0 -0
  13. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/model.py +0 -0
  14. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/service/__init__.py +0 -0
  15. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/storage/__init__.py +0 -0
  16. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/storage/local_storage.py +0 -0
  17. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/storage/s3_storage.py +0 -0
  18. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/storage/storage.py +0 -0
  19. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/task.py +0 -0
  20. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/__init__.py +0 -0
  21. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/analyze_speaker_pkg/__init__.py +0 -0
  22. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/analyze_speaker_pkg/main.py +0 -0
  23. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/extract_voice_pkg/__init__.py +0 -0
  24. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/extract_voice_pkg/main.py +0 -0
  25. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/read_pdf_pkg/__init__.py +0 -0
  26. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/read_pdf_pkg/main.py +0 -0
  27. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/transcript_pkg/__init__.py +0 -0
  28. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub/template/transcript_pkg/main.py +0 -0
  29. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub.egg-info/SOURCES.txt +0 -0
  30. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub.egg-info/dependency_links.txt +0 -0
  31. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/codeflowhub.egg-info/top_level.txt +0 -0
  32. {codeflowhub-1.2.0 → codeflowhub-1.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeflowhub
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: workflow development tools
5
5
  Author: creaddiscans
6
6
  Author-email: creaddiscans@gmail.com
@@ -30,6 +30,7 @@ class FlowDecorator(BaseDecorator):
30
30
  export_destination:str # Export 시 생성 파일 저장 디렉토리
31
31
  default_args:dict # Airflow DAG default_args (owner, retries, retry_delay 등 override)
32
32
  schedule:str # Airflow DAG 스케줄 (cron 문자열 / preset / timedelta / None=수동 트리거)
33
+ doc_md:str # Airflow DAG doc_md (UI에 표시될 Markdown 문서)
33
34
  start_date:datetime # Airflow DAG start_date (None이면 export 시점)
34
35
  secrets:list # 모든 task에 공통 주입할 K8s Secret(env) 목록
35
36
  on_failure: 'BaseDecorator' = None # 모든 task의 기본 failure handler
@@ -38,7 +39,7 @@ class FlowDecorator(BaseDecorator):
38
39
  tags=None, annotations=None, service_account_name=None, volumes=None,
39
40
  airflow_sidecar_image=None, airflow_connection_id=None, repo=None, path=None,
40
41
  export_destination='dags', default_args=None, secrets=None, on_failure=None,
41
- schedule=None, start_date=None, schedule_interval=None, **kwargs):
42
+ schedule=None, start_date=None, doc_md=None, schedule_interval=None, **kwargs):
42
43
  # CLI 속성 먼저 초기화 (init()에서 사용됨)
43
44
  self._cli_export = None
44
45
  self._cli_job_dir = None
@@ -65,6 +66,7 @@ class FlowDecorator(BaseDecorator):
65
66
  self._resolve_schedule_alias(schedule, schedule_interval)
66
67
  )
67
68
  self.start_date = start_date
69
+ self.doc_md = self._normalize_doc_md(doc_md)
68
70
  # Design Ref: §3.2 — flow-level 공통 Secret(env)
69
71
  self.secrets = secrets or []
70
72
  self.on_failure = on_failure
@@ -75,6 +77,35 @@ class FlowDecorator(BaseDecorator):
75
77
  # super().__init__()는 마지막에 호출 (init()이 실행됨)
76
78
  super().__init__(*args, name=name, **kwargs)
77
79
 
80
+ @staticmethod
81
+ def _normalize_doc_md(doc_md):
82
+ """doc_md 정규화 (선언 시점에 조기 실패)
83
+
84
+ - str: Markdown 본문. 함수 안에서 triple-quote로 쓴 경우의 공통 들여쓰기를 제거
85
+ - Path: 해당 파일의 내용을 읽어 사용 (README 등 별도 파일 참조용)
86
+ - None / 빈 문자열: doc_md 미설정
87
+ """
88
+ import textwrap
89
+
90
+ if doc_md is None:
91
+ return None
92
+
93
+ if isinstance(doc_md, Path):
94
+ if not doc_md.exists():
95
+ raise FileNotFoundError(f'doc_md 파일을 찾을 수 없습니다: {doc_md}')
96
+ text = doc_md.read_text(encoding='utf-8')
97
+ elif isinstance(doc_md, str):
98
+ text = doc_md
99
+ else:
100
+ raise TypeError(
101
+ f'doc_md는 str(Markdown 본문), Path(파일 경로), None만 가능합니다. '
102
+ f'전달된 타입: {type(doc_md).__name__}'
103
+ )
104
+
105
+ # 선행 개행 제거 후 dedent → triple-quote 블록의 들여쓰기가 코드블록으로 렌더되는 것 방지
106
+ text = textwrap.dedent(text.lstrip('\n')).rstrip()
107
+ return text or None
108
+
78
109
  @staticmethod
79
110
  def _resolve_schedule_alias(schedule, schedule_interval):
80
111
  """schedule / schedule_interval(구 이름) 중 하나로 정리
@@ -269,13 +269,24 @@ SETUP_SCRIPT = """{setup_script}"""
269
269
  params_str = self._format_dict(self.flow.params, indent=1)
270
270
  params_line = f"\n params={params_str},"
271
271
 
272
- dag_definition = f'''dag = DAG(
272
+ # doc_md 설정 — 본문은 DAG_DOC_MD 변수로 분리 (여러 줄 Markdown)
273
+ doc_md_definition = ""
274
+ doc_md_line = ""
275
+ doc_md = getattr(self.flow, 'doc_md', None)
276
+ if doc_md:
277
+ doc_md_definition = f'''# DAG documentation (Airflow UI)
278
+ DAG_DOC_MD = {self._render_doc_md(doc_md)}
279
+
280
+ '''
281
+ doc_md_line = "\n doc_md=DAG_DOC_MD,"
282
+
283
+ dag_definition = f'''{doc_md_definition}dag = DAG(
273
284
  '{self.dag_id}',
274
285
  default_args={default_args_str},
275
286
  description='{description}',
276
287
  schedule={self._render_schedule(schedule)},
277
288
  catchup=False,
278
- tags={tags_str},{params_line}
289
+ tags={tags_str},{params_line}{doc_md_line}
279
290
  )
280
291
 
281
292
  '''
@@ -881,6 +892,21 @@ base_volume_mounts = [
881
892
  dependencies.append(f"[{deps_str}] >> {task.name}")
882
893
  return dependencies
883
894
 
895
+ def _render_doc_md(self, doc_md):
896
+ """Markdown 본문 → 생성 DAG의 문자열 리터럴 코드
897
+
898
+ 줄 단위로 repr()을 적용해 이어붙인다. triple-quote를 쓰면 본문에 포함된
899
+ 따옴표/백슬래시가 문법 오류를 만들 수 있으므로 repr로 완전히 이스케이프하고,
900
+ 줄마다 나누어 생성 DAG에서도 읽을 수 있게 유지한다.
901
+ """
902
+ lines = doc_md.split('\n')
903
+ if len(lines) == 1:
904
+ return repr(lines[0])
905
+
906
+ rendered = [f" {line + chr(10)!r}" for line in lines[:-1]]
907
+ rendered.append(f" {lines[-1]!r}")
908
+ return '(\n' + '\n'.join(rendered) + '\n)'
909
+
884
910
  def _render_schedule(self, schedule):
885
911
  """schedule → DAG 코드 문자열
886
912
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeflowhub
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: workflow development tools
5
5
  Author: creaddiscans
6
6
  Author-email: creaddiscans@gmail.com
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='codeflowhub',
5
- version='1.2.0',
5
+ version='1.3.0',
6
6
  description='workflow development tools',
7
7
  author='creaddiscans',
8
8
  author_email='creaddiscans@gmail.com',
File without changes
File without changes
File without changes