|
3 | 3 | You can directly import the main function in your code. |
4 | 4 | """ |
5 | 5 |
|
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 | | - |
96 | 6 |
|
97 | 7 | def main() -> None: |
98 | 8 | """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 |
104 | 10 |
|
105 | | - all_services: dict = {} |
106 | | - for item in [*endpoints, *services]: |
107 | | - add_to_services_dict(item, all_services) |
108 | 11 |
|
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