EvoSpikeNet SDK Developer Guide
Copyright: 2026 Moonlight Technologies Inc.
Author: Masahiro Aoki
Last updated: January 15, 2026
overview
This developer guide describes the internals of the EvoSpikeNet SDK, how to extend it, and best practices. Intended for developers involved in SDK development, testing, and deployment.
SDK architecture
Main components
evospikenet/
├── sdk.py # Main API client
├── sdk_jupyter.py # Jupyter Notebook integration
├── __init__.py # Package initialization
└── ...
Class hierarchy
EvoSpikeNetAPIClient (メインクライアント)
├── 基本HTTP機能
├── エラーハンドリング
├── 統計収集
└── 拡張機能
JupyterAPIClient (Jupyter統合)
├── EvoSpikeNetAPIClient (継承)
├── HTML表示機能
├── インタラクティブ機能
└── マジックコマンド
WebSocketClient (リアルタイム通信)
├── 接続管理
├── メッセージ送受信
└── イベントハンドリング
Setting up the development environment
Required tools
# Python development environment
pip install -e ".[dev]"
# test dependencies
pip install pytest pytest-cov pytest-asyncio
# Document generation
pip install sphinx sphinx-rtd-theme
# code quality
pip install black isort flake8 mypy
Development Workflow
# code format
black evospikenet/
isort evospikenet/
# type check
mypy evospikenet/
# lint
flake8 evospikenet/
# test run
pytest
# coverage report
pytest --cov=evospikenet --cov-report=html
SDK extension guidelines
Adding a new API endpoint
- Defining the endpoint URL
class EvoSpikeNetAPIClient:
def __init__(self, ...):
# existing initialization
self.new_endpoint_url = f"{self.base_url}/api/new_endpoint"
- Method implementation
def new_api_method(self, param1: str, param2: int = 10) -> Dict[str, Any]:
"""
新しいAPIメソッドの説明。
Args:
param1: パラメータ1の説明
param2: パラメータ2の説明(デフォルト値付き)
Returns:
APIレスポンスの辞書
Raises:
EvoSpikeNetAPIError: APIエラーの場合
"""
payload = {
"param1": param1,
"param2": param2
}
return cast(Dict[str, Any], self._make_request("post", self.new_endpoint_url, json=payload))
- Using type hints
from typing import Dict, Any, Optional, List, Union
def method_with_complex_types(
self,
required_param: str,
optional_param: Optional[int] = None,
list_param: List[str] = None,
union_param: Union[str, int] = "default"
) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
# implementation
pass
Error handling enhancements
class CustomAPIError(EvoSpikeNetAPIError):
"""カスタムAPIエラークラス"""
def __init__(self, error_info: ErrorInfo, custom_field: str = None):
super().__init__(error_info)
self.custom_field = custom_field
# Usage example
try:
result = client.new_method()
except CustomAPIError as e:
print(f"Custom error: {e.custom_field}")
# special treatment
Adding an async method
import aiohttp
async def new_async_method(self, param: str) -> Dict[str, Any]:
"""
非同期バージョンの新しいメソッド。
Args:
param: メソッドパラメータ
Returns:
非同期レスポンス
"""
payload = {"param": param}
async with aiohttp.ClientSession() as session:
async with session.post(
self.new_endpoint_url,
json=payload,
headers=self.session.headers,
timeout=aiohttp.ClientTimeout(total=self.timeout)
) as response:
response.raise_for_status()
return await response.json()
Testing strategy
Test structure
tests/
├── unit/ # unit test
│ ├── test_sdk.py
│ └── test_jupyter.py
├── integration/ # integration testing
│ └── test_api_integration.py
├── fixtures/ # test fixture
└── conftest.py # pytest settings
Unit test example
import pytest
from unittest.mock import Mock, patch
<!-- from evospikenet.sdk import EvoSpikeNetAPIClient, EvoSpikeNetAPIError -->
class TestEvoSpikeNetAPIClient:
"""EvoSpikeNetAPIClientのテストクラス"""
@pytest.fixture
def client(self):
"""テスト用クライアントフィクスチャ"""
return EvoSpikeNetAPIClient(base_url="http://test-server")
@patch('requests.Session.request')
def test_generate_success(self, mock_request, client):
"""正常系のテキスト生成テスト"""
# Mock response settings
mock_response = Mock()
mock_response.json.return_value = {
"generated_text": "Test response",
"prompt": "Test prompt"
}
mock_request.return_value = mock_response
# test run
result = client.generate("Test prompt")
# assertion
assert result["generated_text"] == "Test response"
assert result["prompt"] == "Test prompt"
mock_request.assert_called_once()
@patch('requests.Session.request')
def test_generate_http_error(self, mock_request, client):
"""HTTPエラーのテスト"""
# Error response settings
mock_response = Mock()
mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError("404 Not Found")
mock_response.status_code = 404
mock_response.json.return_value = {"detail": "Not found"}
mock_request.return_value = mock_response
# Test execution and exception checking
with pytest.raises(EvoSpikeNetAPIError) as exc_info:
client.generate("Test prompt")
assert exc_info.value.error_info.status_code == 404
assert "Not found" in exc_info.value.error_info.message
def test_stats_tracking(self, client):
"""統計追跡のテスト"""
# Initial status confirmation
stats = client.get_stats()
assert stats["requests"] == 0
# statistics reset
client.reset_stats()
stats = client.get_stats()
assert stats["requests"] == 0
Integration test example
import pytest
<!-- TODO: update or remove - import fail<!-- Remember: Automatic conversion not possible — please fix manually -->eNetAPIClient -->
class TestAPIIntegration:
"""API統合テスト"""
@pytest.fixture(scope="class")
def live_client(self):
"""ライブAPIサーバー接続用フィクスチャ"""
client = EvoSpikeNetAPIClient()
# Check if server is available
if not client.wait_for_server(timeout=10):
pytest.skip("API server not available")
return client
def test_health_check_integration(self, live_client):
"""ヘルスチェックの統合テスト"""
health = live_client.health_check()
assert "status" in health
assert health["status"] in ["healthy", "unhealthy"]
def test_generate_integration(self, live_client):
"""テキスト生成の統合テスト"""
prompt = "Hello, world!"
result = live_client.generate(prompt, max_length=50)
assert "generated_text" in result
assert isinstance(result["generated_text"], str)
assert len(result["generated_text"]) > 0
def test_batch_generate_integration(self, live_client):
"""バッチ生成の統合テスト"""
prompts = ["Test 1", "Test 2", "Test 3"]
results = live_client.batch_generate(prompts, max_length=30)
assert len(results) == len(prompts)
for result in results:
if "generated_text" in result:
assert isinstance(result["generated_text"], str)
Asynchronous test example
import pytest
import asyncio
from unittest.mock import AsyncMock, patch
<!-- Module 'evospikenet' not found. Check moves/renames within the package -->
<!-<!-- Remember: Cannot convert automatically — please fix manually -->ions:
"""非同期操作のテスト"""
@pytest.fixture
def client(self):
return EvoSpikeNetAPIClient()
@pytest.mark.asyncio
@patch('aiohttp.ClientSession.post')
async def test_generate_async_success(self, mock_post, client):
"""非同期生成の成功テスト"""
# Mock response settings
mock_response = AsyncMock()
mock_response.json.return_value = {"generated_text": "Async response"}
mock_response.raise_for_status.return_value = None
mock_post.return_value.__aenter__.return_value = mock_response
# test run
result = await client.generate_async("Test prompt")
# assertion
assert result["generated_text"] == "Async response"
@pytest.mark.asyncio
async def test_concurrent_generation(self, client):
"""並行生成のテスト"""
prompts = ["Prompt 1", "Prompt 2", "Prompt 3"]
# Timeout settings when calling the actual API
with pytest.raises(asyncio.TimeoutError):
await asyncio.wait_for(
asyncio.gather(*[client.generate_async(p) for p in prompts]),
timeout=1.0 # Test with short timeout
)
Performance optimization
Connection pooling
# Session reuse
class EvoSpikeNetAPIClient:
def __init__(self, ...):
self.session = requests.Session()
# Connection pooling settings
adapter = requests.adapters.HTTPAdapter(
pool_connections=10,
pool_maxsize=20,
max_retries=3
)
self.session.mount('http://', adapter)
self.session.mount('https://', adapter)
Response cache
from functools import lru_cache
import hashlib
class EvoSpikeNetAPIClient:
def __init__(self, ...):
self.cache = {}
def _get_cache_key(self, method: str, url: str, **kwargs) -> str:
"""キャッシュキーの生成"""
key_data = f"{method}:{url}:{str(sorted(kwargs.items()))}"
return hashlib.md5(key_data.encode()).hexdigest()
@lru_cache(maxsize=100)
def _cached_request(self, cache_key: str, method: str, url: str, **kwargs):
"""キャッシュ付きリクエスト"""
return self._make_request(method, url, **kwargs)
Streaming processing
def download_large_artifact(self, artifact_id: str, destination_path: str):
"""大容量アーティファクトのストリーミングダウンロード"""
url = f"{self.base_url}/api/artifacts/{artifact_id}/download"
with self.session.get(url, stream=True, timeout=300) as response:
response.raise_for_status()
with open(destination_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
Security considerations
API key management
import os
from typing import Optional
class EvoSpikeNetAPIClient:
def __init__(self, api_key: Optional[str] = None, ...):
# Get API key from environment variable
self.api_key = api_key or os.getenv('EVOSPIKENET_API_KEY')
if not self.api_key:
raise ValueError("API key must be provided or set in EVOSPIKENET_API_KEY environment variable")
# header settings
self.session.headers.update({
'X-API-Key': self.api_key,
'User-Agent': 'EvoSpikeNet-SDK/2.0'
})
Certificate validation
import ssl
class EvoSpikeNetAPIClient:
def __init__(self, verify_ssl: bool = True, ca_cert_path: Optional[str] = None, ...):
self.session.verify = verify_ssl
if ca_cert_path:
self.session.verify = ca_cert_path
elif verify_ssl:
# Use system certificate
pass
else:
# show warning
import warnings
warnings.warn("SSL verification is disabled. This is insecure for production use.")
Timeout settings
class EvoSpikeNetAPIClient:
def __init__(self, timeout: int = 60, ...):
self.timeout = timeout
# Timeout settings for different operations
self.timeouts = {
'health': 5,
'generate': timeout,
'upload': 300, # upload is long
'download': 300, # Download is long
}
Document generation
Sphinx documentation
# docs/conf.py
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
]
# API documentation generation
# sphinx-apidoc -f -o docs/source evospikenet
Utilizing type hints
from typing import Dict, Any, Optional, List, Union
def well_documented_method(
self,
required_param: str,
optional_param: Optional[int] = None
) -> Dict[str, Any]:
"""
型ヒント付きのメソッド。
Args:
required_param: 必須パラメータの説明
optional_param: オプションのパラメータ説明
Returns:
戻り値の説明
Raises:
EvoSpikeNetAPIError: エラーの説明
Example:
>>> result = client.well_documented_method("test")
>>> print(result)
{'status': 'success'}
"""
pass
Release process
Version control
# evospikenet/__init__.py
__version__ = "2.0.0"
# Version acquisition method
def get_version() -> str:
"""SDKバージョンを取得"""
return __version__
Release checklist
- [ ] All tests pass
- [ ] Coverage is 80% or more
- [ ] Type check passes
- [ ] Lint passes
- [ ] Documentation has been updated
- [ ] Changelog has been updated
- [ ] Version number has been updated
- [ ] Integration test passes
Packaging
# setup.py
from setuptools import setup, find_packages
setup(
name="evospikenet-sdk",
version="2.0.0",
packages=find_packages(),
install_requires=[
"requests>=2.25.0",
"typing-extensions>=4.0.0",
],
extras_require={
"jupyter": ["ipython", "jupyter"],
"async": ["aiohttp"],
"websocket": ["websockets"],
"all": ["ipython", "jupyter", "aiohttp", "websockets"],
},
python_requires=">=3.8",
)
troubleshooting
Common development issues
- Import error```bash # Check if the path is correct python -c "import sys; print(sys.path)"
# Check if the development installation is correct pip show evospikenet ```
- Test failed```bash # Detailed test output pytest -v -s
# Run only specific tests pytest tests/unit/test_sdk.py::TestEvoSpikeNetAPIClient::test_generate_success ```
- Type checking error
bash # mypy verbose output mypy evospikenet/ --show-error-codes --show-traceback
Diagnosing performance problems
import time
import cProfile
def profile_method():
"""メソッドのパフォーマンスプロファイリング"""
client = EvoSpikeNetAPIClient()
start_time = time.time()
cProfile.runctx('client.generate("Test prompt")', globals(), locals(), 'profile.out')
end_time = time.time()
print(f"Execution time: {end_time - start_time:.3f}s")
# Profile result analysis
import pstats
stats = pstats.Stats('profile.out')
stats.sort_stats('cumulative').print_stats(10)
Contribution Guidelines
Coding Standards
- PEP 8 Compliant: Uses Black and isort
- Type hints: Add type hints to all methods
- Documentation: docstring is Google style
- Tests: Add tests for new features
- Commit: Meaningful commit message
Pull request template
## overview
何を実装/修正したか
## Changes
- 変更1
- 変更2
## test
- [ ] 単体テスト追加
- [ ] 統合テスト確認
- [ ] 手動テスト実施
## Things to check
- [ ] ドキュメント更新
- [ ] 変更履歴更新
- [ ] 後方互換性維持
This guide provides the information you need to proceed with SDK development. If you have any questions, please contact our development team.