Skip to content

EvoSpikeNet SDK Developer Guide

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

  1. Defining the endpoint URL
class EvoSpikeNetAPIClient:
    def __init__(self, ...):
        # existing initialization
        self.new_endpoint_url = f"{self.base_url}/api/new_endpoint"
  1. 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))
  1. 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

  1. 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 ```

  1. Test failed```bash # Detailed test output pytest -v -s

# Run only specific tests pytest tests/unit/test_sdk.py::TestEvoSpikeNetAPIClient::test_generate_success ```

  1. Type checking errorbash # 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

  1. PEP 8 Compliant: Uses Black and isort
  2. Type hints: Add type hints to all methods
  3. Documentation: docstring is Google style
  4. Tests: Add tests for new features
  5. 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. /Users/maoki/Documents/GitHub/EvoSpikeNet/docs/SDK_DEVELOPER_GUIDE.md