sefia-litellm 0.1.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.
@@ -0,0 +1,175 @@
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
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py.cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ # .python-version
85
+
86
+ # pipenv
87
+ #Pipfile.lock
88
+
89
+ # UV
90
+ #uv.lock
91
+
92
+ # poetry
93
+ #poetry.lock
94
+ #poetry.toml
95
+
96
+ # pdm
97
+ #pdm.lock
98
+ #pdm.toml
99
+ .pdm-python
100
+ .pdm-build/
101
+
102
+ # pixi
103
+ #pixi.lock
104
+ .pixi
105
+
106
+ # PEP 582
107
+ __pypackages__/
108
+
109
+ # Celery stuff
110
+ celerybeat-schedule
111
+ celerybeat.pid
112
+
113
+ # SageMath parsed files
114
+ *.sage.py
115
+
116
+ # Environments
117
+ .env
118
+ .envrc
119
+ .venv
120
+ env/
121
+ venv/
122
+ ENV/
123
+ env.bak/
124
+ venv.bak/
125
+
126
+ # Spyder project settings
127
+ .spyderproject
128
+ .spyproject
129
+
130
+ # Rope project settings
131
+ .ropeproject
132
+
133
+ # mkdocs documentation
134
+ /site
135
+
136
+ # mypy
137
+ .mypy_cache/
138
+ .dmypy.json
139
+ dmypy.json
140
+
141
+ # Pyre type checker
142
+ .pyre/
143
+
144
+ # pytype static type analyzer
145
+ .pytype/
146
+
147
+ # Cython debug symbols
148
+ cython_debug/
149
+
150
+ # PyCharm
151
+ #.idea/
152
+
153
+ # Abstra
154
+ .abstra/
155
+
156
+ # Visual Studio Code
157
+ # .vscode/
158
+
159
+ # Ruff stuff:
160
+ .ruff_cache/
161
+
162
+ # PyPI configuration file
163
+ .pypirc
164
+
165
+ # Cursor
166
+ .cursorignore
167
+ .cursorindexingignore
168
+
169
+ # Marimo
170
+ marimo/_static/
171
+ marimo/_lsp/
172
+ __marimo__/
173
+
174
+ /out/
175
+ /.local/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nueruyu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: sefia-litellm
3
+ Version: 0.1.0
4
+ Summary: LiteLLM adapter for Sefia.
5
+ Project-URL: Homepage, https://github.com/nueruyu/sefia
6
+ Project-URL: Repository, https://github.com/nueruyu/sefia
7
+ Project-URL: Issues, https://github.com/nueruyu/sefia/issues
8
+ Project-URL: Documentation, https://github.com/nueruyu/sefia/tree/main/docs
9
+ Author: nueruyu
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 nueruyu
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: inference,litellm,llm,sefia
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Framework :: AsyncIO
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.11
45
+ Requires-Dist: litellm>=1.63.0
46
+ Requires-Dist: sefia>=0.1.0
47
+ Description-Content-Type: text/markdown
48
+
49
+ # sefia-litellm
50
+
51
+ A [`sefia`](https://pypi.org/project/sefia/) `LLMClient` implementation that
52
+ connects to various LLM providers via
53
+ [LiteLLM](https://github.com/BerriAI/litellm).
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install sefia-litellm
59
+ ```
60
+
61
+ Or through the stack: `pip install 'sefios[litellm]'`.
62
+
63
+ ## Usage
64
+
65
+ ```python
66
+ import sefia_litellm
67
+
68
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o")
69
+ ```
70
+
71
+ ## Suppressing LiteLLM logging
72
+
73
+ LiteLLM logs through the standard-library `LiteLLM` logger — mostly INFO-level
74
+ messages that become visible whenever your application configures logging at
75
+ INFO/DEBUG — and, when a request raises, prints debug info including a
76
+ `Provider List: ...` banner. `LiteLLMClient` **silences all of this by default**.
77
+
78
+ Real failures still surface: LiteLLM raises exceptions on errors (which this
79
+ client maps to `sefia` exceptions), so silencing the logs never hides a failure.
80
+
81
+ There are two ways to control this:
82
+
83
+ - **Constructor argument** `suppress_logs` (takes precedence)
84
+
85
+ ```python
86
+ # Suppress logs (default)
87
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o")
88
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o", suppress_logs=True)
89
+
90
+ # Let LiteLLM log as usual
91
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o", suppress_logs=False)
92
+ ```
93
+
94
+ - **Environment variable** `SEFIA_LITELLM_SUPPRESS_LOGS` (used as the default when
95
+ `suppress_logs` is `None`)
96
+
97
+ ```bash
98
+ # Disable suppression (let logs through). 0/false/no/off disable it.
99
+ export SEFIA_LITELLM_SUPPRESS_LOGS=false
100
+ ```
101
+
102
+ An explicit `suppress_logs` argument overrides the environment variable. When
103
+ unset, suppression is on.
104
+
105
+ When suppression is on, the `LiteLLM` logger is fully silenced (its level is set
106
+ above `CRITICAL`) and `litellm.suppress_debug_info` is set to `True`. The logger
107
+ level is applied as soon as `sefia_litellm` is imported — before LiteLLM itself is
108
+ imported — so even LiteLLM's import-time warnings (e.g. optional-dependency
109
+ preload warnings) are suppressed.
110
+
111
+ ## On slow imports
112
+
113
+ Importing LiteLLM is heavy and can take around a second
114
+ (see [BerriAI/litellm#7605](https://github.com/BerriAI/litellm/issues/7605)).
115
+
116
+ This package mitigates that as follows:
117
+
118
+ 1. **Lazy import** — LiteLLM is imported only inside the methods that actually
119
+ send a request. Importing `sefia_litellm` alone costs nothing. After the first
120
+ request the module is cached in `sys.modules`, so subsequent imports are
121
+ effectively free. This is the primary mitigation.
122
+
123
+ 2. **Local model cost map** — `LITELLM_LOCAL_MODEL_COST_MAP=True` is set before
124
+ LiteLLM is imported so that it uses its bundled cost map JSON instead of
125
+ fetching it over the network. This speeds up the import and keeps it working
126
+ offline.
127
+
128
+ If you need up-to-date pricing for the newest models and the bundled map is
129
+ stale, you can restore the original behavior:
130
+
131
+ ```bash
132
+ export LITELLM_LOCAL_MODEL_COST_MAP=False
133
+ ```
134
+
135
+ 3. **(Optional) Warm up at startup** — if you also want to hide the first
136
+ request's latency, import LiteLLM in the background during application startup.
137
+ A daemon thread works regardless of whether an asyncio event loop is running
138
+ yet:
139
+
140
+ ```python
141
+ import threading
142
+
143
+ threading.Thread(target=__import__, args=("litellm",), daemon=True).start()
144
+ ```
145
+
146
+ ## Status
147
+
148
+ Early development. APIs may change before v1.0.
149
+
150
+ ## License
151
+
152
+ MIT
@@ -0,0 +1,104 @@
1
+ # sefia-litellm
2
+
3
+ A [`sefia`](https://pypi.org/project/sefia/) `LLMClient` implementation that
4
+ connects to various LLM providers via
5
+ [LiteLLM](https://github.com/BerriAI/litellm).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install sefia-litellm
11
+ ```
12
+
13
+ Or through the stack: `pip install 'sefios[litellm]'`.
14
+
15
+ ## Usage
16
+
17
+ ```python
18
+ import sefia_litellm
19
+
20
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o")
21
+ ```
22
+
23
+ ## Suppressing LiteLLM logging
24
+
25
+ LiteLLM logs through the standard-library `LiteLLM` logger — mostly INFO-level
26
+ messages that become visible whenever your application configures logging at
27
+ INFO/DEBUG — and, when a request raises, prints debug info including a
28
+ `Provider List: ...` banner. `LiteLLMClient` **silences all of this by default**.
29
+
30
+ Real failures still surface: LiteLLM raises exceptions on errors (which this
31
+ client maps to `sefia` exceptions), so silencing the logs never hides a failure.
32
+
33
+ There are two ways to control this:
34
+
35
+ - **Constructor argument** `suppress_logs` (takes precedence)
36
+
37
+ ```python
38
+ # Suppress logs (default)
39
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o")
40
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o", suppress_logs=True)
41
+
42
+ # Let LiteLLM log as usual
43
+ client = sefia_litellm.LiteLLMClient(model="gpt-4o", suppress_logs=False)
44
+ ```
45
+
46
+ - **Environment variable** `SEFIA_LITELLM_SUPPRESS_LOGS` (used as the default when
47
+ `suppress_logs` is `None`)
48
+
49
+ ```bash
50
+ # Disable suppression (let logs through). 0/false/no/off disable it.
51
+ export SEFIA_LITELLM_SUPPRESS_LOGS=false
52
+ ```
53
+
54
+ An explicit `suppress_logs` argument overrides the environment variable. When
55
+ unset, suppression is on.
56
+
57
+ When suppression is on, the `LiteLLM` logger is fully silenced (its level is set
58
+ above `CRITICAL`) and `litellm.suppress_debug_info` is set to `True`. The logger
59
+ level is applied as soon as `sefia_litellm` is imported — before LiteLLM itself is
60
+ imported — so even LiteLLM's import-time warnings (e.g. optional-dependency
61
+ preload warnings) are suppressed.
62
+
63
+ ## On slow imports
64
+
65
+ Importing LiteLLM is heavy and can take around a second
66
+ (see [BerriAI/litellm#7605](https://github.com/BerriAI/litellm/issues/7605)).
67
+
68
+ This package mitigates that as follows:
69
+
70
+ 1. **Lazy import** — LiteLLM is imported only inside the methods that actually
71
+ send a request. Importing `sefia_litellm` alone costs nothing. After the first
72
+ request the module is cached in `sys.modules`, so subsequent imports are
73
+ effectively free. This is the primary mitigation.
74
+
75
+ 2. **Local model cost map** — `LITELLM_LOCAL_MODEL_COST_MAP=True` is set before
76
+ LiteLLM is imported so that it uses its bundled cost map JSON instead of
77
+ fetching it over the network. This speeds up the import and keeps it working
78
+ offline.
79
+
80
+ If you need up-to-date pricing for the newest models and the bundled map is
81
+ stale, you can restore the original behavior:
82
+
83
+ ```bash
84
+ export LITELLM_LOCAL_MODEL_COST_MAP=False
85
+ ```
86
+
87
+ 3. **(Optional) Warm up at startup** — if you also want to hide the first
88
+ request's latency, import LiteLLM in the background during application startup.
89
+ A daemon thread works regardless of whether an asyncio event loop is running
90
+ yet:
91
+
92
+ ```python
93
+ import threading
94
+
95
+ threading.Thread(target=__import__, args=("litellm",), daemon=True).start()
96
+ ```
97
+
98
+ ## Status
99
+
100
+ Early development. APIs may change before v1.0.
101
+
102
+ ## License
103
+
104
+ MIT
@@ -0,0 +1,68 @@
1
+ [project]
2
+ name = "sefia-litellm"
3
+ description = "LiteLLM adapter for Sefia."
4
+ readme = "README.md"
5
+ license = { file = "LICENSE" }
6
+ authors = [{ name = "nueruyu" }]
7
+ requires-python = ">=3.11"
8
+ dependencies = [
9
+ "sefia>=0.1.0",
10
+ # 1.63.0 is the first release exposing reasoning_content / thinking blocks,
11
+ # which the adapter reads and streams; older versions install fine but would
12
+ # silently drop reasoning.
13
+ "litellm>=1.63.0",
14
+ ]
15
+ dynamic = ["version"]
16
+ keywords = [
17
+ "llm",
18
+ "litellm",
19
+ "inference",
20
+ "sefia",
21
+ ]
22
+ classifiers = [
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Independent",
29
+ "Development Status :: 3 - Alpha",
30
+ "Framework :: AsyncIO",
31
+ "Intended Audience :: Developers",
32
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
33
+ "Typing :: Typed",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/nueruyu/sefia"
38
+ Repository = "https://github.com/nueruyu/sefia"
39
+ Issues = "https://github.com/nueruyu/sefia/issues"
40
+ Documentation = "https://github.com/nueruyu/sefia/tree/main/docs"
41
+
42
+ [build-system]
43
+ requires = ["hatchling", "hatch-vcs"]
44
+ build-backend = "hatchling.build"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/sefia_litellm"]
48
+
49
+ [tool.hatch.version]
50
+ source = "vcs"
51
+ raw-options = { root = "../.." }
52
+
53
+ # Mirrors the root pyproject's pytest options so `uv run pytest
54
+ # packages/sefia_litellm` (which resolves this file as the config) behaves the
55
+ # same: e2e tests stay opt-in via `-m e2e`.
56
+ [tool.pytest.ini_options]
57
+ addopts = ["-m", "not e2e"]
58
+ asyncio_mode = "auto"
59
+ testpaths = ["tests"]
60
+ markers = [
61
+ "e2e: live LLM provider tests (need API keys; run with `pytest -m e2e`)",
62
+ ]
63
+
64
+ [tool.uv.sources]
65
+ sefia = { workspace = true }
66
+
67
+ [dependency-groups]
68
+ dev = ["pytest>=8.0", "pytest-asyncio>=0.23", "pytest-mock>=3.12.0"]
@@ -0,0 +1,3 @@
1
+ from ._client import LiteLLMClient
2
+
3
+ __all__ = ["LiteLLMClient"]