Skip to content

Commit 1ecef78

Browse files
committed
feat: update main
1 parent 7385c47 commit 1ecef78

File tree

1 file changed

+3
-103
lines changed

1 file changed

+3
-103
lines changed

app/main.py

Lines changed: 3 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -3,111 +3,11 @@
33
You can directly import the main function in your code.
44
"""
55

6-
import csv
7-
from urllib.parse import ParseResult, urljoin, urlparse
8-
from uuid import uuid4
9-
10-
from pydantic import BaseModel
11-
12-
API_INDICATOR = ['v1', 'v2', 'v3', 'v4', 'v5', 'api', 'graphql', 'v1.1', 'v1.0']
13-
14-
ENDPOINTS_FILE = 'data/endpoints_with_services.csv'
15-
SERVICES_FILE = 'data/services.csv'
16-
KEEP_HEADERS = ['path', 'service', 'id', 'method', 'url']
17-
18-
19-
def load_csv(filename: str) -> list[dict[str, str]]:
20-
with open(filename) as f:
21-
reader = csv.DictReader(f, skipinitialspace=True)
22-
return [{k: v for k, v in row.items() if k in KEEP_HEADERS} for row in reader]
23-
24-
25-
def format_path(path: str) -> str:
26-
return f'/{path}'.replace('//', '/')
27-
28-
29-
def format_url(url: str) -> str:
30-
return url.rstrip('/')
31-
32-
33-
class APIBase(BaseModel):
34-
"""Base class for API-related models with common URL parsing logic."""
35-
36-
_id: str
37-
method: str = 'GET'
38-
39-
@property
40-
def parsed_url(self) -> ParseResult:
41-
return urlparse(self.url)
42-
43-
@property
44-
def subdomain(self) -> str:
45-
return format_url(self.parsed_url.netloc)
46-
47-
@property
48-
def full_path(self) -> str:
49-
return format_path(self.parsed_url.path)
50-
51-
@property
52-
def api_path(self) -> str:
53-
path_split = self.parsed_url.path.split('/')
54-
for i, el in enumerate(reversed(path_split)):
55-
if el in API_INDICATOR:
56-
return format_path('/'.join(path_split[len(path_split) - i :]))
57-
return format_path(self.parsed_url.path)
58-
59-
@property
60-
def api_base_path(self) -> str:
61-
path_split = self.parsed_url.path.split('/')
62-
for i, el in enumerate(reversed(path_split)):
63-
if el in API_INDICATOR:
64-
return format_url(self.subdomain + '/' + '/'.join(path_split[: len(path_split) - i]))
65-
return format_url(self.subdomain)
66-
67-
68-
class Endpoint(APIBase):
69-
"""Represents an API endpoint with its path and service."""
70-
71-
path: str
72-
service: str
73-
74-
@property
75-
def url(self) -> str:
76-
return urljoin(self.service, self.path)
77-
78-
79-
class Service(APIBase):
80-
"""Represents a service with its URL."""
81-
82-
url: str
83-
84-
85-
def add_to_services_dict(item: APIBase, services_dict: dict) -> None:
86-
"""Add an API item to the services dictionary.
87-
88-
Args:
89-
item: APIBase instance (Endpoint or Service)
90-
services_dict: Dictionary to store grouped services
91-
"""
92-
if item.api_base_path not in services_dict:
93-
services_dict[item.api_base_path] = {'GET /': Service(url=item.api_base_path, _id=str(uuid4()))}
94-
services_dict[item.api_base_path][f'{item.method} {item.api_path}'] = item
95-
966

977
def main() -> None:
988
"""Entrypoint."""
99-
endpoints_data = load_csv(ENDPOINTS_FILE)
100-
services_data = load_csv(SERVICES_FILE)
101-
102-
endpoints = [Endpoint(**endpoint) for endpoint in endpoints_data]
103-
services = [Service(**service) for service in services_data]
9+
print('Hello, World!') # noqa: T201
10410

105-
all_services: dict = {}
106-
for item in [*endpoints, *services]:
107-
add_to_services_dict(item, all_services)
10811

109-
for base_path, items in all_services.items():
110-
print('#' * 100)
111-
print(base_path)
112-
for item in items.values():
113-
print(item.method, item.api_path)
12+
if __name__ == '__main__':
13+
main()

0 commit comments

Comments
 (0)