添加jupyterNooteBook token生成,创建笔记本等接口

master
whb
parent b976826f0f
commit dcfbd56d41

@ -0,0 +1,344 @@
package com.sztzjy.resource_center.controller.new_module.stu;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sztzjy.resource_center.annotation.AnonymousAccess;
import com.sztzjy.resource_center.util.ResultEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @author 17803
* @date 2024-07-19 13:21
*/
@RestController
@Api(tags = "jupyter相关")
@RequestMapping("api/stu/jupyter")
public class StuJupyterController {
@Value("${tch.serverAddress}")
String JUPYTER_URL;
@Value("${tch.token}")
String TOKEN;
//获取最新token
@ApiOperation("教师端获取token")
@GetMapping("/tokenTch")
@AnonymousAccess
public ResultEntity getBlockResources(@ApiParam("参数为jupytertch/jupyterstu") String type) throws IOException, InterruptedException {
String[] command = {"docker", "exec", type, "jupyter", "server", "list"};
Map map = connectdocker(command);
Object o = map.get("exitCode");
System.out.println(o);
Integer exitCode = Convert.toInt(o);
System.out.println(exitCode);
if (exitCode == 0) {
Object out = map.get("output");
String output = Convert.toStr(out);
// String s="Currently running servers: http://27fedcc1ea32:8888/?token=0201325a5e218f35db24f90b8a4c23373ec86987ce9d0a56 :: /home/jovyan/work";
int i = output.toString().indexOf("=");
int i1 = output.toString().lastIndexOf("::");
String substring = output.toString().substring(i + 1, i1 - 1);
System.out.println(substring);
//todo 保存数据库 每半小时执行一次更新token ,如果相同就变换,否则就不变
return new ResultEntity<>(HttpStatus.OK, type + "token为", substring);
} else {
// 执行失败,输出错误信息
Object err = map.get("errors");
String errors = Convert.toStr(err);
System.err.println("Error executing Python code:\n" + errors.toString());
return new ResultEntity(HttpStatus.OK, errors.toString());
}
}
//文件格式转换
@ApiOperation("发布之后格式转换")
@GetMapping("/convertToObj")
@AnonymousAccess
public ResultEntity convertToObj(@ApiParam("参数为:案例名") String name) throws IOException, InterruptedException {
String caseName = "/home/jovyan/work/" + name + ".ipynb";
String[] command = {"docker", "exec", "jupytertch", "sudo", "jupyter", "nbconvert", "--to", "markdown", caseName};
Map map = connectdocker(command);
Object o = map.get("exitCode");
Integer exitCode = Convert.toInt(o);
if (exitCode == 0) {
Object out = map.get("output");
String output = Convert.toStr(out);
System.out.println(output);
//文件移动
String path = "/usr/local/tianzeProject/jupyter/tch/" + name + ".md";
String toPath = "/usr/local/tianzeProject/jupyter/html";
String[] commandMove = {"sudo", "mv", path, toPath};
Process process = Runtime.getRuntime().exec(commandMove);
// 获取进程的输入流
BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
// 获取进程的输出流
BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// 等待进程执行完成
int exitCodeInfo = process.waitFor();
if (exitCodeInfo == 0) {
return new ResultEntity<>(HttpStatus.OK, "导出成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "导出失败!请联系管理员");
}
} else {
// 执行失败,输出错误信息
Object err = map.get("errors");
String errors = Convert.toStr(err);
System.err.println("Error executing Python code:\n" + errors.toString());
return new ResultEntity(HttpStatus.OK, errors.toString());
}
}
//文件查询 ,判断有无文件
@ApiOperation("发布时候判断文件是否存在")
@GetMapping("/filesIfExist")
@AnonymousAccess
public ResultEntity filesIfExist(@ApiParam("参数为:案例名") String name) throws InterruptedException, IOException {
String path = "/usr/local/tianzeProject/jupyter/tch";
// 创建表示该目录的 File 对象
File directory = new File(path);
// 获取目录中的所有文件和子目录
File[] filesList = directory.listFiles();
if (filesList != null) {
// 使用流查找目标文件
Optional<File> targetFile = Arrays.stream(filesList)
.filter(file -> file.getName().equals(name))
.findFirst();
if (targetFile.isPresent()) {
System.out.println("找到了目标文件: " + targetFile.get().getPath());
//文件复制
// String pathFile = "/usr/local/tianzeProject/jupyter/tch/"+name+".ipynb";
String toPath = "/usr/local/tianzeProject/jupyter/stu";
String[] commandMove = {"sudo", "cp", "-f", targetFile.get().getPath(), toPath};
Process process = Runtime.getRuntime().exec(commandMove);
// 获取进程的输入流
BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
// 获取进程的输出流
BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// 等待进程执行完成
int exitCodeInfo = process.waitFor();
System.out.println(exitCodeInfo);
if (exitCodeInfo == 0) {
return new ResultEntity<>(HttpStatus.OK, "复制成功", true);
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "复制失败!请联系管理员", false);
}
} else {
return new ResultEntity<>(HttpStatus.OK, "文件不存在!", false);
}
} else {
System.out.println("该目录不存在或不是一个目录");
return new ResultEntity<>(HttpStatus.BAD_REQUEST, false);
}
}
@ApiOperation("后端根据名字创建notebook")
@GetMapping("/createNoteBook")
@AnonymousAccess
public ResultEntity createNoteBook(@ApiParam("参数为:案例名") String name) {
//判断有无这个案例
//
// String path = "/usr/local/tianzeProject/jupyter/tch";
//
// // 创建表示该目录的 File 对象
// File directory = new File(path);
//
// // 获取目录中的所有文件和子目录
// File[] filesList = directory.listFiles();
//
//
// if (filesList != null) {
// // 使用流查找目标文件
// Optional<File> targetFile = Arrays.stream(filesList)
// .filter(file -> file.getName().equals(name))
// .findFirst();
//
// if (targetFile.isPresent()) {
// return new ResultEntity<>(HttpStatus.OK,"文件已存在");
// }
// }
//没有就创建
try (CloseableHttpClient client = HttpClients.createDefault()) {
String notebookContent = "{"
+ "\"cells\": ["
+ "{"
+ "\"cell_type\": \"code\","
+ "\"execution_count\": null,"
+ "\"metadata\": {},"
+ "\"outputs\": [],"
+ "\"source\": [\"print('Hello, world!')\"]"
+ "},"
+ "{"
+ "\"cell_type\": \"raw\","
+ "\"execution_count\": null,"
+ "\"metadata\": {},"
+ "\"outputs\": [],"
+ "\"source\": [\"print('This is text!')\"]"
+ "},"
+ "{"
+ "\"cell_type\": \"markdown\","
+ "\"metadata\": {},"
+ "\"source\": [\"# Markdown Cell\\n\", \"This is a markdown cell.\"]"
+ "}"
+ "],"
+ "\"metadata\": {"
+ " \"kernelspec\": {"
+ " \"display_name\": \"Python 3\","
+ " \"language\": \"python\","
+ " \"name\": \"python3\""
+ " }"
+ "},"
+ "\"nbformat\": 4,"
+ "\"nbformat_minor\": 2"
+ "}";
// 在根目录下创建新的笔记本
HttpPut createNotebookRequest = new HttpPut(JUPYTER_URL + "/api/contents/"+name+".ipynb");
createNotebookRequest.addHeader("Authorization", "token " + TOKEN);
createNotebookRequest.addHeader("Content-Type", "application/json");
createNotebookRequest.setEntity(new StringEntity("{\"type\": \"notebook\", \"content\": " + notebookContent + "}"));
try (CloseableHttpResponse createNotebookResponse = client.execute(createNotebookRequest)) {
int statusCode = createNotebookResponse.getStatusLine().getStatusCode();
if (statusCode == 201) {
System.out.println("Notebook created successfully!");
return new ResultEntity<>(HttpStatus.OK,"创建成功!");
} else {
String responseBody = EntityUtils.toString(createNotebookResponse.getEntity());
System.out.println("Failed to create notebook: " + responseBody);
return new ResultEntity<>(HttpStatus.OK,"已经存在,不用重复创建");
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 导入ipynb文件
//打开页面创建一个uuid文本返回名字给前端前端拼接路径打开保存文件就行 保存之后重命名为案例名称
// 两套系统,一套教师能看到,一套学生能看到 ,老师发布后学生能看到
public Map connectdocker(String[] command) throws IOException, InterruptedException {
// 创建一个新的进程来执行Python代码
Process process = Runtime.getRuntime().exec(command);
// 获取进程的输入流
BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
// 获取进程的输出流
BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// 读取Python代码的输出
String line;
StringBuilder output = new StringBuilder();
while ((line = inputStream.readLine()) != null) {
output.append(line).append("\n");
}
// 读取Python代码的错误信息
StringBuilder errors = new StringBuilder();
while ((line = errorStream.readLine()) != null) {
errors.append(line).append("\n");
}
// 等待进程执行完成
int exitCode = process.waitFor();
Map<String, String> map = new HashMap<>();
map.put("exitCode", String.valueOf(exitCode));
map.put("output", output.toString());
map.put("errors", errors.toString());
return map;
}
//新增notebook可用
public static void main(String[] args) throws Exception {
createNotebookAndExecuteCode();
}
public static void createNotebookAndExecuteCode() throws IOException {
}
}

@ -23,4 +23,9 @@ swagger:
description: 天择外汇模拟交易WebAPI接口文档
contactName: 深圳天择教育科技有限公司
contactAddress: www.sztzjy.com
version: @project.version@
version: @project.version@
tch:
serverAddress: http://118.31.7.2:9998
token: 26a5b8081702080b150b9d4a715a4b9b442b1d3b5c38823c
Loading…
Cancel
Save