Skip to content

Commit 84129fc

Browse files
committed
feat: Implement smt plugin and operations
1 parent f2ad2da commit 84129fc

13 files changed

+93
-86
lines changed

.prospector.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pylint:
66
disable:
77
- super-init-not-called
88
- unsubscriptable-object
9-
- dangerous-default-value
9+
- too-many-arguments
1010

1111
mccabe:
1212
run: true

app/apis/pypi_service.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,17 @@ async def requires_packages(pkg_name: str, version_dist: str) -> dict[str, dict[
4545
).json()['info']['requires_dist']
4646

4747
if response:
48-
require_packages = {}
48+
require_packages: dict[str, Any] = {}
4949

5050
for dist in response:
5151
data = dist.split(';')
5252

53-
'''
54-
TODO: En el futuro sería interesante construir el grado teniendo en cuenta los extras
55-
'''
53+
# TODO: En el futuro sería interesante construir el grado teniendo en cuenta los extras
5654
if len(data) > 1:
5755
if 'extra' in data[1]:
5856
continue
5957

60-
'''
61-
TODO: Eliminamos que se puedan requerir extras
62-
'''
58+
# TODO: Eliminamos que se puedan requerir extras
6359
if '[' in data[0]:
6460
pos_1 = await get_first_position(data[0], ['['])
6561
pos_2 = await get_first_position(data[0], [']']) + 1
@@ -73,9 +69,13 @@ async def requires_packages(pkg_name: str, version_dist: str) -> dict[str, dict[
7369
raw_ctcs = data[pos:]
7470

7571
if dist in require_packages:
76-
if not isinstance(require_packages[dist], str):
77-
require_packages[dist].update(await parse_constraints(raw_ctcs))
72+
if isinstance(require_packages[dist], dict):
73+
ctcs = await parse_constraints(raw_ctcs)
74+
if isinstance(ctcs, dict):
75+
require_packages[dist].update(ctcs)
7876
else:
77+
if '.' not in raw_ctcs:
78+
continue
7979
require_packages[dist] = await parse_constraints(raw_ctcs)
8080

8181
return require_packages

app/controllers/generate_controller.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ async def generate_packages(package_name: str, version: dict[str, Any]) -> None:
107107

108108
print(package_name)
109109
await no_exist_package(
110-
package_name, constraints,
110+
package_name,
111+
constraints,
111112
'pypi',
112113
version['_id'],
113114
'version'
Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
from typing import Any
2-
31
from fastapi import APIRouter, status
42
from fastapi.responses import JSONResponse
53

6-
from app.controllers.network_info import NetworkInfo
7-
from app.controllers.network_to_smt import NetworkToSMT
8-
from app.controllers.operations import (FilterConfigs, MaximizeImpact,
9-
MinimizeImpact, NumberOfProducts,
10-
ValidModel)
4+
from flamapy.metamodels.dn_metamodel.operations import NetworkInfo
5+
from flamapy.metamodels.smt_metamodel.transformations import NetworkToSMT
6+
from flamapy.metamodels.smt_metamodel.operations import (
7+
FilterConfigs,
8+
MaximizeImpact,
9+
MinimizeImpact,
10+
NumberOfProducts,
11+
ValidModel
12+
)
1113
from app.controllers.serialize_controller import serialize_network
1214
from app.services.version_service import get_release_by_values
1315
from app.utils.json_encoder import json_encoder
@@ -32,25 +34,25 @@ async def valid_file(network_id: str, file_name: str, agregator: str) -> JSONRes
3234
smt_transform = NetworkToSMT(dependency_network, agregator)
3335
smt_transform.transform()
3436
smt_model = smt_transform.destination_model
35-
operation = ValidModel()
36-
operation.execute(smt_model, file_name)
37+
operation = ValidModel(file_name)
38+
operation.execute(smt_model)
3739
result = {'is_valid': operation.get_result()}
3840
return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder(result))
3941

4042

41-
@router.post(
42-
'/operation/number_of_products/{network_id}',
43-
response_description='Number of products operation'
44-
)
45-
async def number_of_products(network_id: str, file_name: str, agregator: str) -> JSONResponse:
46-
dependency_network = await serialize_network(network_id)
47-
smt_transform = NetworkToSMT(dependency_network, agregator)
48-
smt_transform.transform()
49-
smt_model = smt_transform.destination_model
50-
operation = NumberOfProducts()
51-
operation.execute(smt_model, file_name)
52-
result = {'number_of_products': operation.get_result()}
53-
return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder(result))
43+
# @router.post(
44+
# '/operation/number_of_products/{network_id}',
45+
# response_description='Number of products operation'
46+
# )
47+
# async def number_of_products(network_id: str, file_name: str, agregator: str) -> JSONResponse:
48+
# dependency_network = await serialize_network(network_id)
49+
# smt_transform = NetworkToSMT(dependency_network, agregator)
50+
# smt_transform.transform()
51+
# smt_model = smt_transform.destination_model
52+
# operation = NumberOfProducts(file_name)
53+
# operation.execute(smt_model)
54+
# result = {'number_of_products': operation.get_result()}
55+
# return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder(result))
5456

5557

5658
@router.post(
@@ -59,16 +61,16 @@ async def number_of_products(network_id: str, file_name: str, agregator: str) ->
5961
)
6062
async def minimize_impact(
6163
network_id: str,
62-
file_name: str,
6364
agregator: str,
64-
op_configs: dict[str, int] = {'limit': 10}
65+
file_name: str,
66+
limit: int
6567
) -> JSONResponse:
6668
dependency_network = await serialize_network(network_id)
6769
smt_transform = NetworkToSMT(dependency_network, agregator)
6870
smt_transform.transform()
6971
smt_model = smt_transform.destination_model
70-
operation = MinimizeImpact(**op_configs)
71-
operation.execute(smt_model, file_name)
72+
operation = MinimizeImpact(file_name, limit)
73+
operation.execute(smt_model)
7274
result = await get_release_by_values(operation.get_result())
7375
return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder({'result': result}))
7476

@@ -79,16 +81,16 @@ async def minimize_impact(
7981
)
8082
async def maximize_impact(
8183
network_id: str,
82-
file_name: str,
8384
agregator: str,
84-
op_configs: dict[str, int] = {'limit': 10}
85+
file_name: str,
86+
limit: int
8587
) -> JSONResponse:
8688
dependency_network = await serialize_network(network_id)
8789
smt_transform = NetworkToSMT(dependency_network, agregator)
8890
smt_transform.transform()
8991
smt_model = smt_transform.destination_model
90-
operation = MaximizeImpact(**op_configs)
91-
operation.execute(smt_model, file_name)
92+
operation = MaximizeImpact(file_name, limit)
93+
operation.execute(smt_model)
9294
result = await get_release_by_values(operation.get_result())
9395
return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder({'result': result}))
9496

@@ -99,19 +101,17 @@ async def maximize_impact(
99101
)
100102
async def filter_configs(
101103
network_id: str,
102-
file_name: str,
103104
agregator: str,
104-
op_configs: dict[str, Any] = {
105-
'max_threshold': 10.,
106-
'min_threshold': 0.,
107-
'limit': 10
108-
}
105+
file_name: str,
106+
max_threshold: float,
107+
min_threshold: float,
108+
limit: int
109109
) -> JSONResponse:
110110
dependency_network = await serialize_network(network_id)
111111
smt_transform = NetworkToSMT(dependency_network, agregator)
112112
smt_transform.transform()
113113
smt_model = smt_transform.destination_model
114-
operation = FilterConfigs(**op_configs)
115-
operation.execute(smt_model, file_name)
114+
operation = FilterConfigs(file_name, max_threshold, min_threshold, limit)
115+
operation.execute(smt_model)
116116
result = await get_release_by_values(operation.get_result())
117117
return JSONResponse(status_code=status.HTTP_200_OK, content=json_encoder({'result': result}))
Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
from typing import Any
22

33
from bson import ObjectId
4-
from flamapy.metamodels.dn_metamodel.models import (DependencyNetwork, Package,
5-
RequirementFile, Version)
4+
from flamapy.metamodels.dn_metamodel.models import (
5+
DependencyNetwork,
6+
RequirementFile,
7+
Package,
8+
Version
9+
)
610
from flamapy.metamodels.dn_metamodel.transformations import SerializeNetwork
711

812
from app.services.package_edge_service import read_package_edge_by_id
913
from app.services.serialize_service import aggregate_network_by_id
1014

11-
all_package_edges: list[dict[str, Any]] = []
15+
all_package_edges: dict[str, dict[str, Any]] = {}
1216
all_package_edges_ids: list[ObjectId] = []
17+
all_versions: dict[str, Version] = {}
18+
all_packages: dict[str, Package] = {}
1319

1420

1521
async def serialize_network(network_id: str) -> DependencyNetwork | None:
1622
network = await aggregate_network_by_id(network_id)
1723
requirement_files = network['requirement_files']
18-
del network['_id']
1924
network['requirement_files'] = []
2025
serializer = SerializeNetwork(source_model=network)
2126
serializer.transform()
@@ -31,50 +36,57 @@ async def read_requirement_files(
3136
if not requirement_file['package_edges']:
3237
continue
3338
package_edges = requirement_file['package_edges']
34-
del requirement_file['package_edges']
35-
del requirement_file['_id']
3639
requirement_file['packages'] = []
3740
requirement_file = RequirementFile(**requirement_file)
3841
dn_model.requirement_files.append(requirement_file)
3942
await read_packages(package_edges, requirement_file)
4043
all_package_edges.clear()
4144
all_package_edges_ids.clear()
45+
all_versions.clear()
46+
all_packages.clear()
4247

4348

4449
async def read_packages(
4550
package_egdes: list[dict[str, Any]],
4651
parent: RequirementFile | Version
4752
) -> None:
4853
for package_edge in package_egdes:
49-
package = Package(**{'name': package_edge['package_name'], 'versions': []})
50-
parent.packages.append(package)
51-
await read_versions(package_edge['versions'], package)
54+
key = package_edge['package_name'] + str(package_edge['constraints'])
55+
if key in all_packages:
56+
parent.packages.append(all_packages[key])
57+
else:
58+
package = Package(**{
59+
'name': package_edge['package_name'],
60+
'constraints': package_edge['constraints'],
61+
'versions': []
62+
})
63+
all_packages[key] = package
64+
parent.packages.append(package)
65+
await read_versions(package_edge['versions'], package)
5266

5367

5468
async def read_versions(versions: list[dict[str, Any]], package: Package) -> None:
5569
for version in versions:
56-
if '_id' not in version:
57-
continue
58-
package_edges = await search_package_edge(version['package_edges'])
59-
del version['package_edges']
60-
del version['_id']
70+
package_edges = []
71+
if 'package_edges' in version:
72+
package_edges = await search_package_edge(version['package_edges'])
6173
version['packages'] = []
6274
version = Version(**version)
6375
package.versions.append(version)
64-
await read_packages(package_edges, version)
76+
if package_edges:
77+
await read_packages(package_edges, version)
6578

6679

6780
async def search_package_edge(package_edge_ids: list[ObjectId]) -> list[dict[str, Any]]:
6881
package_edges = []
6982
for package_edge_id in package_edge_ids:
83+
key = str(package_edge_id)
7084
if package_edge_id not in all_package_edges_ids:
7185
package_edge = await read_package_edge_by_id(package_edge_id, 'pypi')
72-
all_package_edges.append(package_edge)
86+
all_package_edges[key] = package_edge
7387
all_package_edges_ids.append(package_edge_id)
7488
package_edges.append(package_edge)
7589
continue
76-
for package_edge in all_package_edges:
77-
if package_edge['_id'] == package_edge_id:
78-
package_edges.append(package_edge)
79-
break
90+
package_edge = all_package_edges[key]
91+
package_edges.append(package_edge)
8092
return package_edges

app/utils/get_session.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ async def get_session() -> Session:
77
session = Session()
88
retry = Retry(connect=4, backoff_factor=0.5)
99
adapter = HTTPAdapter(max_retries=retry)
10-
session.mount('http://', adapter)
11-
session.mount('https://', adapter)
10+
session.mount('http*://', adapter)
1211
return session

mongo_seed/seeds/cves.bson.gz

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:efcab8082b6b1efb19fe6c796683ae2e2a310f94a0e0bd32cd9164910b249994
3-
size 134086565
2+
oid sha256:3278c194abf20f166b8eb929d769ad550ec11bb78d9e79889ae56246a302c908
3+
size 151949839
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:a2117dfff06661366070174e0b87493eae8a8668ab5d17687183d3228f0544e3
2+
oid sha256:0ad6777181562035fb433e7d0835930fb491cbe67d7ab68bb9c6368568e6438c
33
size 120
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:4ad7d17ded9348ba908cb0020e736226b486b7554fd24e55e1d2e7ee8904e6a7
3-
size 1455980
2+
oid sha256:47d9bdaca10021bea64eb5f933dd62fcafa4267f50f2a2fdb158dbaf0ce30acd
3+
size 1457336

mongo_seed/seeds/packages.bson.gz

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:01884f838c4b62e1b21e0128a20722d9fdaca1a7309dcb252897311e55ddd41c
3-
size 158079
2+
oid sha256:83c94f5bb26eb712f836d9c6e30991095510031ed1d7f0de4c947e1eb0947134
3+
size 156132

0 commit comments

Comments
 (0)