Skip to content

Commit f60a02c

Browse files
author
Fraser Greenroyd
authored
6.3 Deployment (#116)
2 parents d7cca92 + 5ce577b commit f60a02c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1219
-1506
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,8 @@ Alligator/Alligator_REMOTE_9848.csproj
9494

9595
# VSCode User File #
9696
####################
97-
.vscode/
97+
.vscode/
98+
99+
# User defined files #
100+
######################
101+
build.ps1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* This file is part of the Buildings and Habitats object Model (BHoM)
3+
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
4+
*
5+
* Each contributor holds copyright over their respective contributions.
6+
* The project versioning (Git) records all such contribution source information.
7+
*
8+
*
9+
* The BHoM is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3.0 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* The BHoM is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
21+
*/
22+
23+
using BH.oM.Base.Attributes;
24+
using BH.oM.Python;
25+
using BH.oM.Python.Enums;
26+
using System.Collections.Generic;
27+
using System.ComponentModel;
28+
using System.Diagnostics;
29+
using System.IO;
30+
using System.Linq;
31+
32+
namespace BH.Engine.Python
33+
{
34+
public static partial class Compute
35+
{
36+
[Description("Retrieve or reinstall the base Python Environment for BHoM workflows.")]
37+
[Input("reload", "Reload the base Python environment rather than recreating it, if it already exists.")]
38+
[Output("env", "The base Python Environment for all BHoM workflows.")]
39+
[PreviousVersion("6.3", "BH.Engine.Python.Compute.InstallBasePythonEnvironment(System.Boolean)")]
40+
public static PythonEnvironment BasePythonEnvironment(
41+
bool reload = true
42+
)
43+
{
44+
if (!Directory.Exists(Query.DirectoryEnvironments()))
45+
{
46+
// create PythonEnvironments directory if it doesnt already exist
47+
Directory.CreateDirectory(Query.DirectoryEnvironments());
48+
}
49+
50+
// determine whether the base environment already exists
51+
string targetExecutable = Path.Combine(Query.DirectoryBaseEnvironment(), "python.exe");
52+
bool exists = Directory.Exists(Query.DirectoryBaseEnvironment()) && File.Exists(targetExecutable);
53+
54+
if (exists && reload)
55+
return new PythonEnvironment() { Name = Query.ToolkitName(), Executable = targetExecutable };
56+
57+
if (exists && !reload)
58+
// remove all existing environments and kernels
59+
RemoveEverything();
60+
61+
// download the target Python version and convert into a "full" python installation bypassing admin rights
62+
string executable = PythonVersion.v3_10_5.DownloadPython(Query.ToolkitName());
63+
string pipInstaller = DownloadGetPip(Path.GetDirectoryName(executable));
64+
string baseEnvironmentDirectory = Path.GetDirectoryName(executable);
65+
66+
// install pip into the python installation
67+
Process process = new Process()
68+
{
69+
StartInfo = new ProcessStartInfo()
70+
{
71+
FileName = Modify.AddQuotesIfRequired(executable),
72+
Arguments = Modify.AddQuotesIfRequired(pipInstaller) + " --no-warn-script-location",
73+
RedirectStandardError=true,
74+
UseShellExecute=false,
75+
}
76+
};
77+
using (Process p = Process.Start(process.StartInfo))
78+
{
79+
p.WaitForExit();
80+
if (p.ExitCode != 0)
81+
BH.Engine.Base.Compute.RecordError($"Error installing pip.\n{p.StandardError.ReadToEnd()}");
82+
File.Delete(pipInstaller);
83+
}
84+
85+
// delete files with the suffix ._pth from installedDirectory
86+
List<string> pthFiles = Directory.GetFiles(baseEnvironmentDirectory, "*.*", SearchOption.TopDirectoryOnly).Where(s => s.EndsWith("._pth")).ToList();
87+
foreach (string pthFile in pthFiles)
88+
{
89+
File.Delete(pthFile);
90+
}
91+
92+
// move files with the suffix .dll and .pyd from installedDirectory into a DLLs directory
93+
string libDirectory = Directory.CreateDirectory(Path.Combine(baseEnvironmentDirectory, "DLLs")).FullName;
94+
List<string> libFiles = Directory.GetFiles(baseEnvironmentDirectory, "*.*", SearchOption.TopDirectoryOnly).Where(s => (s.EndsWith(".dll") || s.EndsWith(".pyd")) && !Path.GetFileName(s).Contains("python") && !Path.GetFileName(s).Contains("vcruntime")).ToList();
95+
foreach (string libFile in libFiles)
96+
{
97+
File.Move(libFile, Path.Combine(libDirectory, Path.GetFileName(libFile)));
98+
}
99+
100+
// install essential packages into base environment
101+
InstallPackages(executable, new List<string>() { "virtualenv", "jupyterlab", "black", "pylint" });
102+
103+
return new PythonEnvironment() { Name = Query.ToolkitName(), Executable = executable };
104+
}
105+
}
106+
}

Python_Engine/Compute/Download.cs

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* This file is part of the Buildings and Habitats object Model (BHoM)
3+
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
4+
*
5+
* Each contributor holds copyright over their respective contributions.
6+
* The project versioning (Git) records all such contribution source information.
7+
*
8+
*
9+
* The BHoM is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3.0 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* The BHoM is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
21+
*/
22+
23+
using BH.oM.Base.Attributes;
24+
using BH.oM.Python.Enums;
25+
using System;
26+
using System.ComponentModel;
27+
using System.IO;
28+
using System.Xml.Linq;
29+
30+
namespace BH.Engine.Python
31+
{
32+
public static partial class Compute
33+
{
34+
[Description("Download a file from a Url.")]
35+
[Input("fileUrl", "The file to download.")]
36+
[Input("targetDirectory", "The destination directory to download the file to.")]
37+
[Input("filename", "An optional input to rename the downloaded file.")]
38+
[Input("overwrite", "An optional input to overwrite the file if it already exists, otherwise if it does then return the existing file.")]
39+
[Output("filePath", "The path to the downloaded file.")]
40+
public static string DownloadFile(
41+
string fileUrl,
42+
string targetDirectory,
43+
string filename = null,
44+
bool overwrite = true
45+
)
46+
{
47+
if (string.IsNullOrWhiteSpace(fileUrl))
48+
{
49+
BH.Engine.Base.Compute.RecordError($"The fileUrl cannot be null or empty.");
50+
return null;
51+
}
52+
53+
54+
if (string.IsNullOrWhiteSpace(targetDirectory))
55+
{
56+
BH.Engine.Base.Compute.RecordError($"The targetDirectory cannot be null or empty.");
57+
return null;
58+
}
59+
60+
61+
if (!Directory.Exists(targetDirectory))
62+
{
63+
BH.Engine.Base.Compute.RecordError($"The targetDirectory \"{targetDirectory}\" does not exist.");
64+
return null;
65+
}
66+
67+
68+
if (string.IsNullOrWhiteSpace(filename))
69+
filename = Path.GetFileName(fileUrl);
70+
71+
string filePath = Path.Combine(targetDirectory, filename);
72+
73+
if (File.Exists(filePath))
74+
{
75+
if (!overwrite)
76+
return filePath;
77+
File.Delete(filePath);
78+
}
79+
80+
using (var client = new System.Net.WebClient())
81+
{
82+
client.DownloadFile(fileUrl, filePath);
83+
}
84+
85+
return filePath;
86+
}
87+
88+
// TODO - THIS METHOD HAS CHANGED BUT IS STILL USED, SO NEEDS DEPRECATING
89+
// changed from what to what ?
90+
[Description("Download the target version of Python.")]
91+
[Input("version", "A Python version.")]
92+
[Input("name", "Name of target exe file.")]
93+
[Output("executablePath", "The path of the executable for the downloaded Python.")]
94+
[PreviousVersion("6.3", "BH.Engine.Python.Compute.DownloadPython(BH.oM.Python.Enums.PythonVersion)")]
95+
public static string DownloadPython(this PythonVersion version, string name = null)
96+
{
97+
string url = version.EmbeddableURL();
98+
if (string.IsNullOrEmpty(name))
99+
name = Path.GetFileNameWithoutExtension(url);
100+
string targetExecutable = Path.Combine(Query.DirectoryEnvironments(), name, "python.exe");
101+
102+
if (File.Exists(targetExecutable))
103+
return targetExecutable;
104+
105+
string zipfile = DownloadFile(url, Query.DirectoryEnvironments());
106+
UnzipFile(zipfile, Query.DirectoryEnvironments(), name, true);
107+
108+
return targetExecutable;
109+
}
110+
111+
[Description("Download the pip installer")]
112+
[Input("targetDirectory", "The directory into which get-pip.py will be downloaded.")]
113+
[Output("getpipPath", "The path of the file used to install pip into an embedded Python environment.")]
114+
public static string DownloadGetPip(string targetDirectory)
115+
{
116+
return DownloadFile("https://bootstrap.pypa.io/get-pip.py", targetDirectory);
117+
}
118+
}
119+
}

Python_Engine/Compute/DownloadPython.cs

-65
This file was deleted.

0 commit comments

Comments
 (0)