From 1d67eb9e77b3f43a91590c01ad2a74002eb698c2 Mon Sep 17 00:00:00 2001 From: Hagen Fritz Date: Mon, 20 Jan 2025 10:17:08 -0600 Subject: [PATCH] feat: add filter for project --- .github/workflows/publish_to_pypi.yml | 0 .github/workflows/tests.yml | 4 +- ProPyCore/access/projects.py | 8 +- propycore-0.5.0/setup.cfg | 4 - propycore-0.5.0/tests/unit/test_cost_codes.py | 52 ----- propycore-0.5.0/tests/unit/test_files.py | 199 ------------------ .../tests/unit/test_generic_tools.py | 39 ---- propycore-0.5.0/tests/unit/test_rfis.py | 69 ------ propycore-0.5.0/tests/unit/test_tasks.py | 69 ------ setup.py | 2 +- snippets/projects.ipynb | 76 ++++--- 11 files changed, 60 insertions(+), 462 deletions(-) create mode 100644 .github/workflows/publish_to_pypi.yml delete mode 100644 propycore-0.5.0/setup.cfg delete mode 100644 propycore-0.5.0/tests/unit/test_cost_codes.py delete mode 100644 propycore-0.5.0/tests/unit/test_files.py delete mode 100644 propycore-0.5.0/tests/unit/test_generic_tools.py delete mode 100644 propycore-0.5.0/tests/unit/test_rfis.py delete mode 100644 propycore-0.5.0/tests/unit/test_tasks.py diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a5cebaa..9c987b7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,8 +37,8 @@ jobs: - name: Test with pytest env: - CLIENT_ID: ${{ secrets.PROCORE_CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.PROCORE_CLIENT_SECRET }} + PROCORE_CLIENT_ID: ${{ secrets.PROCORE_CLIENT_ID }} + PROCORE_CLIENT_SECRET: ${{ secrets.PROCORE_CLIENT_SECRET }} SANDBOX_COMPANY_ID: ${{ secrets.SANDBOX_COMPANY_ID }} SANDBOX_PROJECT_ID: ${{ secrets.SANDBOX_PROJECT_ID }} REDIRECT_URI: "urn:ietf:wg:oauth:2.0:oob" diff --git a/ProPyCore/access/projects.py b/ProPyCore/access/projects.py index 7f03361..1d4fe1c 100644 --- a/ProPyCore/access/projects.py +++ b/ProPyCore/access/projects.py @@ -11,9 +11,10 @@ def __init__(self, access_token, server_url) -> None: self.endpoint = "/rest/v1.1/projects" - def get(self, company_id, per_page=300): + def get(self, company_id, status="All",per_page=300): """ Gets a list of all the projects from a certain company + https://developers.procore.com/reference/rest/projects?version=latest#list-projects Parameters ---------- @@ -21,6 +22,8 @@ def get(self, company_id, per_page=300): unique identifier for the company per_page : int, default 300 number of companies to include. Max is 300 per v1.1 API. + status : str enum, default "All" + status of the projects to get must be one of: ["Active", "Inactive", "All"] Returns ------- @@ -34,7 +37,8 @@ def get(self, company_id, per_page=300): params = { "company_id": company_id, "page": page, - "per_page": per_page + "per_page": per_page, + "filters[by_status]": status } projects_per_page = self.get_request( diff --git a/propycore-0.5.0/setup.cfg b/propycore-0.5.0/setup.cfg deleted file mode 100644 index 8bfd5a1..0000000 --- a/propycore-0.5.0/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[egg_info] -tag_build = -tag_date = 0 - diff --git a/propycore-0.5.0/tests/unit/test_cost_codes.py b/propycore-0.5.0/tests/unit/test_cost_codes.py deleted file mode 100644 index 5eb5694..0000000 --- a/propycore-0.5.0/tests/unit/test_cost_codes.py +++ /dev/null @@ -1,52 +0,0 @@ -import pytest -from ProPyCore.access.cost_codes import CostCodes -from ProPyCore.exceptions import NotFoundItemError - -# Fixture for CostCodes instance -@pytest.fixture -def cost_codes_instance(mocker): - mocker.patch('ProPyCore.access.cost_codes.Base.__init__', return_value=None) # Mock the base class initializer - return CostCodes('mock_access_token', 'mock_server_url') - -def test_get_cost_codes(cost_codes_instance, mocker): - # Mock the get_request method to return sample cost codes for different pages - mock_response_page_1 = [{'id': 1, 'name': 'Code 1'}, {'id': 2, 'name': 'Code 2'}] - mock_response_page_2 = [] - - mocker.patch.object(cost_codes_instance, 'get_request', side_effect=[mock_response_page_1, mock_response_page_2]) - - response = cost_codes_instance.get(company_id=123, project_id=456) - - assert isinstance(response, list) - assert response == mock_response_page_1 - -def test_show_cost_code(cost_codes_instance, mocker): - # Mock the get_request method to return a specific cost code - mock_response = {'id': 1, 'name': 'Code 1'} - mocker.patch.object(cost_codes_instance, 'get_request', return_value=mock_response) - - cost_code = cost_codes_instance.show(company_id=123, project_id=456, cost_code_id=1) - - assert isinstance(cost_code, dict) - assert cost_code == {'id': 1, 'name': 'Code 1'} - -def test_find_cost_code_by_id(cost_codes_instance, mocker): - # Mock the get method to return a list of cost codes - mock_get_response = [{'id': 1, 'name': 'Code 1'}, {'id': 2, 'name': 'Code 2'}] - mock_show_response = {'id': 1, 'name': 'Code 1'} - - mocker.patch.object(cost_codes_instance, 'get', return_value=mock_get_response) - mocker.patch.object(cost_codes_instance, 'show', return_value=mock_show_response) - - cost_code = cost_codes_instance.find(company_id=123, project_id=456, identifier=1) - - assert isinstance(cost_code, dict) - assert cost_code == {'id': 1, 'name': 'Code 1'} - -def test_find_cost_code_not_found(cost_codes_instance, mocker): - # Mock the get method to return a list of cost codes - mock_get_response = [{'id': 1, 'name': 'Code 1'}, {'id': 2, 'name': 'Code 2'}] - mocker.patch.object(cost_codes_instance, 'get', return_value=mock_get_response) - - with pytest.raises(NotFoundItemError): - cost_codes_instance.find(company_id=123, project_id=456, identifier=999) \ No newline at end of file diff --git a/propycore-0.5.0/tests/unit/test_files.py b/propycore-0.5.0/tests/unit/test_files.py deleted file mode 100644 index cfc2dcc..0000000 --- a/propycore-0.5.0/tests/unit/test_files.py +++ /dev/null @@ -1,199 +0,0 @@ -import pytest -from unittest.mock import MagicMock, mock_open -from ProPyCore.access.documents.files import Files # Adjust the import path as needed - - -class TestFiles: - @pytest.fixture - def files_instance(self, mocker): - """ - Fixture to create an instance of the Files class with mocked dependencies. - """ - mocker.patch("ProPyCore.access.documents.files.Base.__init__", return_value=None) # Mock Base class init - return Files(access_token="mock_access_token", server_url="mock_server_url") - - def test_create(self, files_instance, mocker): - """ - Test the `create` method. - """ - mock_file = mock_open(read_data="dummy content") - mocker.patch("builtins.open", mock_file) - mocker.patch.object( - files_instance, - "post_request", - return_value={"id": 1, "name": "New File"} - ) - - response = files_instance.create( - company_id=123, - project_id=456, - filepath="/path/to/file.txt", - folder_id=789, - description="Test file" - ) - - # Assertions - assert response["id"] == 1 - assert response["name"] == "New File" - - # Verify the call to `post_request` - files_instance.post_request.assert_called_once() - - # Extract the actual call arguments for comparison - call_args = files_instance.post_request.call_args[1] - - # Validate `api_url`, `additional_headers`, `params`, and `data` - assert call_args["api_url"] == "/rest/v1.0/files" - assert call_args["additional_headers"] == {"Procore-Company-Id": "123"} - assert call_args["params"] == {"project_id": 456} - assert call_args["data"] == { - "file[name]": "file.txt", - "file[description]": "Test file", - "file[parent_id]": 789, - } - - # Validate the structure of `files` argument - assert len(call_args["files"]) == 1 - assert call_args["files"][0][0] == "file[data]" - assert mock_file.return_value in call_args["files"][0] - - def test_update(self, files_instance, mocker): - """ - Test the `update` method. - """ - mock_file = mock_open(read_data="dummy content") - mocker.patch("builtins.open", mock_file) - mocker.patch.object( - files_instance, - "patch_request", - return_value={"id": 1, "name": "Updated File"} - ) - - response = files_instance.update( - company_id=123, - project_id=456, - doc_id=1, - filepath="/path/to/file.txt", - folder_id=789, - filename="Updated File.txt", - description="Updated description" - ) - - # Assertions - assert response["id"] == 1 - assert response["name"] == "Updated File" - - # Verify the call to `patch_request` - files_instance.patch_request.assert_called_once() - - # Extract the actual call arguments for comparison - call_args = files_instance.patch_request.call_args[1] - - # Validate `api_url`, `additional_headers`, `params`, and `data` - assert call_args["api_url"] == "/rest/v1.0/files/1" - assert call_args["additional_headers"] == {"Procore-Company-Id": "123"} - assert call_args["params"] == {"project_id": 456} - assert call_args["data"] == { - "file[parent_id]": 789, - "file[name]": "Updated File.txt", - "file[description]": "Updated description", - } - - # Validate the structure of `files` argument - assert len(call_args["files"]) == 1 - assert call_args["files"][0][0] == "file[data]" - assert mock_file.return_value in call_args["files"][0] - - def test_show(self, files_instance, mocker): - """ - Test the `show` method. - """ - mocker.patch.object( - files_instance, - "get_request", - return_value={"id": 1, "name": "Test File"} - ) - - response = files_instance.show(company_id=123, project_id=456, doc_id=1) - - # Assertions - assert response["id"] == 1 - assert response["name"] == "Test File" - - files_instance.get_request.assert_called_once_with( - api_url="/rest/v1.0/files/1", - additional_headers={"Procore-Company-Id": "123"}, - params={"project_id": 456} - ) - - def test_remove(self, files_instance, mocker): - """ - Test the `remove` method. - """ - mocker.patch.object( - files_instance, - "delete_request", - return_value={"success": True} - ) - - response = files_instance.remove(company_id=123, project_id=456, doc_id=1) - - # Assertions - assert response["success"] is True - - files_instance.delete_request.assert_called_once_with( - api_url="/rest/v1.0/files/1", - additional_headers={"Procore-Company-Id": "123"}, - params={"project_id": 456} - ) - - def test_get(self, files_instance, mocker): - """ - Test the `get` method. - """ - mocker.patch.object( - files_instance, - "get_request", - side_effect=[ - [{"id": 1, "is_deleted": False}, {"id": 2, "is_deleted": False}], - [] # To simulate pagination end - ] - ) - - response = files_instance.get(company_id=123, project_id=456) - - # Assertions - assert len(response) == 2 - assert response[0]["id"] == 1 - - files_instance.get_request.assert_any_call( - api_url="/rest/v1.0/projects/456/documents", - additional_headers={"Procore-Company-Id": "123"}, - params={ - "view": "normal", - "sort": "name", - "page": 1, - "per_page": 10000, - "filters[document_type]": "file", - "filters[is_in_recycle_bin]": False - } - ) - - def test_search(self, files_instance, mocker): - """ - Test the `search` method. - """ - mocker.patch.object( - files_instance, - "get", - return_value=[ - {"id": 1, "name": "Matching File", "is_deleted": False, "is_recycle_bin": False, "document_type": "file"}, - {"id": 2, "name": "Another File", "is_deleted": False, "is_recycle_bin": False, "document_type": "file"} - ] - ) - - response = files_instance.search(company_id=123, project_id=456, value="Matching") - - # Assertions - assert response["id"] == 1 - assert response["search_criteria"]["match"] > 0 diff --git a/propycore-0.5.0/tests/unit/test_generic_tools.py b/propycore-0.5.0/tests/unit/test_generic_tools.py deleted file mode 100644 index 218e727..0000000 --- a/propycore-0.5.0/tests/unit/test_generic_tools.py +++ /dev/null @@ -1,39 +0,0 @@ -import pytest -from ProPyCore.access.generic_tools import GenericTool -from ProPyCore.exceptions import NotFoundItemError - -# Fixture for GenericTool instance -@pytest.fixture -def generic_tool_instance(): - return GenericTool('mock_access_token', 'mock_server_url') - -# Test for get_tools method -def test_get_tools(generic_tool_instance, mocker): - # Mock the get_request method - mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}] - mocker.patch.object(generic_tool_instance, 'get_request', return_value=mock_response) - - response = generic_tool_instance.get_tools(123) - - assert isinstance(response, list) - assert response == mock_response - -# Test for find_tool by id -def test_find_tool_by_id(generic_tool_instance, mocker): - # Mock the get_tools method - mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}] - mocker.patch.object(generic_tool_instance, 'get_tools', return_value=mock_response) - - tool = generic_tool_instance.find_tool(123, 1) - - assert tool == {'id': 1, 'title': 'Tool 1'} - -# Test for find_tool by title -def test_find_tool_by_title(generic_tool_instance, mocker): - # Mock the get_tools method - mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}] - mocker.patch.object(generic_tool_instance, 'get_tools', return_value=mock_response) - - tool = generic_tool_instance.find_tool(123, 'Tool 2') - - assert tool == {'id': 2, 'title': 'Tool 2'} diff --git a/propycore-0.5.0/tests/unit/test_rfis.py b/propycore-0.5.0/tests/unit/test_rfis.py deleted file mode 100644 index c0d995d..0000000 --- a/propycore-0.5.0/tests/unit/test_rfis.py +++ /dev/null @@ -1,69 +0,0 @@ -import pytest -from ProPyCore.access.rfis import RFI -from ProPyCore.exceptions import NotFoundItemError - -# Fixture for RFI instance -@pytest.fixture -def rfi_instance(mocker): - mocker.patch('ProPyCore.access.rfis.Base.__init__', return_value=None) # Mock the base class initializer - return RFI('mock_access_token', 'mock_server_url') - -def test_get_rfies(rfi_instance, mocker): - # Mock the get_request method to return sample RFIs with pagination - mock_response_page_1 = [{'id': 1, 'number': 'RFI-1'}, {'id': 2, 'number': 'RFI-2'}] - mock_response_page_2 = [] - - mocker.patch.object(rfi_instance, 'get_request', side_effect=[mock_response_page_1, mock_response_page_2]) - - response = rfi_instance.get(company_id=123, project_id=456) - - assert isinstance(response, list) - assert response == mock_response_page_1 - -def test_show_rfi(rfi_instance, mocker): - # Mock the get_request method to return a specific RFI - mock_response = {'id': 1, 'number': 'RFI-1'} - mocker.patch.object(rfi_instance, 'get_request', return_value=mock_response) - - response = rfi_instance.show(company_id=123, project_id=456, rfi_id=1) - - assert isinstance(response, dict) - assert response == mock_response - -def test_find_rfi_by_id(rfi_instance, mocker): - # Mock the get and show methods - mock_get_response_page_1 = [{'id': 1, 'number': 'RFI-1'}, {'id': 2, 'number': 'RFI-2'}] - mock_get_response_page_2 = [] - mock_show_response = {'id': 1, 'number': 'RFI-1'} - - mocker.patch.object(rfi_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - mocker.patch.object(rfi_instance, 'show', return_value=mock_show_response) - - rfi_info = rfi_instance.find(company_id=123, project_id=456, identifier=1) - - assert isinstance(rfi_info, dict) - assert rfi_info == mock_show_response - -def test_find_rfi_by_number(rfi_instance, mocker): - # Mock the get and show methods - mock_get_response_page_1 = [{'id': 1, 'number': 'RFI-1'}, {'id': 2, 'number': 'RFI-2'}] - mock_get_response_page_2 = [] - mock_show_response = {'id': 2, 'number': 'RFI-2'} - - mocker.patch.object(rfi_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - mocker.patch.object(rfi_instance, 'show', return_value=mock_show_response) - - rfi_info = rfi_instance.find(company_id=123, project_id=456, identifier='RFI-2') - - assert isinstance(rfi_info, dict) - assert rfi_info == mock_show_response - -def test_find_rfi_not_found(rfi_instance, mocker): - # Mock the get method to return sample RFIs - mock_get_response_page_1 = [{'id': 1, 'number': 'RFI-1'}, {'id': 2, 'number': 'RFI-2'}] - mock_get_response_page_2 = [] - - mocker.patch.object(rfi_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - - with pytest.raises(NotFoundItemError): - rfi_instance.find(company_id=123, project_id=456, identifier='Nonexistent RFI') diff --git a/propycore-0.5.0/tests/unit/test_tasks.py b/propycore-0.5.0/tests/unit/test_tasks.py deleted file mode 100644 index 529c8f4..0000000 --- a/propycore-0.5.0/tests/unit/test_tasks.py +++ /dev/null @@ -1,69 +0,0 @@ -import pytest -from ProPyCore.access.tasks import Task -from ProPyCore.exceptions import NotFoundItemError - -# Fixture for Task instance -@pytest.fixture -def task_instance(mocker): - mocker.patch('ProPyCore.access.tasks.Base.__init__', return_value=None) # Mock the base class initializer - return Task('mock_access_token', 'mock_server_url') - -def test_get_tasks(task_instance, mocker): - # Mock the get_request method to return sample tasks with pagination - mock_response_page_1 = [{'id': 1, 'name': 'Task 1'}, {'id': 2, 'name': 'Task 2'}] - mock_response_page_2 = [] - - mocker.patch.object(task_instance, 'get_request', side_effect=[mock_response_page_1, mock_response_page_2]) - - response = task_instance.get(company_id=123, project_id=456) - - assert isinstance(response, list) - assert response == mock_response_page_1 - -def test_show_task(task_instance, mocker): - # Mock the get_request method to return a specific task - mock_response = {'id': 1, 'name': 'Task 1'} - mocker.patch.object(task_instance, 'get_request', return_value=mock_response) - - response = task_instance.show(company_id=123, project_id=456, task_id=1) - - assert isinstance(response, dict) - assert response == mock_response - -def test_find_task_by_id(task_instance, mocker): - # Mock the get and show methods - mock_get_response_page_1 = [{'id': 1, 'name': 'Task 1'}, {'id': 2, 'name': 'Task 2'}] - mock_get_response_page_2 = [] - mock_show_response = {'id': 1, 'name': 'Task 1'} - - mocker.patch.object(task_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - mocker.patch.object(task_instance, 'show', return_value=mock_show_response) - - task_info = task_instance.find(company_id=123, project_id=456, identifier=1) - - assert isinstance(task_info, dict) - assert task_info == mock_show_response - -def test_find_task_by_name(task_instance, mocker): - # Mock the get and show methods - mock_get_response_page_1 = [{'id': 1, 'name': 'Task 1'}, {'id': 2, 'name': 'Task 2'}] - mock_get_response_page_2 = [] - mock_show_response = {'id': 2, 'name': 'Task 2'} - - mocker.patch.object(task_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - mocker.patch.object(task_instance, 'show', return_value=mock_show_response) - - task_info = task_instance.find(company_id=123, project_id=456, identifier='Task 2') - - assert isinstance(task_info, dict) - assert task_info == mock_show_response - -def test_find_task_not_found(task_instance, mocker): - # Mock the get method to return sample tasks - mock_get_response_page_1 = [{'id': 1, 'name': 'Task 1'}, {'id': 2, 'name': 'Task 2'}] - mock_get_response_page_2 = [] - - mocker.patch.object(task_instance, 'get_request', side_effect=[mock_get_response_page_1, mock_get_response_page_2]) - - with pytest.raises(NotFoundItemError): - task_instance.find(company_id=123, project_id=456, identifier='Nonexistent Task') diff --git a/setup.py b/setup.py index b2fec69..2198144 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name="ProPyCore", - version="0.5.0", + version="0.5.1", author="Hagen E. Fritz", author_email="hfritz@r-o.com", description="Interact with Procore through Python for data connection applications", diff --git a/snippets/projects.ipynb b/snippets/projects.ipynb index bd21de9..48e7916 100644 --- a/snippets/projects.ipynb +++ b/snippets/projects.ipynb @@ -131,25 +131,55 @@ "name": "stdout", "output_type": "stream", "text": [ - "Project: 1301 South Lamar (1668030)\n", - "Project: 24th & Rio Grande Student Housing (2289314)\n", + "Help on method get in module ProPyCore.access.projects:\n", + "\n", + "get(company_id, status='All', per_page=300) method of ProPyCore.access.projects.Projects instance\n", + " Gets a list of all the projects from a certain company\n", + " https://developers.procore.com/reference/rest/projects?version=latest#list-projects\n", + " \n", + " Parameters\n", + " ----------\n", + " company_id : int\n", + " unique identifier for the company\n", + " per_page : int, default 300\n", + " number of companies to include. Max is 300 per v1.1 API.\n", + " status : str enum, default \"All\"\n", + " status of the projects to get must be one of: [\"Active\", \"Inactive\", \"All\"]\n", + " \n", + " Returns\n", + " -------\n", + " projects : list of dict\n", + " list where each value is a dict with the project's id, active status (is_active), and name\n", + "\n" + ] + } + ], + "source": [ + "help(connection.projects.get)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ "Project: 315 College Main Apartments (1642207)\n", - "Project: Integrations & Connector Test Project (2512856)\n", - "Project: Intern Training Project (2121003)\n", - "Project: Mexican American Cultural Center, Phase 2 (1494731)\n", - "Project: OpX Test Project (2261578)\n", - "Project: Precon Test Project (2507742)\n", - "Project: Sandbox Test Project (2783683)\n", - "Project: South Laredo Multifamily (2430207)\n", - "Project: The Fundamentals Test Project (2861990)\n", - "Project: TSTC Waco CCAP (2602910)\n" + "Project: 400 W.15th Elevator Mods (2023731)\n", + "Project: 717 East Parmer (2319467)\n", + "Project: Cambria Hotel (1756058)\n", + "Project: Uptown Dual Brand Hotel (2412567)\n" ] } ], "source": [ "company = connection.companies.find(identifier=company_name)\n", "projects = connection.projects.get(\n", - " company_id=company[\"id\"]\n", + " company_id=company[\"id\"],\n", + " status=\"Inactive\"\n", ")\n", "for project in projects:\n", " print(f\"Project: {project['name']} ({project['id']})\")" @@ -195,17 +225,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dict_keys(['id', 'accounting_project_number', 'active', 'actual_start_date', 'address', 'city', 'code', 'company', 'completion_date', 'country_code', 'county', 'created_at', 'custom_fields', 'delivery_method', 'description', 'designated_market_area', 'display_name', 'erp_integrated', 'estimated_value', 'fax', 'is_demo', 'latitude', 'longitude', 'name', 'origin_code', 'origin_data', 'origin_id', 'owners_project_id', 'parent_job_id', 'phone', 'photo_id', 'project_bid_type_id', 'project_number', 'project_owner_type_id', 'project_region_id', 'project_stage', 'project_type', 'projected_finish_date', 'sector', 'square_feet', 'start_date', 'state_code', 'store_number', 'time_zone', 'total_value', 'updated_at', 'work_scope', 'zip'])\n" - ] - } - ], + "outputs": [], "source": [ "found_project = connection.projects.find(\n", " company_id=company[\"id\"],\n", @@ -248,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -258,6 +280,9 @@ "Project: 1301 South Lamar (1668030): Office\n", "Project: 24th & Rio Grande Student Housing (2289314): Multifamily\n", "Project: 315 College Main Apartments (1642207): Multifamily\n", + "Project: 400 W.15th Elevator Mods (2023731): Interiors\n", + "Project: 717 East Parmer (2319467): Interiors\n", + "Project: Cambria Hotel (1756058): Hospitality\n", "Project: Integrations & Connector Test Project (2512856): None\n", "Project: Intern Training Project (2121003): None\n", "Project: Mexican American Cultural Center, Phase 2 (1494731): Public\n", @@ -266,7 +291,8 @@ "Project: Sandbox Test Project (2783683): None\n", "Project: South Laredo Multifamily (2430207): Multifamily\n", "Project: The Fundamentals Test Project (2861990): None\n", - "Project: TSTC Waco CCAP (2602910): Higher Education\n" + "Project: TSTC Waco CCAP (2602910): Higher Education\n", + "Project: Uptown Dual Brand Hotel (2412567): Hospitality\n" ] } ], @@ -295,7 +321,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv_doc", + "display_name": ".venv", "language": "python", "name": "python3" },