dishka-fastmcp 1.0.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.
- dishka_fastmcp-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- dishka_fastmcp-1.0.0/.github/ISSUE_TEMPLATE/config.yml +11 -0
- dishka_fastmcp-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- dishka_fastmcp-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- dishka_fastmcp-1.0.0/.github/dependabot.yml +15 -0
- dishka_fastmcp-1.0.0/.github/workflows/ci.yml +100 -0
- dishka_fastmcp-1.0.0/.github/workflows/release.yml +72 -0
- dishka_fastmcp-1.0.0/.gitignore +218 -0
- dishka_fastmcp-1.0.0/.pre-commit-config.yaml +64 -0
- dishka_fastmcp-1.0.0/.python-version +1 -0
- dishka_fastmcp-1.0.0/CHANGELOG.md +53 -0
- dishka_fastmcp-1.0.0/CODE_OF_CONDUCT.md +65 -0
- dishka_fastmcp-1.0.0/CONTRIBUTING.md +58 -0
- dishka_fastmcp-1.0.0/LICENSE +21 -0
- dishka_fastmcp-1.0.0/PKG-INFO +228 -0
- dishka_fastmcp-1.0.0/README.md +203 -0
- dishka_fastmcp-1.0.0/SECURITY.md +22 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/__init__.py +24 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/_container.py +75 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/_inject.py +72 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/_middleware.py +78 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/exceptions.py +7 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/lifespan.py +41 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/providers.py +26 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/py.typed +0 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/setup.py +17 -0
- dishka_fastmcp-1.0.0/dishka_fastmcp/version.py +15 -0
- dishka_fastmcp-1.0.0/docs/llms.txt +85 -0
- dishka_fastmcp-1.0.0/pyproject.toml +176 -0
- dishka_fastmcp-1.0.0/tests/test_lifespan.py +62 -0
- dishka_fastmcp-1.0.0/tests/test_resources_prompts.py +141 -0
- dishka_fastmcp-1.0.0/tests/test_threading.py +63 -0
- dishka_fastmcp-1.0.0/tests/test_tools.py +160 -0
- dishka_fastmcp-1.0.0/tests/test_version.py +8 -0
- dishka_fastmcp-1.0.0/tests/typing_surface.py +49 -0
- dishka_fastmcp-1.0.0/uv.lock +2000 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report incorrect behaviour
|
|
4
|
+
title: ''
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**What happened**
|
|
10
|
+
A clear description of the bug.
|
|
11
|
+
|
|
12
|
+
**Expected behaviour**
|
|
13
|
+
What you expected instead.
|
|
14
|
+
|
|
15
|
+
**Minimal reproduction**
|
|
16
|
+
```python
|
|
17
|
+
# the smallest server + provider + handler that triggers the issue
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Environment**
|
|
21
|
+
- dishka-fastmcp version:
|
|
22
|
+
- dishka version:
|
|
23
|
+
- fastmcp version:
|
|
24
|
+
- Python version:
|
|
25
|
+
- OS:
|
|
26
|
+
- Sync or async container? Tool, resource or prompt?
|
|
27
|
+
|
|
28
|
+
**Additional context**
|
|
29
|
+
Anything else that helps — the generated schema, traceback, etc.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/bagowix/dishka-fastmcp/security/advisories/new
|
|
5
|
+
about: Please report security issues privately, not as public issues.
|
|
6
|
+
- name: dishka documentation
|
|
7
|
+
url: https://dishka.readthedocs.io/
|
|
8
|
+
about: Scopes, providers and the container API.
|
|
9
|
+
- name: FastMCP documentation
|
|
10
|
+
url: https://gofastmcp.com/
|
|
11
|
+
about: Tools, resources, prompts and middleware.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea or improvement
|
|
4
|
+
title: ''
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**Problem**
|
|
10
|
+
What are you trying to do that dishka-fastmcp makes hard or impossible today?
|
|
11
|
+
|
|
12
|
+
**Proposed solution**
|
|
13
|
+
What you'd like to see. API sketches welcome.
|
|
14
|
+
|
|
15
|
+
**Alternatives considered**
|
|
16
|
+
Other approaches you weighed.
|
|
17
|
+
|
|
18
|
+
**Scope check**
|
|
19
|
+
dishka-fastmcp is deliberately a thin, correct bridge over FastMCP's native
|
|
20
|
+
extension points. It supports the scopes FastMCP can honor (`APP` and `REQUEST`);
|
|
21
|
+
`SESSION` is out until FastMCP exposes a session-teardown hook. Injection logic
|
|
22
|
+
stays delegated to dishka's `wrap_injection`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this change and why? -->
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] Tests added or updated (suite stays at 100% coverage)
|
|
8
|
+
- [ ] Registration changes assert the generated tool/resource/prompt schema
|
|
9
|
+
- [ ] `uv run ruff format --check` and `uv run ruff check` pass
|
|
10
|
+
- [ ] `uv run mypy` and `uv run pyright` pass
|
|
11
|
+
- [ ] `CHANGELOG.md` `[Unreleased]` updated
|
|
12
|
+
- [ ] Commits follow Conventional Commits
|
|
13
|
+
|
|
14
|
+
## Related issues
|
|
15
|
+
|
|
16
|
+
<!-- e.g. Closes #123 -->
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
commit-message:
|
|
8
|
+
prefix: "ci"
|
|
9
|
+
|
|
10
|
+
- package-ecosystem: "uv"
|
|
11
|
+
directory: "/"
|
|
12
|
+
schedule:
|
|
13
|
+
interval: "weekly"
|
|
14
|
+
commit-message:
|
|
15
|
+
prefix: "chore"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ci-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
# Least-privilege default for every job; the coverage job overrides it with
|
|
13
|
+
# the write scopes py-cov-action needs.
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
quality:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
python-version: ['3.11', '3.12', '3.13', '3.14']
|
|
24
|
+
env:
|
|
25
|
+
UV_PYTHON: ${{ matrix.python-version }}
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v7
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v7
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: uv sync --frozen
|
|
36
|
+
|
|
37
|
+
- name: Ruff format
|
|
38
|
+
run: uv run ruff format --check
|
|
39
|
+
|
|
40
|
+
- name: Ruff lint
|
|
41
|
+
run: uv run ruff check
|
|
42
|
+
|
|
43
|
+
- name: Mypy
|
|
44
|
+
run: uv run mypy --num-workers 2
|
|
45
|
+
|
|
46
|
+
- name: Pyright
|
|
47
|
+
run: uv run pyright
|
|
48
|
+
|
|
49
|
+
- name: Tests
|
|
50
|
+
run: uv run pytest --cov
|
|
51
|
+
|
|
52
|
+
deps-min:
|
|
53
|
+
name: Dependencies (minimum versions)
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
env:
|
|
56
|
+
UV_PYTHON: '3.11'
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v7
|
|
59
|
+
|
|
60
|
+
- name: Install uv
|
|
61
|
+
uses: astral-sh/setup-uv@v7
|
|
62
|
+
with:
|
|
63
|
+
enable-cache: true
|
|
64
|
+
|
|
65
|
+
- name: Install dependencies
|
|
66
|
+
run: uv sync --frozen
|
|
67
|
+
|
|
68
|
+
- name: Pin dishka and fastmcp to minimum supported versions
|
|
69
|
+
run: >-
|
|
70
|
+
uv pip install
|
|
71
|
+
'dishka==1.10.1'
|
|
72
|
+
'fastmcp==3.2.4'
|
|
73
|
+
|
|
74
|
+
- name: Tests against minimum versions
|
|
75
|
+
run: uv run --no-sync pytest
|
|
76
|
+
|
|
77
|
+
coverage:
|
|
78
|
+
name: Coverage
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
permissions:
|
|
81
|
+
contents: write
|
|
82
|
+
pull-requests: write
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v7
|
|
85
|
+
|
|
86
|
+
- name: Install uv
|
|
87
|
+
uses: astral-sh/setup-uv@v7
|
|
88
|
+
with:
|
|
89
|
+
enable-cache: true
|
|
90
|
+
|
|
91
|
+
- name: Install dependencies
|
|
92
|
+
run: uv sync --frozen
|
|
93
|
+
|
|
94
|
+
- name: Run tests with coverage
|
|
95
|
+
run: uv run pytest --cov
|
|
96
|
+
|
|
97
|
+
- name: Coverage badge and PR comment
|
|
98
|
+
uses: py-cov-action/python-coverage-comment-action@v3
|
|
99
|
+
with:
|
|
100
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v7
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: uv sync --frozen
|
|
24
|
+
|
|
25
|
+
# The package version is static in dishka_fastmcp/version.py, so a tag that
|
|
26
|
+
# disagrees with it would publish the wrong build (or collide on PyPI).
|
|
27
|
+
- name: Verify tag matches package version
|
|
28
|
+
run: |
|
|
29
|
+
version=$(uv run python -c 'from dishka_fastmcp.version import VERSION; print(VERSION)')
|
|
30
|
+
if [ "$GITHUB_REF_NAME" != "v$version" ]; then
|
|
31
|
+
echo "::error::tag $GITHUB_REF_NAME does not match package version $version (expected v$version)"
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
- name: Tests
|
|
36
|
+
run: uv run pytest
|
|
37
|
+
|
|
38
|
+
- name: Build sdist and wheel
|
|
39
|
+
run: uv build
|
|
40
|
+
|
|
41
|
+
- name: Upload artifacts
|
|
42
|
+
uses: actions/upload-artifact@v7
|
|
43
|
+
with:
|
|
44
|
+
name: dist
|
|
45
|
+
path: dist/
|
|
46
|
+
|
|
47
|
+
publish:
|
|
48
|
+
needs: build
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
environment: pypi
|
|
51
|
+
permissions:
|
|
52
|
+
id-token: write
|
|
53
|
+
steps:
|
|
54
|
+
- name: Download artifacts
|
|
55
|
+
uses: actions/download-artifact@v8
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist/
|
|
59
|
+
|
|
60
|
+
- name: Publish to PyPI
|
|
61
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
62
|
+
|
|
63
|
+
github-release:
|
|
64
|
+
needs: publish
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
permissions:
|
|
67
|
+
contents: write
|
|
68
|
+
steps:
|
|
69
|
+
- name: Create GitHub Release
|
|
70
|
+
uses: softprops/action-gh-release@v3
|
|
71
|
+
with:
|
|
72
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
default_install_hook_types:
|
|
2
|
+
- pre-commit
|
|
3
|
+
- commit-msg
|
|
4
|
+
|
|
5
|
+
default_stages: [pre-commit, pre-push]
|
|
6
|
+
|
|
7
|
+
repos:
|
|
8
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
9
|
+
rev: v0.15.22
|
|
10
|
+
hooks:
|
|
11
|
+
- id: ruff-format
|
|
12
|
+
- id: ruff-check
|
|
13
|
+
name: ruff-check
|
|
14
|
+
|
|
15
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
16
|
+
rev: v6.0.0
|
|
17
|
+
hooks:
|
|
18
|
+
- id: check-docstring-first
|
|
19
|
+
exclude: ^dishka_fastmcp/version\.py$
|
|
20
|
+
- id: check-ast
|
|
21
|
+
- id: check-toml
|
|
22
|
+
- id: check-yaml
|
|
23
|
+
- id: check-merge-conflict
|
|
24
|
+
- id: check-case-conflict
|
|
25
|
+
- id: debug-statements
|
|
26
|
+
- id: end-of-file-fixer
|
|
27
|
+
- id: mixed-line-ending
|
|
28
|
+
- id: trailing-whitespace
|
|
29
|
+
- id: detect-private-key
|
|
30
|
+
- id: no-commit-to-branch
|
|
31
|
+
args: [--branch, main]
|
|
32
|
+
|
|
33
|
+
- repo: local
|
|
34
|
+
hooks:
|
|
35
|
+
- id: mypy
|
|
36
|
+
name: mypy
|
|
37
|
+
entry: uv run mypy --num-workers 2
|
|
38
|
+
language: system
|
|
39
|
+
types: [python]
|
|
40
|
+
pass_filenames: false
|
|
41
|
+
args: [--config-file=./pyproject.toml]
|
|
42
|
+
|
|
43
|
+
- id: pyright
|
|
44
|
+
name: pyright
|
|
45
|
+
entry: uv run pyright
|
|
46
|
+
language: system
|
|
47
|
+
types: [python]
|
|
48
|
+
pass_filenames: false
|
|
49
|
+
|
|
50
|
+
- repo: https://github.com/jackdewinter/pymarkdown
|
|
51
|
+
rev: v0.9.38
|
|
52
|
+
hooks:
|
|
53
|
+
- id: pymarkdown
|
|
54
|
+
name: pymarkdown
|
|
55
|
+
files: \.md$
|
|
56
|
+
pass_filenames: true
|
|
57
|
+
exclude: (CHANGELOG\.md|^\.github/)
|
|
58
|
+
|
|
59
|
+
- repo: https://github.com/compilerla/conventional-pre-commit
|
|
60
|
+
rev: v4.4.0
|
|
61
|
+
hooks:
|
|
62
|
+
- id: conventional-pre-commit
|
|
63
|
+
stages: [commit-msg]
|
|
64
|
+
args: []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [1.0.0] - 2026-07-21
|
|
10
|
+
|
|
11
|
+
First release. dishka dependency injection for FastMCP tools, resources and
|
|
12
|
+
prompts.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `setup_dishka(container, mcp)` — registers the middleware that publishes the
|
|
17
|
+
root container and current FastMCP objects for every tool call, resource read
|
|
18
|
+
and prompt render. Accepts an `AsyncContainer` for async handlers or a
|
|
19
|
+
`Container` for sync handlers; `@inject` owns the REQUEST scope.
|
|
20
|
+
- `@inject` — resolves `FromDishka[...]` parameters and strips them from the
|
|
21
|
+
signature, so they never leak into the tool schema. Auto-detects sync vs async
|
|
22
|
+
handlers. Must be placed below the FastMCP decorator.
|
|
23
|
+
- `FastMCPProvider` — exposes the current request's FastMCP objects to
|
|
24
|
+
dependencies via `from_context`: the `Context`, the `FastMCP` server, and the
|
|
25
|
+
raw request params (`CallToolRequestParams`, `ReadResourceRequestParams`,
|
|
26
|
+
`GetPromptRequestParams`).
|
|
27
|
+
- `dishka_lifespan(container)` — builds a FastMCP lifespan that closes the root
|
|
28
|
+
container on shutdown, finalizing every `Scope.APP` provider. Works with async
|
|
29
|
+
and sync containers.
|
|
30
|
+
- `FromDishka` re-exported for a single import site.
|
|
31
|
+
- Full typing surface (`py.typed`), checked by mypy and pyright in strict mode.
|
|
32
|
+
|
|
33
|
+
### Notes
|
|
34
|
+
|
|
35
|
+
- Only `Scope.APP` and `Scope.REQUEST` are supported. FastMCP has no
|
|
36
|
+
session-teardown hook, so a `Scope.SESSION` container could not be finalized
|
|
37
|
+
deterministically; it is deliberately omitted rather than shipped as a scope
|
|
38
|
+
that silently behaves like `REQUEST`.
|
|
39
|
+
- The REQUEST scope is entered and finalized by `@inject`, inside the thread that
|
|
40
|
+
runs the handler. FastMCP executes sync tools in a worker thread, so a scope
|
|
41
|
+
managed on the event loop would create a thread-affine dependency (such as a
|
|
42
|
+
`sqlite3` connection) in the worker and finalize it on the loop, raising on
|
|
43
|
+
cleanup. Sync handlers therefore create, use and release their REQUEST-scoped
|
|
44
|
+
dependencies in one thread.
|
|
45
|
+
- APP-scoped dependencies in a sync container must be thread-safe and have
|
|
46
|
+
thread-independent cleanup because FastMCP may run handlers on different worker
|
|
47
|
+
threads and the root container is closed from the server lifespan. Thread-affine
|
|
48
|
+
resources belong in `Scope.REQUEST`.
|
|
49
|
+
- Handlers registered with FastMCP's `task=True` are not supported: they run after
|
|
50
|
+
the request has finished, so no container is in scope for them.
|
|
51
|
+
|
|
52
|
+
[Unreleased]: https://github.com/bagowix/dishka-fastmcp/compare/v1.0.0...HEAD
|
|
53
|
+
[1.0.0]: https://github.com/bagowix/dishka-fastmcp/releases/tag/v1.0.0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment include:
|
|
18
|
+
|
|
19
|
+
- Demonstrating empathy and kindness toward other people
|
|
20
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
21
|
+
- Giving and gracefully accepting constructive feedback
|
|
22
|
+
- Accepting responsibility and apologizing to those affected by our mistakes,
|
|
23
|
+
and learning from the experience
|
|
24
|
+
- Focusing on what is best for the overall community
|
|
25
|
+
|
|
26
|
+
Examples of unacceptable behavior include:
|
|
27
|
+
|
|
28
|
+
- The use of sexualized language or imagery, and sexual attention or advances of
|
|
29
|
+
any kind
|
|
30
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
31
|
+
- Public or private harassment
|
|
32
|
+
- Publishing others' private information, such as a physical or email address,
|
|
33
|
+
without their explicit permission
|
|
34
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
35
|
+
professional setting
|
|
36
|
+
|
|
37
|
+
## Enforcement Responsibilities
|
|
38
|
+
|
|
39
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
40
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
41
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
42
|
+
or harmful.
|
|
43
|
+
|
|
44
|
+
## Scope
|
|
45
|
+
|
|
46
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
47
|
+
an individual is officially representing the community in public spaces.
|
|
48
|
+
|
|
49
|
+
## Enforcement
|
|
50
|
+
|
|
51
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
52
|
+
reported to the community leaders responsible for enforcement at
|
|
53
|
+
**galushko355@gmail.com**. All complaints will be reviewed and investigated
|
|
54
|
+
promptly and fairly.
|
|
55
|
+
|
|
56
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
57
|
+
reporter of any incident.
|
|
58
|
+
|
|
59
|
+
## Attribution
|
|
60
|
+
|
|
61
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
62
|
+
version 2.1, available at
|
|
63
|
+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>.
|
|
64
|
+
|
|
65
|
+
[homepage]: https://www.contributor-covenant.org
|