Skip to main content
Glama
test_files.py17.2 kB
import pytest import json from main import mcp from test_project import Project from test_compile import Compile from test_project_collaboration import ProjectCollaboration, COLLABORATOR_ID from utils import ( validate_models, ensure_request_raises_validation_error, ensure_request_raises_validation_error_when_omitting_an_arg, ensure_request_fails_when_including_an_invalid_arg ) from models import ( CreateProjectFileRequest, ReadFilesRequest, UpdateFileNameRequest, UpdateFileContentsRequest, DeleteFileRequest, RestResponse, ProjectFilesResponse ) # Static helpers for common operations: class Files: @staticmethod async def create(project_id, name, **kwargs): return await validate_models( mcp, 'create_file', {'projectId': project_id, 'name': name} | kwargs, ProjectFilesResponse ) @staticmethod async def read(project_id, **kwargs): return await validate_models( mcp, 'read_file', {'projectId': project_id} | kwargs, ProjectFilesResponse ) @staticmethod async def update(project_id, **kwargs): tool_name = 'update_file_' if 'content' in kwargs: tool_name += 'contents' output_class = ProjectFilesResponse else: tool_name += 'name' output_class = RestResponse output_model = await validate_models( mcp, tool_name, {'projectId': project_id} | kwargs, output_class ) return output_model @staticmethod async def delete(project_id, name): return await validate_models( mcp, 'delete_file', {'projectId': project_id, 'name': name}, RestResponse ) @staticmethod async def setup_project(language, algorithm=None): # Create a project. project_id = (await Project.create(language=language)).projectId if algorithm: # Read the algorithm file. with open('algorithms/' + algorithm, 'r') as file: content = file.read() # Update the project to the new algorithm. await Files.update( project_id, name='main.py' if language == 'Py' else 'Main.cs', content=content ) # Compile the project. compile_id = (await Compile.create(project_id)).compileId await Compile.wait_for_job_to_complete(project_id, compile_id) return project_id, compile_id # Test suite: class TestFiles: _basic_code_file = { 'Py': """class CustomClass: def __init__(self): pass""", 'C#': """public class CustomClass { CustomClass() { } }""" } _basic_research_file = { 'Py': { 'cells': [ { 'cell_type': 'code', 'execution_count': None, 'metadata': { 'pycharm': { 'name': '#%%\n' } }, 'outputs': [ ], 'source': [ "print('Hello world!')\n", ] } ], 'metadata': { 'kernelspec': { 'display_name': 'Python 3', 'language': 'python', 'name': 'python3' }, 'language_info': { 'codemirror_mode': { 'name': 'ipython', 'version': 3 }, 'file_extension': '.py', 'mimetype': 'text/x-python', 'name': 'python', 'nbconvert_exporter': 'python', 'pygments_lexer': 'ipython3', 'version': '3.6.8' } }, 'nbformat': 4, 'nbformat_minor': 2 }, 'C#': { "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { }, "outputs": [ ], "source": [ "// We need to load assemblies at the start in their own cell\n", "#load \"../Initialize.csx\"" ] }, ], "metadata": { "kernelspec": { "display_name": ".NET (C#)", "language": "C#", "name": "csharp" }, "language_info": { "file_extension": ".cs", "mimetype": "text/x-csharp", "name": "C#", "pygments_lexer": "csharp", "version": "9.0" } }, "nbformat": 4, "nbformat_minor": 2 } } _default_file_names = { 'Py': ['main.py', 'research.ipynb'], 'C#': ['Main.cs', 'Research.ipynb'] } @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_create_file(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Test adding an empty code file to the project. await Files.create( id_, 'test_file_1.py' if language == 'Py' else 'TestFile1.cs' ) # Test adding a code file with contents to the project. if language == 'Py': name = 'test_file_2.py' else: name = 'TestFile2.cs' content = self._basic_code_file[language] file = (await Files.create(id_, name, content=content)).files[0] assert file.name == name assert file.content == content # Test adding a research file with contents to the project. if language == 'Py': name = 'test_file_3.py' else: name = 'TestFile3.ipynb' content = json.dumps(self._basic_research_file[language]) file = (await Files.create(id_, name, content=content)).files[0] assert file.name == name assert file.content == content # Test adding a directory. if language == 'Py': name = 'test_dir/test_file_4.py' else: name = 'TestDir/TestFile4.cs' await Files.create(id_, name) # Response is {'success': True} # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio async def test_create_file_during_project_collaboration(self): # Create a project and add a collaborator. project_id = (await Project.create()).projectId await ProjectCollaboration.create( project_id, COLLABORATOR_ID, True, True ) # Before editing the project, lock it and read files to avoid # errors. await ProjectCollaboration.lock(project_id) await Files.read(project_id) # Test adding a file to the project. await Files.create(project_id, 'test_file_1.py') # Remove the collaborator and delete the project to clean up. await ProjectCollaboration.delete(project_id, COLLABORATOR_ID) await Project.delete(project_id) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_create_file_on_with_invalid_args(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Test the invalid requests. tool_name = 'create_file' minimal_payload = { 'projectId': id_, 'name': 'test_file.py' if language == 'Py' else 'TestFile.cs' } await ensure_request_raises_validation_error_when_omitting_an_arg( tool_name, CreateProjectFileRequest, minimal_payload ) await ensure_request_fails_when_including_an_invalid_arg( mcp, tool_name, minimal_payload, [ # Try to add a file to a project that doesn't exist. {'projectId': -1}, # Try to add a file to a project with the same name as # a file that is already in the project. {'name': self._default_file_names[language][0]}, # Try to add a file that has no content. {'content': ''} ] ) # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_read_file(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Try to read all the default files in the project one-by-one. for file_name in self._default_file_names[language]: files = (await Files.read(id_, name=file_name)).files assert len(files) == 1 file = files[0] assert file.projectId == id_ assert file.name == file_name # Try to read all the default files in a project at once. files = (await Files.read(id_)).files assert len(files) == 2 for f in files: assert f.projectId == id_ assert f.name in self._default_file_names[language] # Try to read all the files after adding a new empty file to # the project. if language == 'Py': name = 'test_dir/test_file.py' else: name = 'TestDir/TestFile.cs' content = self._basic_code_file[language] await Files.create(id_, name, content=content) files = (await Files.read(id_, name=name)).files assert len(files) == 1 file = files[0] assert file.name == name assert file.content == content # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_read_file_with_invalid_args(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Test the invalid requests. tool_name = 'read_file' # Try to read the files of a project without providing the # project Id. await ensure_request_raises_validation_error( tool_name, ReadFilesRequest, {} ) await ensure_request_fails_when_including_an_invalid_arg( mcp, tool_name, {'projectId': id_}, [ # Try to read a file from a project that doesn't exist. {'projectId': -1}, # Try to read a file that doesn't exist. {'name': self._default_file_names[language][0][2:]}, ] ) # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_update_file_name(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Add a basic code file. name = 'test_file.py' if language == 'Py' else 'TestFile.cs' await Files.create(id_, name) # Try to update the file name. new_name = 'test_file_1.py' if language == 'Py' else 'TestFile1.cs' await Files.update(id_, name=name, newName=new_name) files = (await Files.read(id_)).files assert all([f.name != name for f in files]) assert any([f.name == new_name for f in files]) # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_update_file_name_with_invalid_args(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Add a basic code file. name = 'test_file.py' if language == 'Py' else 'TestFile.cs' await Files.create(id_, name) # Test the invalid requests. tool_name = 'update_file_name' minimal_payload = { 'projectId': id_, 'name': name, 'newName': 'test_file_1.py' if language == 'Py' else 'TestFile1.cs' } # Try to update the file name without providing all the data. await ensure_request_raises_validation_error_when_omitting_an_arg( tool_name, UpdateFileNameRequest, minimal_payload ) await ensure_request_fails_when_including_an_invalid_arg( mcp, tool_name, minimal_payload, [ # Try to update the name of a file in a project that # doesn't exist. {'projectId': -1}, # Try to update the name of a file that doesn't exist # in the project. {'name': self._default_file_names[language][0][2:]}, ] ) # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_update_contents(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Update the contents of the default code file. name = self._default_file_names[language][0] content = self._basic_code_file[language] response = await Files.update(id_, name=name, content=content) assert len(response.files) == 1 file = response.files[0] assert file.name == name assert file.content == content # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_update_file_contents_with_invalid_args(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Test the invalid requests. tool_name = 'update_file_contents' minimal_payload = { 'projectId': id_, 'name': self._default_file_names[language][0], 'content': self._basic_code_file[language] } # Try to update the contents of a file without providing all # the data. await ensure_request_raises_validation_error_when_omitting_an_arg( tool_name, UpdateFileContentsRequest, minimal_payload ) await ensure_request_fails_when_including_an_invalid_arg( mcp, tool_name, minimal_payload, [ # Try to contents of a file in a project that doesn't # exist. {'projectId': -1}, # Try to update a file that doesn't exist in the # project. {'name': self._default_file_names[language][0][2:]}, # Try to update the file contents to a blank file. {'content': ''}, ] ) # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_delete_file(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Try to delete the code file. await Files.delete(id_, self._default_file_names[language][0]) files = (await Files.read(id_)).files assert len(files) == 1 assert files[0].name == self._default_file_names[language][1] # Try to delete the research file. await Files.delete(id_, self._default_file_names[language][1]) files = (await Files.read(id_)).files assert len(files) == 0 # Try to delete a file in a directory. if language == 'Py': name = 'test_dir/test_file.py' else: name = 'TestDir/TestFile.cs' content = self._basic_code_file[language] await Files.create(id_, name, content=content) await Files.delete(id_, name) files = (await Files.read(id_)).files assert len(files) == 0 # Delete the project to clean up. await Project.delete(id_) @pytest.mark.asyncio @pytest.mark.parametrize('language', ['Py', 'C#']) async def test_delete_file_with_invalid_args(self, language): # Create a project. id_ = (await Project.create(language=language)).projectId # Test the invalid requests. tool_name = 'delete_file' minimal_payload = { 'projectId': id_, 'name': self._default_file_names[language][0] } # Try to read a file without providing all the required data. await ensure_request_raises_validation_error( tool_name, DeleteFileRequest, {} ) await ensure_request_fails_when_including_an_invalid_arg( mcp, tool_name, minimal_payload, [ # Try to delete a file from a project that doesn't exist. {'projectId': -1}, # Try to delete a file that doesn't exist. {'name': self._default_file_names[language][0][2:]}, ] ) # Delete the project to clean up. await Project.delete(id_)

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/i-dream-of-ai/quantconnect-mcp-jwt'

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