eKoNLPy 2.2.0__tar.gz → 2.2.2__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 (142) hide show
  1. ekonlpy-2.2.2/.github/workflows/deploy-docs.yaml +69 -0
  2. ekonlpy-2.2.2/.github/workflows/lint_and_test.yaml +97 -0
  3. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/workflows/release-test.yaml +18 -6
  4. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/workflows/release.yaml +18 -6
  5. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.gitignore +4 -1
  6. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/CHANGELOG.md +64 -0
  7. ekonlpy-2.2.2/CLAUDE.md +76 -0
  8. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/Makefile +3 -1
  9. ekonlpy-2.2.2/PKG-INFO +105 -0
  10. ekonlpy-2.2.2/README.md +74 -0
  11. ekonlpy-2.2.2/REVIEW.md +62 -0
  12. ekonlpy-2.2.2/docs/cli.md +27 -0
  13. ekonlpy-2.2.2/docs/contributing.md +53 -0
  14. ekonlpy-2.2.2/docs/dictionaries.md +56 -0
  15. ekonlpy-2.2.2/docs/index.md +34 -0
  16. ekonlpy-2.2.2/docs/installation.md +53 -0
  17. ekonlpy-2.2.2/docs/requirements.txt +5 -0
  18. ekonlpy-2.2.2/docs/sentiment.md +108 -0
  19. ekonlpy-2.2.2/docs/tagging.md +61 -0
  20. ekonlpy-2.2.2/docs/troubleshooting.md +48 -0
  21. ekonlpy-2.2.2/mkdocs.yaml +66 -0
  22. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/pyproject.toml +21 -9
  23. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/__cli__.py +7 -5
  24. ekonlpy-2.2.2/src/ekonlpy/_version.py +1 -0
  25. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/base/base.py +7 -7
  26. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/__init__.py +2 -0
  27. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/tagset.py +0 -1
  28. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/etag/_template.py +39 -27
  29. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/mecab/_mecab.py +38 -43
  30. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/mecab/_userdic.py +55 -23
  31. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/base.py +75 -37
  32. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/euko.py +12 -6
  33. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/hiv4.py +13 -4
  34. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/kosac.py +55 -40
  35. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/lm.py +13 -4
  36. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/mpck.py +152 -103
  37. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/mpko.py +9 -6
  38. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/utils.py +78 -60
  39. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/tag/_mecab.py +68 -47
  40. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/tag/_postprocess.py +17 -12
  41. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/utils/dictionary.py +9 -14
  42. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/utils/io.py +59 -54
  43. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/tests/ekonlpy/demo_breakdown_api.py +2 -2
  44. ekonlpy-2.2.2/tests/ekonlpy/test_io.py +66 -0
  45. ekonlpy-2.2.2/tests/ekonlpy/test_make_gate.py +29 -0
  46. ekonlpy-2.2.2/tests/ekonlpy/test_sentiment_regressions.py +152 -0
  47. ekonlpy-2.2.2/tests/ekonlpy/test_tagger_regressions.py +101 -0
  48. ekonlpy-2.2.2/tests/ekonlpy/test_userdic.py +90 -0
  49. ekonlpy-2.2.2/uv.lock +4526 -0
  50. ekonlpy-2.2.0/.github/workflows/deploy-docs.yaml +0 -40
  51. ekonlpy-2.2.0/.github/workflows/lint_and_test.yaml +0 -71
  52. ekonlpy-2.2.0/PKG-INFO +0 -233
  53. ekonlpy-2.2.0/README.md +0 -204
  54. ekonlpy-2.2.0/docs/index.md +0 -1
  55. ekonlpy-2.2.0/docs/requirements.txt +0 -7
  56. ekonlpy-2.2.0/mkdocs.yaml +0 -79
  57. ekonlpy-2.2.0/src/ekonlpy/_version.py +0 -1
  58. ekonlpy-2.2.0/uv.lock +0 -2192
  59. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.copier-config.poetry.yaml +0 -0
  60. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.copier-config.yaml +0 -0
  61. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.copierignore +0 -0
  62. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.editorconfig +0 -0
  63. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.envrc +0 -0
  64. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.gitattributes +0 -0
  65. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  66. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  67. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/dependabot.yaml +0 -0
  68. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/labels.yaml +0 -0
  69. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.github/release.yaml +0 -0
  70. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.pre-commit-config.yaml +0 -0
  71. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.python-version +0 -0
  72. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.readthedocs.yaml +0 -0
  73. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.tasks-extra.toml +0 -0
  74. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/.tasks.toml +0 -0
  75. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/CITATION.cff +0 -0
  76. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/CODE_OF_CONDUCT.md +0 -0
  77. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/CONTRIBUTING.md +0 -0
  78. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/LICENSE +0 -0
  79. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/codecov.yaml +0 -0
  80. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/codecov.yml +0 -0
  81. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/docs/CNAME +0 -0
  82. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/docs/eKoNLPy.pdf +0 -0
  83. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/docs/javascripts/mathjax.js +0 -0
  84. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/__init__.py +1 -1
  85. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/base/__init__.py +0 -0
  86. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/ADJECTIVES.txt +0 -0
  87. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/ADVERBS.txt +0 -0
  88. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/COUNTRY.txt +0 -0
  89. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/CURRENCY.txt +0 -0
  90. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/ECON_PHRASES.txt +0 -0
  91. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/ECON_TERMS.txt +0 -0
  92. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/ENTITY.txt +0 -0
  93. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/FOREIGN_TERMS.txt +0 -0
  94. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/GENERIC.txt +0 -0
  95. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/INDUSTRY_TERMS.txt +0 -0
  96. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/INSTITUTION.txt +0 -0
  97. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/LEMMA.txt +0 -0
  98. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/NAMES.txt +0 -0
  99. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/NOUNS.txt +0 -0
  100. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/POLARITY_PHRASES.txt +0 -0
  101. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/PROPER_NOUNS.txt +0 -0
  102. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SECTOR.txt +0 -0
  103. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/STOPWORDS.txt +0 -0
  104. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/STOPWORDS_CUST.txt +0 -0
  105. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/STOPWORDS_EN.txt +0 -0
  106. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/STOPWORDS_KOR.txt +0 -0
  107. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SYNONYM.txt +0 -0
  108. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SYNONYM_MAG.txt +0 -0
  109. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SYNONYM_PHRASES.txt +0 -0
  110. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SYNONYM_TERMS.txt +0 -0
  111. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/SYNONYM_VA.txt +0 -0
  112. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/UNIT.txt +0 -0
  113. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/dictionary/VERBS.txt +0 -0
  114. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/Currencies.txt +0 -0
  115. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/DatesandNumbers.txt +0 -0
  116. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/Generic.txt +0 -0
  117. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/Geographic.txt +0 -0
  118. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/HIV-4.csv +0 -0
  119. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/LM.csv +0 -0
  120. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/Names.txt +0 -0
  121. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/euko/mp_uncertainty_lexicon_lex.csv +0 -0
  122. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/euko/mp_uncertainty_lexicon_mkt.csv +0 -0
  123. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/kosac/expressive-type.csv +0 -0
  124. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/kosac/intensity.csv +0 -0
  125. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/kosac/polarity.csv +0 -0
  126. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_lexicon_lex.csv +0 -0
  127. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_lexicon_mkt.csv +0 -0
  128. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_lexicon_mkt_n3.csv +0 -0
  129. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_lexicon_mkt_n7.csv +0 -0
  130. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_vocab.txt +0 -0
  131. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/lexicon/mpko/mp_polarity_wordset.txt +0 -0
  132. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/data/model/MPKC.nbc +0 -0
  133. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/etag/__init__.py +0 -0
  134. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/mecab/__init__.py +0 -0
  135. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/py.typed +0 -0
  136. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/sentiment/__init__.py +0 -0
  137. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/tag/__init__.py +0 -0
  138. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/src/ekonlpy/utils/__init__.py +0 -0
  139. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/tests/ekonlpy/test_fugashi.py +0 -0
  140. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/tests/ekonlpy/test_init.py +0 -0
  141. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/tests/ekonlpy/test_sentiment.py +0 -0
  142. {ekonlpy-2.2.0 → ekonlpy-2.2.2}/tests/ekonlpy/test_tagger.py +0 -0
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: deploy-docs
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ pull_request:
7
+ paths:
8
+ - "README.md"
9
+ - "mkdocs.yaml"
10
+ - "docs/**"
11
+ - "pyproject.toml"
12
+ - ".github/workflows/deploy-docs.yaml"
13
+ push:
14
+ branches:
15
+ - master
16
+ # Paths can be used to only trigger actions when you have edited certain files, such as a file within the /docs directory
17
+ paths:
18
+ - "README.md"
19
+ - "mkdocs.yaml"
20
+ - "docs/**"
21
+ - "pyproject.toml"
22
+ - ".github/workflows/deploy-docs.yaml"
23
+
24
+ permissions:
25
+ contents: read
26
+
27
+ concurrency:
28
+ group: deploy-docs-${{ github.workflow }}-${{ github.ref }}
29
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
30
+
31
+ jobs:
32
+ validate:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
36
+
37
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
38
+ with:
39
+ python-version: 3.12
40
+
41
+ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
42
+ with:
43
+ key: docs-${{ runner.os }}-${{ hashFiles('docs/requirements.txt') }}
44
+ path: .cache
45
+ - name: Build documentation strictly
46
+ run: |
47
+ pip install .
48
+ pip install -r docs/requirements.txt
49
+ mkdocs build --strict
50
+
51
+ deploy:
52
+ if: >-
53
+ github.workflow == 'deploy-docs' && github.ref == 'refs/heads/master' &&
54
+ (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
55
+ needs: validate
56
+ runs-on: ubuntu-latest
57
+ permissions:
58
+ contents: write
59
+ steps:
60
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
61
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
62
+ with:
63
+ python-version: "3.12"
64
+ - name: Install documentation dependencies
65
+ run: |
66
+ pip install .
67
+ pip install -r docs/requirements.txt
68
+ - name: Deploy documentation
69
+ run: mkdocs gh-deploy --strict --force
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: lint & test
3
+
4
+ on:
5
+ workflow_call:
6
+ workflow_dispatch:
7
+ pull_request:
8
+ push:
9
+ branches:
10
+ - master
11
+ paths:
12
+ - "src/**"
13
+ - "tests/**"
14
+ - "pyproject.toml"
15
+ - "Makefile"
16
+ - ".python-version"
17
+ - ".pre-commit-config.yaml"
18
+ - ".github/workflows/lint_and_test.yaml"
19
+
20
+ permissions:
21
+ contents: read
22
+
23
+ concurrency:
24
+ group: lint-and-test-${{ github.workflow }}-${{ github.ref }}
25
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
26
+
27
+ jobs:
28
+ quality:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
32
+ - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
33
+ with:
34
+ enable-cache: true
35
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
36
+ with:
37
+ python-version: "3.12"
38
+ - run: make install
39
+ - run: make check
40
+ - run: make docs-test
41
+
42
+ build:
43
+ name: Python ${{ matrix.python-version }} / ${{ matrix.os }}
44
+ runs-on: ${{ matrix.os }}
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ os: [ubuntu-latest, macos-latest, windows-latest]
49
+ python-version: ["3.12", "3.13", "3.14"]
50
+ include:
51
+ - os: ubuntu-latest
52
+ python-version: "3.9"
53
+ - os: ubuntu-latest
54
+ python-version: "3.10"
55
+ - os: ubuntu-latest
56
+ python-version: "3.11"
57
+ defaults:
58
+ run:
59
+ shell: bash
60
+ env:
61
+ UV_PYTHON: ${{ matrix.python-version }}
62
+ steps:
63
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
64
+ - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
65
+ with:
66
+ enable-cache: true
67
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
68
+ with:
69
+ python-version: ${{ matrix.python-version }}
70
+ - name: Install runtime and test dependencies
71
+ run: uv sync --no-default-groups --group test
72
+ - name: Run tests with failure propagation
73
+ run: UV_NO_SYNC=true make test
74
+ - name: Check installed dependencies
75
+ run: uv pip check
76
+ - name: Build distributions
77
+ run: uv build
78
+ - name: Test installed wheel outside checkout
79
+ run: |
80
+ wheel=$(python -c 'from pathlib import Path; print(next(Path("dist").glob("*.whl")).resolve().as_posix())')
81
+ cd "$RUNNER_TEMP"
82
+ uv run --isolated --no-project --with "$wheel" --with 'pytest>=7.2.1' python -m pytest "$GITHUB_WORKSPACE/tests" -q
83
+ - name: Test installed source distribution
84
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14'
85
+ run: |
86
+ sdist=$(python -c 'from pathlib import Path; print(next(Path("dist").glob("*.tar.gz")).resolve().as_posix())')
87
+ cd "$RUNNER_TEMP"
88
+ uv run --isolated --no-project --with "$sdist" --with 'pytest>=7.2.1' python -m pytest "$GITHUB_WORKSPACE/tests" -q
89
+ - name: Upload test reports
90
+ if: always()
91
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
92
+ with:
93
+ name: tests-${{ matrix.os }}-${{ matrix.python-version }}
94
+ path: |
95
+ tests/pytest-coverage.txt
96
+ tests/pytest.xml
97
+ coverage.xml
@@ -8,10 +8,19 @@ on:
8
8
  branches:
9
9
  - test-release*
10
10
 
11
+ concurrency:
12
+ group: release-publication
13
+ cancel-in-progress: false
14
+
11
15
  jobs:
16
+ validate:
17
+ uses: ./.github/workflows/lint_and_test.yaml
18
+ permissions:
19
+ contents: read
20
+
12
21
  release:
22
+ needs: validate
13
23
  runs-on: ubuntu-latest
14
- concurrency: release
15
24
 
16
25
  permissions:
17
26
  id-token: write
@@ -22,19 +31,22 @@ jobs:
22
31
  # the branch was updated. To keep PSR working with the configured release branches,
23
32
  # we force a checkout of the desired release branch but at the workflow sha HEAD.
24
33
  - name: Setup | Checkout Repository at workflow sha
25
- uses: actions/checkout@v5
34
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
35
  with:
27
36
  fetch-depth: 0
28
37
  ref: ${{ github.sha }}
29
38
 
30
39
  - name: Setup | Force correct release branch on workflow sha
40
+ env:
41
+ RELEASE_BRANCH: ${{ github.ref_name }}
42
+ RELEASE_SHA: ${{ github.sha }}
31
43
  run: |
32
- git checkout -B ${{ github.ref_name }} ${{ github.sha }}
44
+ git checkout -B "$RELEASE_BRANCH" "$RELEASE_SHA"
33
45
 
34
46
  - name: Action | Semantic Version Release
35
47
  id: release
36
48
  # Adjust tag with desired version if applicable.
37
- uses: python-semantic-release/python-semantic-release@v10.4.1
49
+ uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
38
50
  with:
39
51
  build: true
40
52
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -42,14 +54,14 @@ jobs:
42
54
  git_committer_email: "actions@users.noreply.github.com"
43
55
 
44
56
  - name: Publish | Upload package to TestPyPI
45
- uses: pypa/gh-action-pypi-publish@release/v1
57
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
46
58
  if: steps.release.outputs.released == 'true'
47
59
  with:
48
60
  password: ${{ secrets.TEST_PYPI_API_TOKEN }}
49
61
  repository-url: https://test.pypi.org/legacy/
50
62
 
51
63
  - name: Publish | Upload to GitHub Release Assets
52
- uses: python-semantic-release/publish-action@v10.4.1
64
+ uses: python-semantic-release/publish-action@6d89e2de8d40ecb3717316ecbbf15a6fa8ea9039 # v10.6.2
53
65
  if: steps.release.outputs.released == 'true'
54
66
  with:
55
67
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -11,10 +11,19 @@ on:
11
11
  - "src/**"
12
12
  - "pyproject.toml"
13
13
 
14
+ concurrency:
15
+ group: release-publication
16
+ cancel-in-progress: false
17
+
14
18
  jobs:
19
+ validate:
20
+ uses: ./.github/workflows/lint_and_test.yaml
21
+ permissions:
22
+ contents: read
23
+
15
24
  release:
25
+ needs: validate
16
26
  runs-on: ubuntu-latest
17
- concurrency: release
18
27
 
19
28
  permissions:
20
29
  id-token: write
@@ -25,19 +34,22 @@ jobs:
25
34
  # the branch was updated. To keep PSR working with the configured release branches,
26
35
  # we force a checkout of the desired release branch but at the workflow sha HEAD.
27
36
  - name: Setup | Checkout Repository at workflow sha
28
- uses: actions/checkout@v5
37
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29
38
  with:
30
39
  fetch-depth: 0
31
40
  ref: ${{ github.sha }}
32
41
 
33
42
  - name: Setup | Force correct release branch on workflow sha
43
+ env:
44
+ RELEASE_BRANCH: ${{ github.ref_name }}
45
+ RELEASE_SHA: ${{ github.sha }}
34
46
  run: |
35
- git checkout -B ${{ github.ref_name }} ${{ github.sha }}
47
+ git checkout -B "$RELEASE_BRANCH" "$RELEASE_SHA"
36
48
 
37
49
  - name: Action | Semantic Version Release
38
50
  id: release
39
51
  # Adjust tag with desired version if applicable.
40
- uses: python-semantic-release/python-semantic-release@v10.4.1
52
+ uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
41
53
  with:
42
54
  build: true
43
55
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -45,11 +57,11 @@ jobs:
45
57
  git_committer_email: "actions@users.noreply.github.com"
46
58
 
47
59
  - name: Publish | Upload package to PyPI
48
- uses: pypa/gh-action-pypi-publish@release/v1
60
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
49
61
  if: steps.release.outputs.released == 'true'
50
62
 
51
63
  - name: Publish | Upload to GitHub Release Assets
52
- uses: python-semantic-release/publish-action@v10.4.1
64
+ uses: python-semantic-release/publish-action@6d89e2de8d40ecb3717316ecbbf15a6fa8ea9039 # v10.6.2
53
65
  if: steps.release.outputs.released == 'true'
54
66
  with:
55
67
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -29,4 +29,7 @@ pytest-coverage.*
29
29
 
30
30
 
31
31
  uv.lock
32
- workspace
32
+ workspace
33
+
34
+ # MkDocs output
35
+ /site/
@@ -1,5 +1,69 @@
1
1
  <!--next-version-placeholder-->
2
2
 
3
+ ## v2.2.2 (2026-09-17)
4
+
5
+ ### Bug Fixes
6
+
7
+ - Harden data loading, correct classifier metric bugs, and modernize typing
8
+ ([#125](https://github.com/entelecheia/eKoNLPy/pull/125),
9
+ [`a6144e1`](https://github.com/entelecheia/eKoNLPy/commit/a6144e18f09f680874648dd3e5f1f152e34b8833))
10
+
11
+ - Resolve fugashi-build-dict via PATH fallback and tighten loader consistency
12
+ ([#125](https://github.com/entelecheia/eKoNLPy/pull/125),
13
+ [`a6144e1`](https://github.com/entelecheia/eKoNLPy/commit/a6144e18f09f680874648dd3e5f1f152e34b8833))
14
+
15
+ - Use forward slashes for dictionary compiler paths on Windows
16
+ ([#125](https://github.com/entelecheia/eKoNLPy/pull/125),
17
+ [`a6144e1`](https://github.com/entelecheia/eKoNLPy/commit/a6144e18f09f680874648dd3e5f1f152e34b8833))
18
+
19
+ ### Testing
20
+
21
+ - Expect normalized dictionary compiler paths in build_userdic assertions
22
+ ([#125](https://github.com/entelecheia/eKoNLPy/pull/125),
23
+ [`a6144e1`](https://github.com/entelecheia/eKoNLPy/commit/a6144e18f09f680874648dd3e5f1f152e34b8833))
24
+
25
+
26
+ ## v2.2.1 (2026-09-16)
27
+
28
+ ### Bug Fixes
29
+
30
+ - Modernize Python compatibility, documentation, and CI
31
+ ([#124](https://github.com/entelecheia/eKoNLPy/pull/124),
32
+ [`c07fe16`](https://github.com/entelecheia/eKoNLPy/commit/c07fe16d0b00bbeb0b0f219cf04e22dea2b10815))
33
+
34
+ - Restore modern Python and notebook reliability
35
+ ([#124](https://github.com/entelecheia/eKoNLPy/pull/124),
36
+ [`c07fe16`](https://github.com/entelecheia/eKoNLPy/commit/c07fe16d0b00bbeb0b0f219cf04e22dea2b10815))
37
+
38
+ ### Build System
39
+
40
+ - **deps**: Bump astral-sh/setup-uv from 6 to 7
41
+ ([`50dbab6`](https://github.com/entelecheia/eKoNLPy/commit/50dbab651ae9999b136f2f375fc02f4f6b7e325a))
42
+
43
+ - **deps**: Update pandas requirement
44
+ ([`66e3713`](https://github.com/entelecheia/eKoNLPy/commit/66e37130d57c7ce5c64b9104b7fe0f17b39f326d))
45
+
46
+ ### Continuous Integration
47
+
48
+ - Avoid duplicate branch and pull request test runs
49
+ ([#124](https://github.com/entelecheia/eKoNLPy/pull/124),
50
+ [`c07fe16`](https://github.com/entelecheia/eKoNLPy/commit/c07fe16d0b00bbeb0b0f219cf04e22dea2b10815))
51
+
52
+ ### Documentation
53
+
54
+ - Add CLAUDE.md and REVIEW.md for the agent contract
55
+ ([#121](https://github.com/entelecheia/eKoNLPy/pull/121),
56
+ [`52f0fb3`](https://github.com/entelecheia/eKoNLPy/commit/52f0fb3cb1934b2de98265559f4aab54e33ecabf))
57
+
58
+ - Correct CI scope, mypy status, and the ruff test ignores
59
+ ([#121](https://github.com/entelecheia/eKoNLPy/pull/121),
60
+ [`52f0fb3`](https://github.com/entelecheia/eKoNLPy/commit/52f0fb3cb1934b2de98265559f4aab54e33ecabf))
61
+
62
+ - State what the gates actually run and the make test blind spot
63
+ ([#121](https://github.com/entelecheia/eKoNLPy/pull/121),
64
+ [`52f0fb3`](https://github.com/entelecheia/eKoNLPy/commit/52f0fb3cb1934b2de98265559f4aab54e33ecabf))
65
+
66
+
3
67
  ## v2.2.0 (2025-09-21)
4
68
 
5
69
  ### Chores
@@ -0,0 +1,76 @@
1
+ # eKoNLPy
2
+
3
+ Korean NLP library for economic analysis: it extends the KoNLPy `Mecab` tagger so economic terms,
4
+ financial institutions, and company names are treated as single nouns, and adds sentiment scoring
5
+ for monetary policy text (hawkish or dovish). Package `ekonlpy`, sources under `src/ekonlpy/`.
6
+
7
+ `README.md` and the docs site (https://ekonlpy.entelecheia.ai) carry the usage detail. This file
8
+ covers what an agent needs before its first commit.
9
+
10
+ ## Commands
11
+
12
+ - Install: `make install` (uv sync, then installs the pre-commit hooks)
13
+ - Check: `make check` (lock-file consistency, `pre-commit run -a`, `deptry .`)
14
+ - Test: `make test` (pytest with coverage, writes `tests/pytest.xml` and `coverage.xml`)
15
+ - Build: `make build` (wheel via hatch), Docs: `make docs-test` (strict mkdocs build), `make docs`
16
+ - Bare `make` prints the target list (`.DEFAULT_GOAL := help`).
17
+
18
+ ## Verifying your work
19
+
20
+ ```bash
21
+ make check && make test
22
+ ```
23
+
24
+ - **Run both before reporting a task complete, and paste the output.** Run `make install` first in a
25
+ fresh clone, or the hooks `make check` invokes are not present.
26
+ - Make recipes use Bash; the test recipe explicitly enables `pipefail` (also on macOS Make 3.81).
27
+ A failing pytest run must fail `make test` while still
28
+ writing the coverage log. Windows contributors can use Git Bash for Make commands.
29
+ - When a test fails, fix the code, not the test. Do not weaken a gate to make a run pass.
30
+ - CI runs on every PR and on master pushes changing source, tests, dependency metadata, Makefile,
31
+ Python pin, hooks, or the test workflow. It tests Python 3.12-3.14 on Linux/macOS/Windows
32
+ and 3.9-3.11 on Linux, including installed wheel tests outside the checkout. The Linux 3.14
33
+ job also tests the sdist. Quality checks run separately on 3.12.
34
+ - Minimal test setup: `uv sync --no-default-groups --group test`; then
35
+ `UV_NO_SYNC=true make test`. Set `UV_PYTHON` to override the development interpreter in CI.
36
+
37
+ ## Conventions
38
+
39
+ - Python 3.12 is pinned for development (`.python-version`); the package supports >=3.9,<4.0, and
40
+ ruff targets py39, so do not use syntax newer than 3.9 in shipped code. Line length 120.
41
+ - Commit messages are gated: the commitizen `commit-msg` pre-commit hook rejects anything that is
42
+ not a conventional commit.
43
+ - Versioning is automated with python-semantic-release; do not bump versions by hand.
44
+ - Tooling is **configured but not all wired into a gate**. `pyproject.toml` holds settings for ruff
45
+ (including bandit `S` rules), black, isort, flake8, mypy, deptry, and coverage, yet `make check`
46
+ runs only the lock check, the configured pre-commit hooks, and `deptry`. The pre-commit hooks are
47
+ pygrep checks, whitespace and end-of-file fixers scoped to Python, YAML/JSON/large-file checks,
48
+ and the commitizen `commit-msg` gate. Run the formatters and linters yourself (`uv run ruff check
49
+ .`, `uv run black --check .`, `uv run mypy src`) or through the `.tasks.toml` poe tasks; nothing
50
+ else will.
51
+
52
+ ## Things the agent gets wrong
53
+
54
+ - **`src/ekonlpy/_version.py` is generated** by semantic-release (`version_variables` in
55
+ `pyproject.toml`). black and isort exclude it and flake8 carries a `W292` per-file ignore for it.
56
+ Never hand-edit it.
57
+ - **The lock file is local, not committed**: `uv.lock` is gitignored and generated by `make install`
58
+ (`uv sync`). `make check` starts with `uv lock --locked`, which fails when the generated lock no
59
+ longer matches `pyproject.toml`, so re-run `uv lock` (or `make install`) after editing
60
+ dependencies. There is nothing to stage for it.
61
+ - **`deptry` flags dependency drift**: an import that is not a declared dependency, or a declared
62
+ dependency nothing imports, fails the gate.
63
+ - **pre-commit is `fail_fast`**: the first failing hook stops the run, so fix hooks in order rather
64
+ than assuming one failure is the only one.
65
+ - **Tests live in `tests/ekonlpy/`** and `testpaths = ["tests"]`; flake8 excludes `tests`, and ruff
66
+ keeps its rules there minus four per-file ignores: `S101`, `UP035`, `UP006`, `S603`.
67
+ - **Tagger behavior changed in 2.0.0**: the extended tagger is the default and `Mecab` is importable
68
+ from `ekonlpy` directly; `use_original_tagger=True` restores the original path, and `Mecab.pos()`
69
+ takes `text`, not `phrase`. Changing tagger defaults is user-visible and needs a test.
70
+ - **The dictionary is a dependency, not vendored**: `mecab-ko-dic` and `fugashi` supply it, so a
71
+ tagging difference across machines is usually a dependency version difference.
72
+
73
+ ---
74
+
75
+ Contract and update rule for this file: `_meta/rules/development-lifecycle.md` §6 in the workspace
76
+ repo. When the same mistake appears twice, add the correction here in the same PR.
@@ -1,3 +1,5 @@
1
+ SHELL := bash
2
+
1
3
  .PHONY: install
2
4
  install: install-uv ## Install the virtual environment and install the pre-commit hooks
3
5
  @echo "🚀 Creating virtual environment using uv"
@@ -16,7 +18,7 @@ check: ## Run code quality tools.
16
18
  .PHONY: test
17
19
  test: ## Test the code with pytest
18
20
  @echo "🚀 Testing code: Running pytest"
19
- @uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml --junitxml=tests/pytest.xml | tee tests/pytest-coverage.txt
21
+ @set -o pipefail; uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml --junitxml=tests/pytest.xml | tee tests/pytest-coverage.txt
20
22
 
21
23
  .PHONY: build
22
24
  build: clean-build ## Build wheel file
ekonlpy-2.2.2/PKG-INFO ADDED
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: eKoNLPy
3
+ Version: 2.2.2
4
+ Summary: A Korean natural language processing toolkit for economic analysis
5
+ Project-URL: Homepage, https://ekonlpy.entelecheia.ai
6
+ Project-URL: Repository, https://github.com/entelecheia/eKoNLPy
7
+ Project-URL: Documentation, https://ekonlpy.entelecheia.ai
8
+ Author-email: Young Joon Lee <yj.lee@chu.ac.kr>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: KoNLPy,Monetary policy,Sentiment analysis,Tokenization
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: <4.0,>=3.9
23
+ Requires-Dist: click>=8.1.6
24
+ Requires-Dist: fugashi>=1.3.3
25
+ Requires-Dist: mecab-ko-dic>=1.0.0
26
+ Requires-Dist: nltk>=3.8.1
27
+ Requires-Dist: numpy>=1.23.5
28
+ Requires-Dist: pandas>=1.5.3
29
+ Requires-Dist: scipy>1.10.0
30
+ Description-Content-Type: text/markdown
31
+
32
+ # eKoNLPy
33
+
34
+ [![PyPI](https://img.shields.io/pypi/v/ekonlpy.svg)](https://pypi.org/project/ekonlpy/)
35
+ [![License](https://img.shields.io/github/license/entelecheia/eKoNLPy)](https://github.com/entelecheia/eKoNLPy/blob/master/LICENSE)
36
+ [![Documentation](https://img.shields.io/badge/docs-ekonlpy.entelecheia.ai-4c7)](https://ekonlpy.entelecheia.ai)
37
+
38
+ eKoNLPy is a Python library for Korean text processing in economic and financial
39
+ research. It provides a MeCab based tagger with an economic vocabulary and
40
+ lexicon based sentiment analyzers for Korean and English text.
41
+
42
+ This documentation follows the repository source, which may include unreleased
43
+ changes. Published versions are listed on [PyPI](https://pypi.org/project/ekonlpy/).
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ python -m pip install ekonlpy
49
+ ```
50
+
51
+ eKoNLPy supports Python 3.9 or newer, below Python 4. The main CI matrix tests
52
+ Python 3.12-3.14 on Linux, macOS, and Windows, and Python 3.9-3.11 on Linux.
53
+ For Jupyter or Colab, install into the active kernel:
54
+
55
+ ```python
56
+ %pip install ekonlpy
57
+ ```
58
+
59
+ ## Quick start
60
+
61
+ ```python
62
+ from ekonlpy import Mecab
63
+
64
+ tagger = Mecab()
65
+ print(tagger.pos("금통위는 금리정책을 결정했다."))
66
+ ```
67
+
68
+ The default tagger applies eKoNLPy's extended vocabulary. Use
69
+ `Mecab(use_original_tagger=True)` for the underlying fugashi/MeCab tagger.
70
+ Instances keep their dictionaries, synonyms, and lemmas separate from one
71
+ another. See the [documentation](https://ekonlpy.entelecheia.ai) for tagging,
72
+ custom vocabularies, sentiment analyzers, and the CLI.
73
+
74
+ ## Sentiment example
75
+
76
+ ```python
77
+ from ekonlpy.sentiment import MPKO
78
+
79
+ analyzer = MPKO(kind=1)
80
+ tokens = analyzer.tokenize("금리 인상이 필요하다")
81
+ print(analyzer.get_score(tokens))
82
+ ```
83
+
84
+ The sentiment package also exports `EUKO`, `KSA`, `HIV4`, `LM`, and `MPCK`.
85
+ `KSA` uses KoNLPy's Java backed `Kkma` tokenizer and is optional. The separate
86
+ `KOSAC` analyzer is another optional KoNLPy integration.
87
+
88
+ ## Development
89
+
90
+ ```bash
91
+ make install
92
+ make check
93
+ make test
94
+ make docs-test
95
+ ```
96
+
97
+ Contributions and issue reports are welcome on [GitHub](https://github.com/entelecheia/eKoNLPy).
98
+ For project documentation and verification steps, see the
99
+ [contributing guide](https://ekonlpy.entelecheia.ai/contributing/).
100
+
101
+ ## License and citation
102
+
103
+ eKoNLPy is released under the [MIT License](LICENSE). Research users can cite
104
+ the project and the monetary policy text mining paper listed in the
105
+ [contributing and citation notes](https://ekonlpy.entelecheia.ai/contributing/).
@@ -0,0 +1,74 @@
1
+ # eKoNLPy
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/ekonlpy.svg)](https://pypi.org/project/ekonlpy/)
4
+ [![License](https://img.shields.io/github/license/entelecheia/eKoNLPy)](https://github.com/entelecheia/eKoNLPy/blob/master/LICENSE)
5
+ [![Documentation](https://img.shields.io/badge/docs-ekonlpy.entelecheia.ai-4c7)](https://ekonlpy.entelecheia.ai)
6
+
7
+ eKoNLPy is a Python library for Korean text processing in economic and financial
8
+ research. It provides a MeCab based tagger with an economic vocabulary and
9
+ lexicon based sentiment analyzers for Korean and English text.
10
+
11
+ This documentation follows the repository source, which may include unreleased
12
+ changes. Published versions are listed on [PyPI](https://pypi.org/project/ekonlpy/).
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ python -m pip install ekonlpy
18
+ ```
19
+
20
+ eKoNLPy supports Python 3.9 or newer, below Python 4. The main CI matrix tests
21
+ Python 3.12-3.14 on Linux, macOS, and Windows, and Python 3.9-3.11 on Linux.
22
+ For Jupyter or Colab, install into the active kernel:
23
+
24
+ ```python
25
+ %pip install ekonlpy
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ ```python
31
+ from ekonlpy import Mecab
32
+
33
+ tagger = Mecab()
34
+ print(tagger.pos("금통위는 금리정책을 결정했다."))
35
+ ```
36
+
37
+ The default tagger applies eKoNLPy's extended vocabulary. Use
38
+ `Mecab(use_original_tagger=True)` for the underlying fugashi/MeCab tagger.
39
+ Instances keep their dictionaries, synonyms, and lemmas separate from one
40
+ another. See the [documentation](https://ekonlpy.entelecheia.ai) for tagging,
41
+ custom vocabularies, sentiment analyzers, and the CLI.
42
+
43
+ ## Sentiment example
44
+
45
+ ```python
46
+ from ekonlpy.sentiment import MPKO
47
+
48
+ analyzer = MPKO(kind=1)
49
+ tokens = analyzer.tokenize("금리 인상이 필요하다")
50
+ print(analyzer.get_score(tokens))
51
+ ```
52
+
53
+ The sentiment package also exports `EUKO`, `KSA`, `HIV4`, `LM`, and `MPCK`.
54
+ `KSA` uses KoNLPy's Java backed `Kkma` tokenizer and is optional. The separate
55
+ `KOSAC` analyzer is another optional KoNLPy integration.
56
+
57
+ ## Development
58
+
59
+ ```bash
60
+ make install
61
+ make check
62
+ make test
63
+ make docs-test
64
+ ```
65
+
66
+ Contributions and issue reports are welcome on [GitHub](https://github.com/entelecheia/eKoNLPy).
67
+ For project documentation and verification steps, see the
68
+ [contributing guide](https://ekonlpy.entelecheia.ai/contributing/).
69
+
70
+ ## License and citation
71
+
72
+ eKoNLPy is released under the [MIT License](LICENSE). Research users can cite
73
+ the project and the monetary policy text mining paper listed in the
74
+ [contributing and citation notes](https://ekonlpy.entelecheia.ai/contributing/).