Skip to content

Commit e1d27ba

Browse files
committed
Merge branch 'develop' into main
2 parents d18522c + f02d018 commit e1d27ba

4 files changed

Lines changed: 89 additions & 21 deletions

File tree

oshminer/GitHub.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
# SPDX-FileCopyrightText: 2022 Pen-Yuan Hsing
44
# SPDX-License-Identifier: AGPL-3.0-or-later
55

6-
def make_GitHub_request(url: str, data: list) -> str:
7-
print(f"Constructing an API request to GitHub for repository {url} for the following data {data}")
6+
async def make_GitHub_request(url: str, data: list) -> dict:
7+
print(f"Constructing an API request to GitHub for repository {url} for the following data {data}")
8+
9+
# Create a dictionary to hold results from GitHub API query
10+
results: dict = {
11+
"repository": str(url),
12+
"platform": "GitHub",
13+
"requested_data": {}
14+
}
15+
16+
return results

oshminer/Wikifactory.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,19 @@ async def get_files_info(project: dict, session) -> dict:
9999
- result["files_info"]["data_files"]\
100100
- result["files_info"]["document_files"]
101101
# Calculate proportion of each file type
102-
result["files_info"]["ecad_proportion"]: float = result["files_info"]["ecad_files"]/result["files_info"]["total_files"]
103-
result["files_info"]["mcad_proportion"]: float = result["files_info"]["mcad_files"]/result["files_info"]["total_files"]
104-
result["files_info"]["image_proportion"]: float = result["files_info"]["image_files"]/result["files_info"]["total_files"]
105-
result["files_info"]["data_proportion"]: float = result["files_info"]["data_files"]/result["files_info"]["total_files"]
106-
result["files_info"]["document_proportion"]: float = result["files_info"]["document_files"]/result["files_info"]["total_files"]
107-
result["files_info"]["other_proportion"]: float = result["files_info"]["other_files"]/result["files_info"]["total_files"]
102+
# Limit to three decimal places to reduce size of response
103+
ecad_proportion: float = result["files_info"]["ecad_files"]/result["files_info"]["total_files"]
104+
mcad_proportion: float = result["files_info"]["mcad_files"]/result["files_info"]["total_files"]
105+
image_proportion: float = result["files_info"]["image_files"]/result["files_info"]["total_files"]
106+
data_proportion: float = result["files_info"]["data_files"]/result["files_info"]["total_files"]
107+
document_proportion: float = result["files_info"]["document_files"]/result["files_info"]["total_files"]
108+
other_proportion: float = result["files_info"]["other_files"]/result["files_info"]["total_files"]
109+
result["files_info"]["ecad_proportion"]: float = float(f"{ecad_proportion:.3f}")
110+
result["files_info"]["mcad_proportion"]: float = float(f"{mcad_proportion:.3f}")
111+
result["files_info"]["image_proportion"]: float = float(f"{image_proportion:.3f}")
112+
result["files_info"]["data_proportion"]: float = float(f"{data_proportion:.3f}")
113+
result["files_info"]["document_proportion"]: float = float(f"{document_proportion:.3f}")
114+
result["files_info"]["other_proportion"]: float = float(f"{other_proportion:.3f}")
108115
else: # If there are no files, return 0 for everything
109116
result: dict = {
110117
"files_info": {
@@ -398,7 +405,7 @@ def parse_url(url: str) -> dict:
398405
}
399406
return repo
400407

401-
async def make_Wikifactory_request(url: str, data: list) -> str:
408+
async def make_Wikifactory_request(url: str, data: list, api_url: str = "https://wikifactory.com/api/graphql") -> str:
402409
print(
403410
f"Constructing and making an API request to Wikifactory for repository {url} for the following data {data}",
404411
file = sys.stderr
@@ -412,7 +419,7 @@ async def make_Wikifactory_request(url: str, data: list) -> str:
412419
}
413420

414421
# Select transport with the Wikifactory API endpoint URL
415-
transport = AIOHTTPTransport(url = "https://wikifactory.com/api/graphql")
422+
transport = AIOHTTPTransport(url = api_url)
416423

417424
# Get "space" and "slug" components from this repository's URL
418425
space_slug: dict = parse_url(url)

oshminer/errors/exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44
# SPDX-License-Identifier: AGPL-3.0-or-later
55

66
class BadRepoError(Exception):
7+
pass
8+
9+
class BadWIFAPIError(Exception):
710
pass

oshminer/main.py

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# Python Standard Library imports
77
import asyncio
88
import json
9+
import http.client
910
import sys
11+
import urllib
1012

1113
# External library imports
1214
from fastapi import FastAPI, status
@@ -17,9 +19,12 @@
1719
from oshminer.supported_platforms import supported_domains
1820
from oshminer.errors import exceptions
1921

22+
# Default Wikifactory API URL
23+
WIF_API_DEFAULT: str = "https://wikifactory.com/api/graphql"
2024
class MiningRequest(BaseModel):
2125
repo_urls: list[HttpUrl] = set()
2226
requested_data: list[str] = set()
27+
wikifactory_API_URL: str = WIF_API_DEFAULT
2328

2429
# Supported data-mining request types. Items in `required_data` must
2530
# be from this list.
@@ -44,23 +49,58 @@ class MiningRequest(BaseModel):
4449
async def root():
4550
return {"message": "Dashboard data-mining backend is on"}
4651

47-
async def process_repo(repo: HttpUrl, requests: list[str], responses: list):
52+
async def process_repo(repo: HttpUrl, requests: list[str], responses: list, WIF_API: str = WIF_API_DEFAULT):
4853
platform: str = repo.host.replace("www.", "")
49-
try:
50-
repo_info: dict = await supported_domains[platform](repo, requests)
51-
except exceptions.BadRepoError:
52-
return JSONResponse(
53-
status_code = status.HTTP_400_BAD_REQUEST,
54-
content = f"Error with repository: {repo}"
55-
)
56-
responses.append(repo_info)
54+
# If a custom Wikifactory API URL is provided, then use it.
55+
if WIF_API != WIF_API_DEFAULT:
56+
try:
57+
repo_info: dict = await supported_domains[platform](repo, requests, WIF_API)
58+
except exceptions.BadRepoError:
59+
return JSONResponse(
60+
status_code = status.HTTP_400_BAD_REQUEST,
61+
content = f"Error with repository: {repo}"
62+
)
63+
responses.append(repo_info)
64+
else:
65+
try:
66+
repo_info: dict = await supported_domains[platform](repo, requests)
67+
except exceptions.BadRepoError:
68+
return JSONResponse(
69+
status_code = status.HTTP_400_BAD_REQUEST,
70+
content = f"Error with repository: {repo}"
71+
)
72+
responses.append(repo_info)
5773

58-
@app.get(
74+
@app.post(
5975
"/data/",
6076
name = "API endpoint",
6177
description = "Primary endpoint for requesting data."
6278
)
6379
async def mining_request(request_body: MiningRequest):
80+
#
81+
# Check if custom Wikifactory API URL is provided and test it
82+
#
83+
84+
if request_body.wikifactory_API_URL != WIF_API_DEFAULT:
85+
print(
86+
f"Custom Wikifactory API URL detected: {request_body.wikifactory_API_URL}",
87+
file = sys.stderr
88+
)
89+
try:
90+
api_url_response = urllib.request.urlopen(
91+
request_body.wikifactory_API_URL,
92+
timeout=10
93+
)
94+
if api_url_response.status != 200:
95+
raise exceptions.BadWIFAPIError
96+
except (exceptions.BadWIFAPIError, urllib.error.URLError, http.client.BadStatusLine) as err:
97+
return JSONResponse(
98+
status_code = status.HTTP_400_BAD_REQUEST,
99+
content = f"Error reaching Wikifactory API URL: {request_body.wikifactory_API_URL} {err}"
100+
)
101+
elif request_body.wikifactory_API_URL is None:
102+
request_body.wikifactory_API_URL = WIF_API_DEFAULT
103+
64104
#
65105
# Check API client's request body
66106
#
@@ -103,7 +143,16 @@ async def mining_request(request_body: MiningRequest):
103143
# Construct, send API requests, and get results
104144
#
105145

106-
await asyncio.gather(*[process_repo(repo, request_body.requested_data, response_list) for repo in request_body.repo_urls])
146+
await asyncio.gather(
147+
*[
148+
process_repo(
149+
repo,
150+
request_body.requested_data,
151+
response_list,
152+
WIF_API=request_body.wikifactory_API_URL
153+
) for repo in request_body.repo_urls
154+
]
155+
)
107156

108157
# for repo in request_body.repo_urls:
109158
# platform = repo.host.replace("www.", "")

0 commit comments

Comments
 (0)