Skip to content

Commit d225403

Browse files
Merge pull request #80 from miguelgfierro/fastapi
Fastapi
2 parents 26cab46 + 47cbc43 commit d225403

File tree

6 files changed

+101
-43
lines changed

6 files changed

+101
-43
lines changed

.github/workflows/pr_gate.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ jobs:
4848
fail-fast: false
4949
max-parallel: 20 # Usage limits: https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration
5050
matrix:
51-
os: [macos-latest, ubuntu-20.04, ubuntu-22.04] # Available images: https://github.com/actions/runner-images/#available-images
52-
python: ["3.7", "3.8", "3.9", "3.10"]
51+
os: [ubuntu-22.04, ubuntu-24.04] # Available images: https://github.com/actions/runner-images/#available-images
52+
python: ["3.8", "3.9", "3.10", "3.11"]
5353
steps:
5454
- name: Checkout
5555
uses: actions/checkout@v3 # Info: https://github.com/actions/checkout

api/fastapi_pydantic.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from fastapi import FastAPI
2+
from pydantic import BaseModel, EmailStr
3+
from typing import Optional
4+
5+
# Run the app with: uvicorn fastapi_pydantic:app --reload
6+
7+
# Initialize FastAPI app
8+
app = FastAPI()
9+
10+
11+
# Define a Pydantic model for user data
12+
class User(BaseModel):
13+
name: str
14+
email: EmailStr
15+
age: Optional[int] = None # Optional field with default None
16+
is_active: bool = True # Default value
17+
18+
19+
# Create an API endpoint to receive and validate user data
20+
@app.post("/users/")
21+
async def create_user(user: User):
22+
"""
23+
Pydantic automatically validates the input data
24+
and raises an error if the data does not conform to the User model.
25+
26+
Examples:
27+
>>> from fastapi.testclient import TestClient
28+
>>> from pybase.api.fastapi_pydantic import app
29+
>>> client = TestClient(app)
30+
>>> resp = client.post("/users/", json={"name":"Joe","email":"joe@example.com"})
31+
>>> resp.status_code
32+
200
33+
>>> resp.json()["user_data"]["name"]
34+
'Joe'
35+
"""
36+
return {"message": "User created successfully", "user_data": user.model_dump()}

image_base/video_utils.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import os
22
import cv2
3-
from moviepy.video.io.ffmpeg_tools import (
4-
ffmpeg_extract_subclip,
5-
ffmpeg_movie_from_frames,
6-
)
3+
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
4+
from moviepy.video.io.ImageSequenceClip import ImageSequenceClip
75

86

97
def cut_video(input_file, start_time, end_time, output_file):
@@ -87,4 +85,9 @@ def video_from_frames_ffmpeg(filename, folder, fps=25, **kwargs):
8785
raise TypeError(
8886
"Unexpected keyword argument passed to optimizer: " + str(k)
8987
)
90-
ffmpeg_movie_from_frames(filename, folder, fps, kwargs)
88+
# Use ImageSequenceClip to assemble frames into a video
89+
images = sorted(os.listdir(folder))
90+
paths = [os.path.join(folder, img) for img in images]
91+
clip = ImageSequenceClip(paths, fps=fps)
92+
output_path = os.path.join(folder, filename)
93+
clip.write_videofile(output_path, bitrate=kwargs.get("bitrate", None))

requirements.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
numpy>=1.19
1+
numpy>=1.19,<2
22
memory_profiler>=0.47
3-
pandas>1.0.3,<2
3+
pandas>=1.5,<2
44
scikit-image>=0.14.2
55
scikit-learn>=0.22.1
66
scipy>=0.19.0
@@ -13,7 +13,7 @@ beautifulsoup4>=4.6.0
1313
cherrypy>=12.0.1
1414
paste>=2.0.3
1515
fastparquet>=0.1.4
16-
dask>=0.17.1
16+
dask[dataframe]>=0.17.1,<3
1717
pillow>=4.3.0
1818
sqlalchemy>=1.2.4,<2
1919
gitpython>=2.1.8
@@ -38,4 +38,8 @@ moviepy>=1.0.1
3838
numba>=0.38.1,<1
3939
pyodbc>=4.0.21
4040
mlflow>=1.14.0
41-
notebook>=6.4.12,<7.1.0
41+
notebook>=6.4.12,<7.1.0
42+
fastapi>=0.100.0,<1
43+
pydantic>=2.5.0,<3
44+
email-validator>=1.2.0
45+
httpx>=0.23.0

system/memory.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ def _manage_memory_units(data_in_bytes, units):
1717

1818
def get_object_size(obj, units="Mb"):
1919
"""Calculate the size of an object.
20-
20+
2121
Args:
2222
obj (obj or str or array): Object.
2323
units (str): Units [bytes, Kb, Mb, Gb]
24-
24+
2525
Returns:
2626
float: Size of the object.
27-
27+
2828
Examples:
2929
>>> get_object_size(7, "bytes")
3030
28
@@ -41,30 +41,31 @@ def get_pandas_df_size(obj, units="Mb"):
4141
Args:
4242
obj (pd.DataFrame): Dataframe.
4343
units (str): Units [bytes, Kb, Mb, Gb]
44-
44+
4545
Returns:
4646
float: Size of the object.
47-
47+
4848
Examples:
49-
>>> df = pd.DataFrame({"a":[1]*100, "b":[0.5]*100})
50-
>>> get_pandas_df_size(df, "Kb")
51-
1.6875
49+
>>> import pandas as pd
50+
>>> df = pd.DataFrame({"a":[1]*100, "b":[0.5]*100})
51+
>>> get_pandas_df_size(df, "Kb") # doctest: +ELLIPSIS
52+
1.6...
5253
"""
53-
obj_bytes = obj.memory_usage(deep=True).sum()
54+
obj_bytes = obj.memory_usage(deep=False).sum()
5455
return _manage_memory_units(obj_bytes, units)
5556

5657

5758
def get_ram_memory(units="Mb"):
5859
"""Get the RAM memory of the current machine.
59-
60+
6061
Args:
6162
units (str): Units [bytes, Kb, Mb, Gb]
62-
63+
6364
Returns:
6465
float: Memory size.
65-
66+
6667
Examples:
67-
>>> num = get_ram_memory("Gb")
68+
>>> num = get_ram_memory("Gb")
6869
>>> num >= 2
6970
True
7071
"""
@@ -74,82 +75,88 @@ def get_ram_memory(units="Mb"):
7475

7576
def get_total_gpu_memory(units="Mb"):
7677
"""Get the memory of the GPUs in the system
77-
78+
7879
Returns:
7980
list: List of strings with the GPU memory in Mb
80-
81+
8182
Examples:
8283
>>> get_total_gpu_memory() #doctest: +SKIP
8384
[16280.875]
8485
"""
8586
try:
8687
import numba
88+
8789
memory_list = []
8890
for gpu in numba.cuda.gpus:
8991
with gpu:
9092
meminfo = numba.cuda.current_context().get_memory_info()
9193
memory_list.append(_manage_memory_units(meminfo[1], units))
9294
return memory_list
93-
except Exception: #numba.cuda.cudadrv.error.CudaSupportError:
95+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
9496
return []
9597

9698

9799
def get_free_gpu_memory(units="Mb"):
98100
"""Get the memory of the GPUs in the system
99-
101+
100102
Returns:
101103
list: List of strings with the GPU memory in Mb
102-
104+
103105
Examples:
104106
>>> get_free_gpu_memory() #doctest: +SKIP
105107
[15987.8125]
106108
107109
"""
108110
try:
109111
import numba
112+
110113
memory_list = []
111114
for gpu in numba.cuda.gpus:
112115
with gpu:
113116
meminfo = numba.cuda.current_context().get_memory_info()
114117
memory_list.append(_manage_memory_units(meminfo[0], units))
115118
return memory_list
116-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
119+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
117120
return []
118121

119122

120123
def clear_memory_all_gpus():
121124
"""Clear memory of all GPUs.
122-
125+
123126
Examples:
124127
>>> clear_memory_all_gpus() #doctest: +SKIP
125128
No CUDA available
126129
127130
"""
128131
try:
129132
import numba
133+
130134
for gpu in numba.cuda.gpus:
131135
with gpu:
132136
numba.cuda.current_context().deallocations.clear()
133-
except Exception: # numba.cuda.cudadrv.errorCudaSupportError:
137+
except Exception: # numba.cuda.cudadrv.errorCudaSupportError:
134138
print("No CUDA available")
135139

136140

137141
def clear_memory_gpu_id(id):
138142
"""Clear memory of all GPUs.
139-
143+
140144
Args:
141145
id (int): GPU id.
142-
146+
143147
Examples:
144148
>>> clear_memory_gpu_id(0) #doctest: +SKIP
145149
No CUDA available
146150
"""
147151
try:
148152
import numba
153+
149154
for gpu in numba.cuda.gpus:
150155
numba.cuda.select_device(gpu.id)
151156
numba.cuda.close()
152-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
157+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
153158
print("No CUDA available")
154159
except IndexError:
155-
raise ValueError("GPU id should be between 0 and {}".format(len(numba.cuda.gpus) - 1))
160+
raise ValueError(
161+
"GPU id should be between 0 and {}".format(len(numba.cuda.gpus) - 1)
162+
)

system/system_info.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ def get_library_version(library_name):
6868
str: Version of the library.
6969
7070
Examples:
71-
>>> get_library_version("pandas") #doctest: +ELLIPSIS
72-
'1...'
71+
>>> get_library_version("fastapi") #doctest: +ELLIPSIS
72+
'0...'
7373
7474
"""
7575
try:
@@ -170,8 +170,9 @@ def get_gpu_name():
170170
"""
171171
try:
172172
import numba
173+
173174
return [gpu.name.decode("utf-8") for gpu in numba.cuda.gpus]
174-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
175+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
175176
return []
176177

177178

@@ -188,13 +189,15 @@ def get_number_gpus():
188189
"""
189190
try:
190191
import torch
192+
191193
return torch.cuda.device_count()
192194
except (ImportError, ModuleNotFoundError):
193195
pass
194196
try:
195197
import numba
198+
196199
return len(numba.cuda.gpus)
197-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
200+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
198201
return 0
199202

200203

@@ -211,8 +214,9 @@ def get_gpu_compute_capability():
211214
"""
212215
try:
213216
import numba
217+
214218
return [gpu.compute_capability for gpu in numba.cuda.gpus]
215-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
219+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
216220
return []
217221

218222

@@ -225,6 +229,7 @@ def get_cuda_version():
225229
"""
226230
try:
227231
import torch
232+
228233
return torch.version.cuda
229234
except (ImportError, ModuleNotFoundError):
230235
path = ""
@@ -277,9 +282,10 @@ def find_cudnn_in_headers(candiates):
277282
return "Cannot find CUDNN version"
278283
else:
279284
return "Cannot find CUDNN version"
280-
285+
281286
try:
282287
import torch
288+
283289
return torch.backends.cudnn.version()
284290
except (ImportError, ModuleNotFoundError):
285291
if sys.platform == "win32":
@@ -316,13 +322,15 @@ def is_cuda_available():
316322
"""
317323
try:
318324
import torch
325+
319326
return torch.cuda.is_available()
320327
except (ImportError, ModuleNotFoundError):
321328
pass
322329
try:
323330
import numba
331+
324332
return len(numba.cuda.gpus)
325-
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
333+
except Exception: # numba.cuda.cudadrv.error.CudaSupportError:
326334
return False
327335

328336

0 commit comments

Comments
 (0)