mirror of
				https://github.com/ivanch/tcc.git
				synced 2025-11-04 03:07:36 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			FlaskAPI
			...
			05dad7ade5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 05dad7ade5 | |||
| cd1e9da710 | |||
| 1dbd8c238f | 
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,14 @@
 | 
				
			|||||||
.vs
 | 
					.vs
 | 
				
			||||||
 | 
					__pycache__
 | 
				
			||||||
bin
 | 
					bin
 | 
				
			||||||
obj
 | 
					obj
 | 
				
			||||||
 | 
					*.vscode
 | 
				
			||||||
 | 
					__pycache__
 | 
				
			||||||
 | 
					.idea
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*.png
 | 
					*.png
 | 
				
			||||||
 | 
					*.csv
 | 
				
			||||||
 | 
					*.jpg
 | 
				
			||||||
 | 
					*.mp4
 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
# Default ignored files
 | 
					 | 
				
			||||||
/shelf/
 | 
					 | 
				
			||||||
/workspace.xml
 | 
					 | 
				
			||||||
# Editor-based HTTP Client requests
 | 
					 | 
				
			||||||
/httpRequests/
 | 
					 | 
				
			||||||
# Datasource local storage ignored files
 | 
					 | 
				
			||||||
/dataSources/
 | 
					 | 
				
			||||||
/dataSources.local.xml
 | 
					 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/inspectionProfiles/profiles_settings.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/inspectionProfiles/profiles_settings.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
				
			|||||||
<component name="InspectionProjectProfileManager">
 | 
					 | 
				
			||||||
  <settings>
 | 
					 | 
				
			||||||
    <option name="USE_PROJECT_PROFILE" value="false" />
 | 
					 | 
				
			||||||
    <version value="1.0" />
 | 
					 | 
				
			||||||
  </settings>
 | 
					 | 
				
			||||||
</component>
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							@@ -1,4 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="ProjectModuleManager">
 | 
					 | 
				
			||||||
    <modules>
 | 
					 | 
				
			||||||
      <module fileurl="file://$PROJECT_DIR$/.idea/tcc.iml" filepath="$PROJECT_DIR$/.idea/tcc.iml" />
 | 
					 | 
				
			||||||
    </modules>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/tcc.iml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								.idea/tcc.iml
									
									
									
										generated
									
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<module type="PYTHON_MODULE" version="4">
 | 
					 | 
				
			||||||
  <component name="NewModuleRootManager">
 | 
					 | 
				
			||||||
    <content url="file://$MODULE_DIR$" />
 | 
					 | 
				
			||||||
    <orderEntry type="inheritedJdk" />
 | 
					 | 
				
			||||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</module>
 | 
					 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="VcsDirectoryMappings">
 | 
					 | 
				
			||||||
    <mapping directory="" vcs="Git" />
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
@@ -23,6 +23,7 @@ namespace TCC.Controllers
 | 
				
			|||||||
            mstream.Position = 0;
 | 
					            mstream.Position = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var result = ImageService.BoxBlurImage(mstream, radius);
 | 
					            var result = ImageService.BoxBlurImage(mstream, radius);
 | 
				
			||||||
 | 
					            mstream.Close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var blurredImageStream = new MemoryStream();
 | 
					            var blurredImageStream = new MemoryStream();
 | 
				
			||||||
            result.Write(blurredImageStream);
 | 
					            result.Write(blurredImageStream);
 | 
				
			||||||
@@ -31,28 +32,16 @@ namespace TCC.Controllers
 | 
				
			|||||||
            return File(blurredImageStream, "image/png");
 | 
					            return File(blurredImageStream, "image/png");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [HttpGet("load-image")]
 | 
					        [HttpGet("load-small-image")]
 | 
				
			||||||
        public async Task<IActionResult> GetSimpleImage()
 | 
					        public async Task<IActionResult> GetSimpleImage()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var result = ImageService.GetSimpleImage();
 | 
					            return File(ImageService.GetSimpleImage(), "image/png");
 | 
				
			||||||
 | 
					 | 
				
			||||||
            var imageStream = new MemoryStream();
 | 
					 | 
				
			||||||
            result.Write(imageStream);
 | 
					 | 
				
			||||||
            imageStream.Position = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return File(imageStream, "image/png");
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [HttpGet("load-big-image")]
 | 
					        [HttpGet("load-big-image")]
 | 
				
			||||||
        public async Task<IActionResult> GetBigImage()
 | 
					        public async Task<IActionResult> GetBigImage()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var result = ImageService.GetBigImage();
 | 
					            return File(ImageService.GetBigImage(), "image/png");
 | 
				
			||||||
 | 
					 | 
				
			||||||
            var imageStream = new MemoryStream();
 | 
					 | 
				
			||||||
            result.Write(imageStream);
 | 
					 | 
				
			||||||
            imageStream.Position = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return File(imageStream, "image/png");
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [HttpPost("save-big-image")]
 | 
					        [HttpPost("save-big-image")]
 | 
				
			||||||
@@ -61,6 +50,7 @@ namespace TCC.Controllers
 | 
				
			|||||||
            MemoryStream mstream = new MemoryStream();
 | 
					            MemoryStream mstream = new MemoryStream();
 | 
				
			||||||
            await HttpContext.Request.Body.CopyToAsync(mstream);
 | 
					            await HttpContext.Request.Body.CopyToAsync(mstream);
 | 
				
			||||||
            mstream.Position = 0;
 | 
					            mstream.Position = 0;
 | 
				
			||||||
 | 
					            mstream.Close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return Ok();
 | 
					            return Ok();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim AS build-env
 | 
				
			|||||||
WORKDIR /App
 | 
					WORKDIR /App
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Copy everything
 | 
					# Copy everything
 | 
				
			||||||
 | 
					RUN apt update && apt install wget -y
 | 
				
			||||||
COPY * .
 | 
					COPY * .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Restore as distinct layers
 | 
					# Restore as distinct layers
 | 
				
			||||||
@@ -10,15 +11,21 @@ RUN dotnet restore
 | 
				
			|||||||
# Build a release
 | 
					# Build a release
 | 
				
			||||||
RUN dotnet build -c Release -o out
 | 
					RUN dotnet build -c Release -o out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN cd out && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
 | 
				
			||||||
 | 
					    rm -rf runtimes && \
 | 
				
			||||||
 | 
					    mkdir -p ./static && \
 | 
				
			||||||
 | 
					    mv small-image.png ./static && \
 | 
				
			||||||
 | 
					    mv big-image.png ./static && \
 | 
				
			||||||
 | 
					    mv video.mp4 ./static
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build runtime image
 | 
					# Build runtime image
 | 
				
			||||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
 | 
					FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /App
 | 
					WORKDIR /App
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN wget https://files.ivanch.me/api/public/dl/QFCLgtrG/simpleimage.png && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/E0VLgWbx/bigimage.png && \
 | 
					 | 
				
			||||||
    rm -rf runtimes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY --from=build-env /App/out .
 | 
					COPY --from=build-env /App/out .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRYPOINT ["dotnet", "/App/TCC.APP.dll"]
 | 
					ENTRYPOINT ["dotnet", "/App/TCC.APP.dll"]
 | 
				
			||||||
@@ -4,13 +4,13 @@ namespace tcc_app
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public static class ImageHelper
 | 
					    public static class ImageHelper
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public static MagickImage SimpleImage;
 | 
					        public static byte[] SimpleImage;
 | 
				
			||||||
        public static MagickImage BigImage;
 | 
					        public static byte[] BigImage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static ImageHelper()
 | 
					        static ImageHelper()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            SimpleImage = new MagickImage("simpleimage.png");
 | 
					            SimpleImage = File.ReadAllBytes("static/small-image.png");
 | 
				
			||||||
            BigImage = new MagickImage("bigimage.png");
 | 
					            BigImage = File.ReadAllBytes("static/big-image.png");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
 | 
					using Microsoft.AspNetCore.Server.Kestrel.Core;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.FileProviders;
 | 
				
			||||||
using TCC.Services;
 | 
					using TCC.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace TCC
 | 
					namespace TCC
 | 
				
			||||||
@@ -18,9 +19,13 @@ namespace TCC
 | 
				
			|||||||
                options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
 | 
					                options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            var app = builder.Build();
 | 
					            var app = builder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            app.UseStaticFiles(new StaticFileOptions
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "static")),
 | 
				
			||||||
 | 
					                RequestPath = "/static"
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
            app.MapControllers();
 | 
					            app.MapControllers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            app.Run();
 | 
					            app.Run();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
      "dotnetRunMessages": true,
 | 
					      "dotnetRunMessages": true,
 | 
				
			||||||
      "launchBrowser": false,
 | 
					      "launchBrowser": false,
 | 
				
			||||||
      "launchUrl": "weatherforecast",
 | 
					      "launchUrl": "weatherforecast",
 | 
				
			||||||
      "applicationUrl": "http://0.0.0.0:5100",
 | 
					      "applicationUrl": "http://0.0.0.0:9090",
 | 
				
			||||||
      "environmentVariables": {
 | 
					      "environmentVariables": {
 | 
				
			||||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
					        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,14 +62,16 @@ namespace TCC.Services
 | 
				
			|||||||
            file.Close();
 | 
					            file.Close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public MagickImage GetSimpleImage()
 | 
					        public byte[] GetSimpleImage()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return ImageHelper.SimpleImage;
 | 
					            return File.ReadAllBytes("static/small-image.png");
 | 
				
			||||||
 | 
					            //return ImageHelper.SimpleImage;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public MagickImage GetBigImage()
 | 
					        public byte[] GetBigImage()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return ImageHelper.BigImage;
 | 
					            return File.ReadAllBytes("static/big-image.png");
 | 
				
			||||||
 | 
					            //return ImageHelper.BigImage;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								ASP.NET/static/nginx.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ASP.NET/static/nginx.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <title>Welcome to nginx!</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        html {
 | 
				
			||||||
 | 
					            color-scheme: light dark;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            width: 35em;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            font-family: Tahoma, Verdana, Arial, sans-serif;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <h1>Welcome to nginx!</h1>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        If you see this page, the nginx web server is successfully installed and
 | 
				
			||||||
 | 
					        working. Further configuration is required.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        For online documentation and support please refer to
 | 
				
			||||||
 | 
					        <a href="http://nginx.org/">nginx.org</a>.<br />
 | 
				
			||||||
 | 
					        Commercial support is available at
 | 
				
			||||||
 | 
					        <a href="http://nginx.com/">nginx.com</a>.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p><em>Thank you for using nginx.</em></p>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										1266
									
								
								ActixAPI/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1266
									
								
								ActixAPI/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								ActixAPI/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ActixAPI/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "ActixAPI"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					actix-web = "4"
 | 
				
			||||||
 | 
					actix-files = "0.6.2"
 | 
				
			||||||
							
								
								
									
										25
									
								
								ActixAPI/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ActixAPI/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					FROM rust:slim-bullseye AS build-env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt update && apt install wget -y && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/Dj0gkp-m/small-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/FqHEPM1Q/big-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/nTAYqZwD/video.mp4 && \
 | 
				
			||||||
 | 
					    mv small-image.png ./static && \
 | 
				
			||||||
 | 
					    mv big-image.png ./static && \
 | 
				
			||||||
 | 
					    mv video.mp4 ./static
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN cargo build --release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM debian:bullseye-slim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY --from=build-env /app/target/release .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY --from=build-env /app/static .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENTRYPOINT ["./ActixAPI"]
 | 
				
			||||||
							
								
								
									
										40
									
								
								ActixAPI/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								ActixAPI/src/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest, Result};
 | 
				
			||||||
 | 
					use actix_files::NamedFile;
 | 
				
			||||||
 | 
					use std::path::PathBuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/status/ok")]
 | 
				
			||||||
 | 
					async fn hello() -> impl Responder {
 | 
				
			||||||
 | 
					    HttpResponse::Ok().body("{\"status\": 200}")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[post("/echo")]
 | 
				
			||||||
 | 
					async fn echo(req_body: String) -> impl Responder {
 | 
				
			||||||
 | 
					    HttpResponse::Ok().body(req_body)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn manual_hello() -> impl Responder {
 | 
				
			||||||
 | 
					    HttpResponse::Ok().body("Hey there!")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn static_serve(req: HttpRequest) -> Result<NamedFile> {
 | 
				
			||||||
 | 
					    let path: &str = req.path();
 | 
				
			||||||
 | 
					    let real_path = &path[1..];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(NamedFile::open(real_path)?)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[actix_web::main]
 | 
				
			||||||
 | 
					async fn main() -> std::io::Result<()> {
 | 
				
			||||||
 | 
					    println!("Hello, world!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HttpServer::new(|| {
 | 
				
			||||||
 | 
					        App::new()
 | 
				
			||||||
 | 
					            .route("/static/{filename:.*}", web::get().to(static_serve))
 | 
				
			||||||
 | 
					            .service(hello)
 | 
				
			||||||
 | 
					            .service(echo)
 | 
				
			||||||
 | 
					            .route("/hey", web::get().to(manual_hello))
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .bind(("0.0.0.0", 9090))?
 | 
				
			||||||
 | 
					    .run()
 | 
				
			||||||
 | 
					    .await
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								ActixAPI/static/nginx.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ActixAPI/static/nginx.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <title>Welcome to nginx!</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        html {
 | 
				
			||||||
 | 
					            color-scheme: light dark;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            width: 35em;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            font-family: Tahoma, Verdana, Arial, sans-serif;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <h1>Welcome to nginx!</h1>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        If you see this page, the nginx web server is successfully installed and
 | 
				
			||||||
 | 
					        working. Further configuration is required.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        For online documentation and support please refer to
 | 
				
			||||||
 | 
					        <a href="http://nginx.org/">nginx.org</a>.<br />
 | 
				
			||||||
 | 
					        Commercial support is available at
 | 
				
			||||||
 | 
					        <a href="http://nginx.com/">nginx.com</a>.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p><em>Thank you for using nginx.</em></p>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@@ -1,34 +0,0 @@
 | 
				
			|||||||
# Include any files or directories that you don't want to be copied to your
 | 
					 | 
				
			||||||
# container here (e.g., local build artifacts, temporary files, etc.).
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# For more help, visit the .dockerignore file reference guide at
 | 
					 | 
				
			||||||
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**/.DS_Store
 | 
					 | 
				
			||||||
**/__pycache__
 | 
					 | 
				
			||||||
**/.venv
 | 
					 | 
				
			||||||
**/.classpath
 | 
					 | 
				
			||||||
**/.dockerignore
 | 
					 | 
				
			||||||
**/.env
 | 
					 | 
				
			||||||
**/.git
 | 
					 | 
				
			||||||
**/.gitignore
 | 
					 | 
				
			||||||
**/.project
 | 
					 | 
				
			||||||
**/.settings
 | 
					 | 
				
			||||||
**/.toolstarget
 | 
					 | 
				
			||||||
**/.vs
 | 
					 | 
				
			||||||
**/.vscode
 | 
					 | 
				
			||||||
**/*.*proj.user
 | 
					 | 
				
			||||||
**/*.dbmdl
 | 
					 | 
				
			||||||
**/*.jfm
 | 
					 | 
				
			||||||
**/bin
 | 
					 | 
				
			||||||
**/charts
 | 
					 | 
				
			||||||
**/docker-compose*
 | 
					 | 
				
			||||||
**/compose*
 | 
					 | 
				
			||||||
**/Dockerfile*
 | 
					 | 
				
			||||||
**/node_modules
 | 
					 | 
				
			||||||
**/npm-debug.log
 | 
					 | 
				
			||||||
**/obj
 | 
					 | 
				
			||||||
**/secrets.dev.yaml
 | 
					 | 
				
			||||||
**/values.dev.yaml
 | 
					 | 
				
			||||||
LICENSE
 | 
					 | 
				
			||||||
README.md
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								FlaskAPI/.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								FlaskAPI/.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
# Default ignored files
 | 
					 | 
				
			||||||
/shelf/
 | 
					 | 
				
			||||||
/workspace.xml
 | 
					 | 
				
			||||||
# Editor-based HTTP Client requests
 | 
					 | 
				
			||||||
/httpRequests/
 | 
					 | 
				
			||||||
# Datasource local storage ignored files
 | 
					 | 
				
			||||||
/dataSources/
 | 
					 | 
				
			||||||
/dataSources.local.xml
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								FlaskAPI/.idea/FlaskAPI.iml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								FlaskAPI/.idea/FlaskAPI.iml
									
									
									
										generated
									
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<module type="PYTHON_MODULE" version="4">
 | 
					 | 
				
			||||||
  <component name="Flask">
 | 
					 | 
				
			||||||
    <option name="enabled" value="true" />
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
  <component name="NewModuleRootManager">
 | 
					 | 
				
			||||||
    <content url="file://$MODULE_DIR$" />
 | 
					 | 
				
			||||||
    <orderEntry type="inheritedJdk" />
 | 
					 | 
				
			||||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
  <component name="TemplatesService">
 | 
					 | 
				
			||||||
    <option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
 | 
					 | 
				
			||||||
    <option name="TEMPLATE_FOLDERS">
 | 
					 | 
				
			||||||
      <list>
 | 
					 | 
				
			||||||
        <option value="$MODULE_DIR$/../FlaskAPI\templates" />
 | 
					 | 
				
			||||||
      </list>
 | 
					 | 
				
			||||||
    </option>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</module>
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
<component name="InspectionProjectProfileManager">
 | 
					 | 
				
			||||||
  <settings>
 | 
					 | 
				
			||||||
    <option name="USE_PROJECT_PROFILE" value="false" />
 | 
					 | 
				
			||||||
    <version value="1.0" />
 | 
					 | 
				
			||||||
  </settings>
 | 
					 | 
				
			||||||
</component>
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								FlaskAPI/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								FlaskAPI/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							@@ -1,4 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (FlaskAPI)" project-jdk-type="Python SDK" />
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								FlaskAPI/.idea/modules.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								FlaskAPI/.idea/modules.xml
									
									
									
										generated
									
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="ProjectModuleManager">
 | 
					 | 
				
			||||||
    <modules>
 | 
					 | 
				
			||||||
      <module fileurl="file://$PROJECT_DIR$/.idea/FlaskAPI.iml" filepath="$PROJECT_DIR$/.idea/FlaskAPI.iml" />
 | 
					 | 
				
			||||||
    </modules>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								FlaskAPI/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								FlaskAPI/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "version": "0.0.1",
 | 
					 | 
				
			||||||
  "configurations": [
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "name": "Python: Flask",
 | 
					 | 
				
			||||||
      "type": "python",
 | 
					 | 
				
			||||||
      "request": "launch",
 | 
					 | 
				
			||||||
      "module": "flask",
 | 
					 | 
				
			||||||
      "env": { "FLASK_APP": "app.py", "FLASK_DEBUG": "1" },
 | 
					 | 
				
			||||||
      "args": ["run", "--no-debugger", "--no-reload"],
 | 
					 | 
				
			||||||
      "jinja": true,
 | 
					 | 
				
			||||||
      "justMyCode": true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										0
									
								
								FlaskAPI/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								FlaskAPI/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -1,45 +0,0 @@
 | 
				
			|||||||
# syntax=docker/dockerfile:1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Comments are provided throughout this file to help you get started.
 | 
					 | 
				
			||||||
# If you need more help, visit the Dockerfile reference guide at
 | 
					 | 
				
			||||||
# https://docs.docker.com/engine/reference/builder/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ARG PYTHON_VERSION=3.10.12
 | 
					 | 
				
			||||||
FROM python:${PYTHON_VERSION}-slim as base
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Prevents Python from writing pyc files.
 | 
					 | 
				
			||||||
ENV PYTHONDONTWRITEBYTECODE=1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Keeps Python from buffering stdout and stderr to avoid situations where
 | 
					 | 
				
			||||||
# the application crashes without emitting any logs due to buffering.
 | 
					 | 
				
			||||||
ENV PYTHONUNBUFFERED=1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Copy the source code into the container.
 | 
					 | 
				
			||||||
COPY . .
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN apt-get update && apt-get install -y imagemagick && apt-get install -y wget && ls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
 | 
					 | 
				
			||||||
    rm -rf runtimes && \
 | 
					 | 
				
			||||||
    mkdir -p ./static && \
 | 
					 | 
				
			||||||
    mv small-image.png ./static && \
 | 
					 | 
				
			||||||
    mv big-image.png ./static && \
 | 
					 | 
				
			||||||
    mv video.mp4 ./static
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Download dependencies as a separate step to take advantage of Docker's caching.
 | 
					 | 
				
			||||||
# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds.
 | 
					 | 
				
			||||||
# Leverage a bind mount to requirements.txt to avoid having to copy them into
 | 
					 | 
				
			||||||
# into this layer.
 | 
					 | 
				
			||||||
RUN --mount=type=cache,target=/root/.cache/pip \
 | 
					 | 
				
			||||||
    --mount=type=bind,source=requirements.txt,target=requirements.txt \
 | 
					 | 
				
			||||||
    python -m pip install -r requirements.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Expose the port that the application listens on.
 | 
					 | 
				
			||||||
EXPOSE 5000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Run the application.
 | 
					 | 
				
			||||||
CMD gunicorn 'app:app' --bind=0.0.0.0:5000
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@@ -1,12 +0,0 @@
 | 
				
			|||||||
from flask import Flask
 | 
					 | 
				
			||||||
from controllers.status import status_blueprint
 | 
					 | 
				
			||||||
from controllers.image import image_blueprint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app = Flask(__name__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == '__main__':
 | 
					 | 
				
			||||||
    app.run()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
app.register_blueprint(status_blueprint)
 | 
					 | 
				
			||||||
app.register_blueprint(image_blueprint)
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 36 KiB  | 
@@ -1,49 +0,0 @@
 | 
				
			|||||||
# Comments are provided throughout this file to help you get started.
 | 
					 | 
				
			||||||
# If you need more help, visit the Docker compose reference guide at
 | 
					 | 
				
			||||||
# https://docs.docker.com/compose/compose-file/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Here the instructions define your application as a service called "server".
 | 
					 | 
				
			||||||
# This service is built from the Dockerfile in the current directory.
 | 
					 | 
				
			||||||
# You can add other services your application may depend on here, such as a
 | 
					 | 
				
			||||||
# database or a cache. For examples, see the Awesome Compose repository:
 | 
					 | 
				
			||||||
# https://github.com/docker/awesome-compose
 | 
					 | 
				
			||||||
services:
 | 
					 | 
				
			||||||
  server:
 | 
					 | 
				
			||||||
    build:
 | 
					 | 
				
			||||||
      context: .
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - 5000:5000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The commented out section below is an example of how to define a PostgreSQL
 | 
					 | 
				
			||||||
# database that your application can use. `depends_on` tells Docker Compose to
 | 
					 | 
				
			||||||
# start the database before your application. The `db-data` volume persists the
 | 
					 | 
				
			||||||
# database data between container restarts. The `db-password` secret is used
 | 
					 | 
				
			||||||
# to set the database password. You must create `db/password.txt` and add
 | 
					 | 
				
			||||||
# a password of your choosing to it before running `docker compose up`.
 | 
					 | 
				
			||||||
#     depends_on:
 | 
					 | 
				
			||||||
#       db:
 | 
					 | 
				
			||||||
#         condition: service_healthy
 | 
					 | 
				
			||||||
#   db:
 | 
					 | 
				
			||||||
#     image: postgres
 | 
					 | 
				
			||||||
#     restart: always
 | 
					 | 
				
			||||||
#     user: postgres
 | 
					 | 
				
			||||||
#     secrets:
 | 
					 | 
				
			||||||
#       - db-password
 | 
					 | 
				
			||||||
#     volumes:
 | 
					 | 
				
			||||||
#       - db-data:/var/lib/postgresql/data
 | 
					 | 
				
			||||||
#     environment:
 | 
					 | 
				
			||||||
#       - POSTGRES_DB=example
 | 
					 | 
				
			||||||
#       - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
 | 
					 | 
				
			||||||
#     expose:
 | 
					 | 
				
			||||||
#       - 5432
 | 
					 | 
				
			||||||
#     healthcheck:
 | 
					 | 
				
			||||||
#       test: [ "CMD", "pg_isready" ]
 | 
					 | 
				
			||||||
#       interval: 10s
 | 
					 | 
				
			||||||
#       timeout: 5s
 | 
					 | 
				
			||||||
#       retries: 5
 | 
					 | 
				
			||||||
# volumes:
 | 
					 | 
				
			||||||
#   db-data:
 | 
					 | 
				
			||||||
# secrets:
 | 
					 | 
				
			||||||
#   db-password:
 | 
					 | 
				
			||||||
#     file: db/password.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1,41 +0,0 @@
 | 
				
			|||||||
from services.image import ImageService
 | 
					 | 
				
			||||||
from static.image_helper import ImageHelper
 | 
					 | 
				
			||||||
from flask import request, Response, Blueprint, jsonify, send_file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
image_blueprint = Blueprint('image_blueprint', __name__)
 | 
					 | 
				
			||||||
image_service = ImageService()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@image_blueprint.route('/image/blur', methods=['POST'])
 | 
					 | 
				
			||||||
def blur_image():
 | 
					 | 
				
			||||||
    radius = int(request.form.get('radius'))
 | 
					 | 
				
			||||||
    image = request.files.get('file')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if radius and image:
 | 
					 | 
				
			||||||
        return send_file(image_service.box_blur_image(image, radius),
 | 
					 | 
				
			||||||
                         mimetype='image/jpeg',
 | 
					 | 
				
			||||||
                         as_attachment=True,
 | 
					 | 
				
			||||||
                         download_name='blurred_image.jpeg')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return "Bad request", 400
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@image_blueprint.route('/image/load-small-image', methods=['GET'])
 | 
					 | 
				
			||||||
def get_simple_image():
 | 
					 | 
				
			||||||
    return send_file(image_service.get_simple_image(),
 | 
					 | 
				
			||||||
                     mimetype='image/png',
 | 
					 | 
				
			||||||
                     as_attachment=True,
 | 
					 | 
				
			||||||
                     download_name='small-image.png')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@image_blueprint.route('/image/load-big-image', methods=['GET'])
 | 
					 | 
				
			||||||
def get_big_image():
 | 
					 | 
				
			||||||
    return send_file(image_service.get_big_image(),
 | 
					 | 
				
			||||||
                     mimetype='image/png',
 | 
					 | 
				
			||||||
                     as_attachment=True,
 | 
					 | 
				
			||||||
                     download_name='big-image.png')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@image_blueprint.route('/image/save-big-image', methods=['POST'])
 | 
					 | 
				
			||||||
def save_image():
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
from flask import jsonify, Blueprint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
status_blueprint = Blueprint('status_blueprint', __name__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class StatusController:
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def return_ok(self):
 | 
					 | 
				
			||||||
        return jsonify(status=200)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
status_controller = StatusController()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@status_blueprint.route('/status/ok', methods=['GET'])
 | 
					 | 
				
			||||||
def return_ok():
 | 
					 | 
				
			||||||
    return jsonify(status=200)
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
Flask>=1.0
 | 
					 | 
				
			||||||
gunicorn>=19.9.0
 | 
					 | 
				
			||||||
Wand
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@@ -1,69 +0,0 @@
 | 
				
			|||||||
from wand.image import Image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from static.image_helper import ImageHelper
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def box_blur_image_separable(image, blurred_image, radius_x, radius_y):
 | 
					 | 
				
			||||||
    pixels = image.get_pixels()
 | 
					 | 
				
			||||||
    blurred_pixels = blurred_image.get_pixels()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for pixel in pixels:
 | 
					 | 
				
			||||||
        x, y = pixel[0], pixel[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        r_total, g_total, b_total = 0, 0, 0
 | 
					 | 
				
			||||||
        pixel_count = 0
 | 
					 | 
				
			||||||
        for offset_y in range(-radius_y, radius_y + 1):
 | 
					 | 
				
			||||||
            for offset_x in range(-radius_x, radius_x + 1):
 | 
					 | 
				
			||||||
                new_x = x + offset_x
 | 
					 | 
				
			||||||
                new_y = y + offset_y
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if 0 <= new_x < image.width and 0 <= new_y < image.height:
 | 
					 | 
				
			||||||
                    pixel_color = pixels[new_y * image.width + new_x]
 | 
					 | 
				
			||||||
                    r_total += pixel_color.red
 | 
					 | 
				
			||||||
                    g_total += pixel_color.green
 | 
					 | 
				
			||||||
                    b_total += pixel_color.blue
 | 
					 | 
				
			||||||
                    pixel_count += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        blurred_pixel = blurred_pixels[y * image.width + x]
 | 
					 | 
				
			||||||
        blurred_pixel.red = int(r_total / pixel_count)
 | 
					 | 
				
			||||||
        blurred_pixel.green = int(g_total / pixel_count)
 | 
					 | 
				
			||||||
        blurred_pixel.blue = int(b_total / pixel_count)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return blurred_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def save_image(file_stream):
 | 
					 | 
				
			||||||
    with open("image.png", "wb") as file:
 | 
					 | 
				
			||||||
        file.write(file_stream.read())
 | 
					 | 
				
			||||||
        file.close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ImageService:
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def box_blur_image(self, img, radius):
 | 
					 | 
				
			||||||
        temp_path = 'temp_image.png'
 | 
					 | 
				
			||||||
        img.save(temp_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with Image(filename=temp_path) as img:
 | 
					 | 
				
			||||||
            img.blur(radius, 2)
 | 
					 | 
				
			||||||
            blurred_temp_path = 'blurred_temp_image.png'
 | 
					 | 
				
			||||||
            img.save(filename='blurred_temp_image.png')
 | 
					 | 
				
			||||||
            return blurred_temp_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_simple_image(self):
 | 
					 | 
				
			||||||
        with ImageHelper.SimpleImage as img:
 | 
					 | 
				
			||||||
            img = ImageHelper.SimpleImage
 | 
					 | 
				
			||||||
            simple_image = 'simple_image.png'
 | 
					 | 
				
			||||||
            img.save(filename='simple_image.png')
 | 
					 | 
				
			||||||
            return simple_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_big_image(self):
 | 
					 | 
				
			||||||
        with ImageHelper.BigImage as img:
 | 
					 | 
				
			||||||
            img = ImageHelper.BigImage
 | 
					 | 
				
			||||||
            big_image = 'big_image.png'
 | 
					 | 
				
			||||||
            img.save(filename='big_image.png')
 | 
					 | 
				
			||||||
            return big_image
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
from wand.image import Image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ImageHelper:
 | 
					 | 
				
			||||||
    SimpleImage = None
 | 
					 | 
				
			||||||
    BigImage = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @staticmethod
 | 
					 | 
				
			||||||
    def load_images():
 | 
					 | 
				
			||||||
        ImageHelper.SimpleImage = Image(filename="./static/small-image.png")
 | 
					 | 
				
			||||||
        #ImageHelper.SimpleImage.save(filename="./static/small-image.png")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ImageHelper.BigImage = Image(filename="./static/big-image.png")
 | 
					 | 
				
			||||||
        #ImageHelper.BigImage.save(filename="./static/big-image.png")
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ImageHelper.load_images()
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 44 KiB  | 
							
								
								
									
										89
									
								
								scripts/graph.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								scripts/graph.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					import matplotlib.pyplot as plt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def plot_graph(x, y, title, x_label, y_label, filename):
 | 
				
			||||||
 | 
					    plt.plot(x, y, 'ro', markersize=1, linewidth=0.5, linestyle='solid')
 | 
				
			||||||
 | 
					    plt.title(title)
 | 
				
			||||||
 | 
					    plt.xlabel(x_label)
 | 
				
			||||||
 | 
					    plt.ylabel(y_label)
 | 
				
			||||||
 | 
					    plt.savefig(f'{filename}.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    plt.clf()
 | 
				
			||||||
 | 
					    plt.close('all')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def plot_resource_graph(x_data, y_data, title, x_label, y_label, filename):
 | 
				
			||||||
 | 
					    requests = x_data
 | 
				
			||||||
 | 
					    resource = {
 | 
				
			||||||
 | 
					        'CPU': [p[0] for p in y_data],
 | 
				
			||||||
 | 
					        'RAM': [p[1] for p in y_data],
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = np.arange(len(requests))
 | 
				
			||||||
 | 
					    width = 0.25
 | 
				
			||||||
 | 
					    multiplier = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fig, ax = plt.subplots(layout='constrained')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for attribute, measurement in resource.items():
 | 
				
			||||||
 | 
					        offset = width * multiplier
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rects = ax.bar(x + offset, measurement, width, label=attribute)
 | 
				
			||||||
 | 
					        ax.bar_label(rects, padding=3)
 | 
				
			||||||
 | 
					        multiplier += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Add some text for labels, title and custom x-axis tick labels, etc.
 | 
				
			||||||
 | 
					    ax.set_xlabel(x_label)
 | 
				
			||||||
 | 
					    ax.set_ylabel(y_label)
 | 
				
			||||||
 | 
					    ax.set_title(title)
 | 
				
			||||||
 | 
					    ax.set_xticks(x + (width/2), requests)
 | 
				
			||||||
 | 
					    ax.legend(loc='upper left', ncols=len(resource.items()))
 | 
				
			||||||
 | 
					    ax.set_ylim(0, 100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    plt.savefig(f'{filename}.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    plt.clf()
 | 
				
			||||||
 | 
					    plt.close('all')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_data(filename):
 | 
				
			||||||
 | 
					    lines = []
 | 
				
			||||||
 | 
					    with open(filename, 'r') as f:
 | 
				
			||||||
 | 
					        lines = f.readlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = []
 | 
				
			||||||
 | 
					    y = []
 | 
				
			||||||
 | 
					    for line in lines:
 | 
				
			||||||
 | 
					        line = line.strip().split(',')
 | 
				
			||||||
 | 
					        if line:
 | 
				
			||||||
 | 
					            x.append(int(line[0]))
 | 
				
			||||||
 | 
					            y.append(float(line[1]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_resource_data(filename):
 | 
				
			||||||
 | 
					    lines = []
 | 
				
			||||||
 | 
					    with open(filename, 'r') as f:
 | 
				
			||||||
 | 
					        lines = f.readlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = []
 | 
				
			||||||
 | 
					    y = []
 | 
				
			||||||
 | 
					    for line in lines:
 | 
				
			||||||
 | 
					        line = line.strip().split(',')
 | 
				
			||||||
 | 
					        if line:
 | 
				
			||||||
 | 
					            x.append(int(line[0])) # requests
 | 
				
			||||||
 | 
					            y.append([float(v)*100 for v in line[1:]]) # cpu, ram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate_req_graph(filename, framework_name, endpoint_name):
 | 
				
			||||||
 | 
					    x, y = get_data(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    filename = filename.split('/')[-1]
 | 
				
			||||||
 | 
					    new_filename = filename.replace('.csv', '')
 | 
				
			||||||
 | 
					    plot_graph(x, y, f'{framework_name} - {endpoint_name}', 'Número de requisições', 'Requisições por segundo', new_filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate_resource_graph(filename, framework_name, endpoint_name):
 | 
				
			||||||
 | 
					    x, y = get_resource_data(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    filename = filename.split('/')[-1]
 | 
				
			||||||
 | 
					    new_filename = filename.replace('.csv', '')
 | 
				
			||||||
 | 
					    plot_resource_graph(x, y, f'{framework_name} - {endpoint_name}', 'Uso de recursos', 'Uso (%)', new_filename)
 | 
				
			||||||
							
								
								
									
										17
									
								
								scripts/init.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								scripts/init.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def download_file(url):
 | 
				
			||||||
 | 
					    local_filename = url.split('/')[-1]
 | 
				
			||||||
 | 
					    with requests.get(url, stream=True) as r:
 | 
				
			||||||
 | 
					        r.raise_for_status()
 | 
				
			||||||
 | 
					        with open(local_filename, 'wb') as f:
 | 
				
			||||||
 | 
					            for chunk in r.iter_content(chunk_size=8192):
 | 
				
			||||||
 | 
					                # If you have chunk encoded response uncomment if
 | 
				
			||||||
 | 
					                # and set chunk_size parameter to None.
 | 
				
			||||||
 | 
					                #if chunk:
 | 
				
			||||||
 | 
					                f.write(chunk)
 | 
				
			||||||
 | 
					    return local_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def init():
 | 
				
			||||||
 | 
					    download_file('https://files.ivanch.me/api/public/dl/Dj0gkp-m/small-image.png')
 | 
				
			||||||
 | 
					    download_file('https://files.ivanch.me/api/public/dl/FqHEPM1Q/big-image.png')
 | 
				
			||||||
@@ -1,33 +1,155 @@
 | 
				
			|||||||
import requests
 | 
					import requests
 | 
				
			||||||
 | 
					import docker
 | 
				
			||||||
import concurrent.futures
 | 
					import concurrent.futures
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					from graph import generate_req_graph, generate_resource_graph
 | 
				
			||||||
 | 
					from math import floor
 | 
				
			||||||
 | 
					from init import init
 | 
				
			||||||
 | 
					
 | 
				
			||||||
URL_BASE = 'http://localhost:5100'
 | 
					if len(sys.argv) < 2 or len(sys.argv) > 3 or sys.argv[1] == '-h' or sys.argv[1] == '--help':
 | 
				
			||||||
 | 
					    print("Usage: python testes.py <framework name> [container name]")
 | 
				
			||||||
 | 
					    sys.exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
num_requests = [1000, 5000, 10_000, 50_000, 100_000, 500_000, 1_000_000]
 | 
					init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def send_request(session, url):
 | 
					THREADS = 10
 | 
				
			||||||
    response = session.get(url)
 | 
					FRAMEWORK_NAME = sys.argv[1]
 | 
				
			||||||
    return response.status_code
 | 
					CONTAINER_NAME = sys.argv[2] if len(sys.argv) > 2 else ""
 | 
				
			||||||
 | 
					URL_BASE = 'http://localhost:9090'
 | 
				
			||||||
 | 
					BLUR_RADIUS = 5
 | 
				
			||||||
 | 
					API_REQUESTS = [
 | 
				
			||||||
 | 
					    ('/image/save-big-image', 'POST', range(0, 10_000, 1_000), open('big-image.png', 'rb').read()),
 | 
				
			||||||
 | 
					    (f'/image/blur?radius={BLUR_RADIUS}', 'POST', range(0, 1_000, 50), open('small-image.png', 'rb').read()),
 | 
				
			||||||
 | 
					    ('/status/ok', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
 | 
					    ('/image/load-small-image', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
 | 
					    ('/static/small-image.png', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
 | 
					    ('/image/load-big-image', 'GET', range(0, 500, 50), None),
 | 
				
			||||||
 | 
					    ('/static/big-image.png', 'GET', range(0, 500, 50), None),
 | 
				
			||||||
 | 
					    ('/static/video.mp4', 'GET', range(0, 10_000, 1_000), None),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def send_request(url, method = 'GET', payload = None):
 | 
				
			||||||
 | 
					    success = False
 | 
				
			||||||
 | 
					    responses = {
 | 
				
			||||||
 | 
					        2: 0, # OK
 | 
				
			||||||
 | 
					        4: 0, # Bad Request
 | 
				
			||||||
 | 
					        5: 0, # Server Error
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    while not success:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            response = None
 | 
				
			||||||
 | 
					            if method == 'GET':
 | 
				
			||||||
 | 
					                response = requests.get(url)
 | 
				
			||||||
 | 
					            elif method == 'POST':
 | 
				
			||||||
 | 
					                response = requests.post(url, data=payload, headers={'Content-Type': 'image/png'})
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        success = response.status_code == 200
 | 
				
			||||||
 | 
					        responses[floor(response.status_code/100)] += 1
 | 
				
			||||||
 | 
					    return responses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def getFileNames(endpoint):
 | 
				
			||||||
 | 
					    endpoint = endpoint.replace('/', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    files = [
 | 
				
			||||||
 | 
					        f"data/req_{FRAMEWORK_NAME}_{endpoint}.csv",
 | 
				
			||||||
 | 
					        f"data/resource_{FRAMEWORK_NAME}_{endpoint}.csv",
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def record(filename, requests, reqpersec):
 | 
				
			||||||
 | 
					    with open(filename, "a") as file:
 | 
				
			||||||
 | 
					        file.write(f"{requests},{reqpersec}\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def record_resource(filename, requests, cpu, ram):
 | 
				
			||||||
 | 
					    with open(filename, "a") as file:
 | 
				
			||||||
 | 
					        file.write(f"{requests},{cpu},{ram}\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_tests(endpoint, method, num_requests, metadata):
 | 
				
			||||||
 | 
					    files = getFileNames(endpoint)
 | 
				
			||||||
 | 
					    for filename in files:
 | 
				
			||||||
 | 
					        if os.path.exists(filename):
 | 
				
			||||||
 | 
					            os.remove(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					 | 
				
			||||||
    for num_request in num_requests:
 | 
					    for num_request in num_requests:
 | 
				
			||||||
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
 | 
					        if num_request <= 0: continue
 | 
				
			||||||
            url = f'{URL_BASE}/status/ok'
 | 
					
 | 
				
			||||||
 | 
					        ok_responses = 0
 | 
				
			||||||
 | 
					        bad_responses = 0
 | 
				
			||||||
 | 
					        server_errors = 0
 | 
				
			||||||
 | 
					        cpu, ram = 0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor:
 | 
				
			||||||
 | 
					            url = f'{URL_BASE}{endpoint}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            start_time = time.time()
 | 
					            start_time = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            futures = []
 | 
					            futures = []
 | 
				
			||||||
            with requests.Session() as session:
 | 
					            #with requests.Session() as session:
 | 
				
			||||||
                futures = [executor.submit(send_request, session, url) for _ in range(num_request)]
 | 
					            #    futures = [executor.submit(send_request, session, url) for _ in range(num_request)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            half = floor(num_request/2)
 | 
				
			||||||
 | 
					            for i in range(num_request):
 | 
				
			||||||
 | 
					                futures.append(executor.submit(send_request, url, method, metadata))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if i == half:
 | 
				
			||||||
 | 
					                    cpu, ram = get_resource_usage()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            concurrent.futures.wait(futures)
 | 
					            concurrent.futures.wait(futures)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            elapsed_time = time.time() - start_time
 | 
					            elapsed_time = time.time() - start_time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            successful_responses = sum(1 for future in futures if future.result() == 200)
 | 
					            for future in futures:
 | 
				
			||||||
 | 
					                responses = future.result()
 | 
				
			||||||
 | 
					                ok_responses += responses[2]
 | 
				
			||||||
 | 
					                bad_responses += responses[4]
 | 
				
			||||||
 | 
					                server_errors += responses[5]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(f"All requests completed in {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second.")
 | 
					        print(f"{num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second. [OK: {ok_responses}, Bad Request: {bad_responses}, Server Error: {server_errors}]]")
 | 
				
			||||||
        print(f"Successful responses: {successful_responses}/{num_request}")
 | 
					        record(files[0], num_request, f"{num_request/elapsed_time:.2f}")
 | 
				
			||||||
 | 
					        record_resource(files[1], num_request, cpu, ram)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main()
 | 
					        generate_req_graph(files[0], FRAMEWORK_NAME, endpoint)
 | 
				
			||||||
 | 
					        generate_resource_graph(files[1], FRAMEWORK_NAME, endpoint)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        time.sleep(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_resource_usage():
 | 
				
			||||||
 | 
					    if CONTAINER_NAME == "": return 0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        client = docker.from_env()
 | 
				
			||||||
 | 
					        stats = client.containers.get(CONTAINER_NAME).stats(stream=False)
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        return 0, 0 # unable to get stats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return get_cpu_usage(stats), get_ram_usage(stats)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_cpu_usage(stats):
 | 
				
			||||||
 | 
					    UsageDelta = stats['cpu_stats']['cpu_usage']['total_usage'] - stats['precpu_stats']['cpu_usage']['total_usage']
 | 
				
			||||||
 | 
					    SystemDelta = stats['cpu_stats']['system_cpu_usage'] - stats['precpu_stats']['system_cpu_usage']
 | 
				
			||||||
 | 
					    len_cpu = stats['cpu_stats']['online_cpus']
 | 
				
			||||||
 | 
					    percentage = (UsageDelta / SystemDelta) * len_cpu
 | 
				
			||||||
 | 
					    return f"{percentage:.2f}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_ram_usage(stats):
 | 
				
			||||||
 | 
					    usage = stats['memory_stats']['usage']
 | 
				
			||||||
 | 
					    limit = stats['memory_stats']['limit']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    percentage = (usage / limit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # percent = round(percentage, 2)
 | 
				
			||||||
 | 
					    return f"{percentage:.2f}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    if not os.path.exists("data"):
 | 
				
			||||||
 | 
					        os.mkdir("data")
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        os.system("rm -rf data/*")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for endpoint, method, num_requests, metadata in API_REQUESTS:
 | 
				
			||||||
 | 
					        print(f"# {endpoint}")
 | 
				
			||||||
 | 
					        run_tests(endpoint, method, num_requests, metadata)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user