Skip to main content
Glama

chesscom-mxcp

chess_client.cpython-311.pyc13.3 kB
� W]h$����UdZddlZddlZddlZddlmZmZddlmZmZm Z m Z m Z ddl Z ddl mZmZmZmZddlZeje��Zdae e jed<dae ded<Gd �d��Zed ���Zd �Zed ���Z ddede ede ede de eeefeff d�Z!dede eeeffd�Z"dededeeefdefd�Z#dedefd�Z$dS)zD Chess.com API client with caching, rate limiting, and retry logic. �N��datetime� timedelta)�Any�Dict�List�Optional�Union)�db�config�on_init� on_shutdown� http_client� RateLimiter� rate_limiterc�*�eZdZdZd dedefd�Zd�ZdS) rz(Token bucket rate limiter for API calls.�<� �requests_per_minute� burst_sizec��||_||_||_tj��|_t j��|_dS)N)rr�tokens�time� last_refill�asyncio�Lock�lock)�selfrrs �,/home/yori/chess-mxcp/python/chess_client.py�__init__zRateLimiter.__init__s7��#6�� �$��� �� ��9�;�;����L�N�N�� � � �c��K�|j4�d{V��tj��}||jz }||jdz z}t |j|j|z��|_||_|jdkr6d|jz |jdz z }tj|���d{V��d|_|xjdzc_ddd���d{V��dS#1�d{V��swxYwYdS)z*Acquire a token for making an API request.Nr�) rrrr�minrrr�sleep)r�now�elapsed� tokens_to_add� wait_times r�acquirezRateLimiter.acquirest�����9� � � � � � � � ��)�+�+�C��D�,�,�G�#�t�'?�"�'D�E�M��d�o�t�{�]�/J�K�K�D�K�"�D� ��{�Q������_��1I�B�1N�O� ��m�I�.�.�.�.�.�.�.�.�.��� � �K�K�1� �K�K� � � � � � � � � � � � � � � � � � � � � � � � ���� � � � � � s�B%C� C�CN)rr)�__name__� __module__� __qualname__�__doc__�intr r*�r!rrrsP������2�2�#�#�C�#�#�#�#�#�#�����r!c��ddl}ddl}|j�d|j�|j�t ������ddlm}tj tj d��tj dd���dd i� ��a |� d i��}t|� d d ��|� dd�����at �d��dS)z3Initialize HTTP client and rate limiter on startup.rN�� API_CONFIGg>@r�)�max_keepalive_connections�max_connectionsz User-AgentzMXCP-Chess/1.0)�timeout�limits�headers� rate_limitrrr)rrzBChess client initialized with connection pooling and rate limiting)�sys�os�path�insert�dirname�__file__� chess_configr3�httpx� AsyncClient�Timeout�Limitsr�getrr�logger�info)r;r<r3r:s r�initialize_clientrI2s�� �J�J�J� �I�I�I��H�O�O�A�r�w���r�w���x�'@�'@�A�A�B�B�B�'�'�'�'�'�'��#�� �d�#�#��|�b�"�M�M�M��/�0����K���� �b�1�1�J��&�N�N�+@�"�E�E��>�>�,��3�3����L�  �K�K�T�U�U�U�U�Ur!c��� tjd��tjd��d S#t$r�t�d��tjd��tjd�� tjd��tjd��tjd��Yd S#t$r)}t�d |����Yd }~Yd Sd }~wwxYwwxYw) z6Ensure cache tables exist, creating them if necessary.z%SELECT 1 FROM chess_api_cache LIMIT 1z'SELECT 1 FROM chess_games_cache LIMIT 1zCreating chess cache tablesa3 CREATE TABLE IF NOT EXISTS chess_api_cache ( cache_key VARCHAR PRIMARY KEY, endpoint VARCHAR NOT NULL, response_data JSON NOT NULL, cached_at TIMESTAMP NOT NULL, expires_at TIMESTAMP NOT NULL ) a\ CREATE TABLE IF NOT EXISTS chess_games_cache ( game_id VARCHAR PRIMARY KEY, username VARCHAR NOT NULL, game_data JSON NOT NULL, pgn_data TEXT, cached_at TIMESTAMP NOT NULL, year INTEGER, month INTEGER ) zECREATE INDEX IF NOT EXISTS idx_expires ON chess_api_cache(expires_at)zVCREATE INDEX IF NOT EXISTS idx_player_date ON chess_games_cache(username, year, month)zECREATE INDEX IF NOT EXISTS idx_cached ON chess_games_cache(cached_at)zIndex creation warning: N)r �execute� ExceptionrGrH�debug)�es r�ensure_tables_existrOMs!��#9� � �:�;�;�;� � �<�=�=�=�=�=�� �9�9�9�� � �1�2�2�2� � � � � � � � �  � � � � 9� �J�^� _� _� _� �J�o� p� p� p� �J�^� _� _� _� _� _� _��� 9� 9� 9� �L�L�7�A�7�7� 8� 8� 8� 8� 8� 8� 8� 8� 8� 8����� 9����=9���s.�(,�A C/�9<B8�8 C+�C&�C/�&C+�+C/c��K�tr;t����d{V��t�d��dSdS)zClean up resources on shutdown.NzHTTP client closed)r�acloserGrHr0r!r�cleanup_clientrRusW�����*�� � �"�"�"�"�"�"�"�"�"�� � �(�)�)�)�)�)�*�*r!T�endpoint� cache_key� cache_ttl� accept_json�returnc ��K�t�t�t��|s|}|r2|�0t|��}|rt�d|����|Sddl}ddl}|j� d|j� |j� t������ddl m }|�dd��}|�dd��} |�d d ��} |�d |��} d |rd ndi} t����d{V��d} t!| ��D�]} t�| | ����d{V��}|��� t%��t'jd||jd���n4#t,$r'}t�d|����Yd}~nd}~wwxYw|r,|���}|�t1||||��|cS|jcS#t4j$r�}|} |jjdkr;t�d��t=j| |dzz���d{V��nZ|jjdkrIt�d|jj�d���t=j| |dzz���d{V��n�Yd}~���d}~wt,$rf}|} t� d|dz�dtC|������|| dz kr t=j| |dzz���d{V��Yd}~���d}~wwxYwt-d| �dtC| �������)a� Make a request to the Chess.com API with caching and retry logic. Args: endpoint: API endpoint path (without base URL) cache_key: Optional cache key (defaults to endpoint) cache_ttl: Cache TTL in seconds (defaults from config) accept_json: Whether to request JSON response (False for PGN) Returns: API response data (dict for JSON, str for PGN) NzCache hit for rr2�base_urlzhttps://api.chess.com/pub�retry_attempts�� retry_delayg�?�/�Acceptzapplication/jsonzapplication/x-chess-pgn)r9z� INSERT INTO audit_log (timestamp, event_type, endpoint, status_code, username) VALUES (CURRENT_TIMESTAMP, 'api_call', $endpoint, $status, NULL) )rS�statuszCould not log to audit: i�z-Rate limited by Chess.com API, waiting longer�i�z Server error z , retrying...r#zRequest error on attempt z: zAPI request failed after z attempts: )"rrrI�get_from_cacherGrMr;r<r=r>r?r@rAr3rFr*�range�raise_for_statusrOr rK� status_coderL�json�cache_response�textrB�HTTPStatusError�response�warningrr%�error�str)rSrTrUrV�cachedr;r<r3rYrZr\�urlr9� last_error�attemptrirN�datas r�make_api_requestrr~s����(��l�2����� ��� ���y�,�� �*�*�� � � �L�L�5�)�5�5� 6� 6� 6��M��J�J�J� �I�I�I��H�O�O�A�r�w���r�w���x�'@�'@�A�A�B�B�B�'�'�'�'�'�'��~�~�j�*E�F�F�H��^�^�$4�a�8�8�N��.�.���4�4�K� � "� "�� "� "�C�� �R�$�$�9R��G� � � � � � � � � � � � ��J���(�(�(A�(A��' A�(�_�_�S�'�_�B�B�B�B�B�B�B�B�H� � %� %� '� '� '� =�#�%�%�%�� ��#+�h�6J�K�K�M�M�M�M��� =� =� =�� � �;��;�;�<�<�<�<�<�<�<�<����� =����� %��}�}�����(�"�9�h��i�H�H�H�� � � ��}�$�$�$���$� � � ��J��z�%��,�,����O�P�P�P��m�K�7�Q�;�$?�@�@�@�@�@�@�@�@�@�@���'�3�.�.����T�q�z�/E�T�T�T�U�U�U��m�K�7�Q�;�$?�@�@�@�@�@�@�@�@�@�@������������ A� A� A��J� �L�L�L�W�q�[�L�L�C��F�F�L�L� M� M� M���!�+�+�+��m�K�7�Q�;�$?�@�@�@�@�@�@�@�@�@����������  A���� �\��\�\�3�z�?�?�\�\� ]� ]�]sV�:6H�1+F�H� G�'G �H� G�.H�?H�L7�B'K� L7�AL2�2L7c�p�t��tjdd|i��}|r|ddSdS)z#Get data from cache if not expired.z� SELECT response_data FROM chess_api_cache WHERE cache_key = $key AND expires_at > CURRENT_TIMESTAMP �keyr� response_dataN)rOr rK)rT�results rrara�sL������ �Z�� �� � ��F��*��a�y��)�)� �4r!rq�ttlc ��ddlm}m}t��|j��}|||���z}t jd|||||d���dS)zCache API response with TTL.rr)�secondsz� INSERT OR REPLACE INTO chess_api_cache (cache_key, endpoint, response_data, cached_at, expires_at) VALUES ($key, $endpoint, $data, $now, $expires) )rtrSrqr&�expiresN)rrrOr&r rK)rTrSrqrwrrr&rzs rrfrf�s���,�,�,�,�,�,�,�,����� �(�,�.�.�C��I�I�c�*�*�*�*�G��J�� �����  � � � � � � r!� cache_typec���ddl}ddl}|j�d|j�|j�t ������ddlm}|�|d��S)z4Get cache TTL from config for a specific cache type.rN)� CACHE_TTLi) r;r<r=r>r?r@rAr}rF)r{r;r<r}s r� get_cache_ttlr~sl���J�J�J� �I�I�I��H�O�O�A�r�w���r�w���x�'@�'@�A�A�B�B�B�&�&�&�&�&�&� �=�=��T� *� *�*r!)NNT)%r.rrerrr�typingrrrr r rB� mxcp.runtimer r r r�logging� getLoggerr+rGrrC�__annotations__rrrIrOrRrlr/�boolrrrarfr~r0r!r�<module>r�so��������� � � � � � � � �(�(�(�(�(�(�(�(�3�3�3�3�3�3�3�3�3�3�3�3�3�3� � � � �9�9�9�9�9�9�9�9�9�9�9�9����� �� �8� $� $��,0� �X�e�'� (�/�/�/�(,� �h�}�%�,�,�,���������< �V�V� ��V�4%9�%9�%9�P �*�*� ��*� $�#�� `^�`^��`^���}�`^���}�`^�� `^�  �4��S��>�3� �� `^�`^�`^�`^�F �c� �h�t�C��H�~�&>� � � � ��c��S���S�#�X���S�����*+�c�+�c�+�+�+�+�+�+r!

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/datYori/chesscom-mxcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server