graph-dependency-analyzer 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. graph_dependency_analyzer-0.2.0.dist-info/METADATA +158 -0
  2. graph_dependency_analyzer-0.2.0.dist-info/RECORD +86 -0
  3. graph_dependency_analyzer-0.2.0.dist-info/WHEEL +5 -0
  4. graph_dependency_analyzer-0.2.0.dist-info/entry_points.txt +2 -0
  5. graph_dependency_analyzer-0.2.0.dist-info/top_level.txt +1 -0
  6. src/__init__.py +0 -0
  7. src/application/__init__.py +0 -0
  8. src/application/dtos/__init__.py +0 -0
  9. src/application/dtos/affected_component.py +59 -0
  10. src/application/dtos/batch_processing_result.py +17 -0
  11. src/application/dtos/impact_analysis_response.py +56 -0
  12. src/application/dtos/impact_query_request.py +38 -0
  13. src/application/dtos/index_batch_request.py +53 -0
  14. src/application/dtos/index_batch_response.py +72 -0
  15. src/application/dtos/index_result.py +20 -0
  16. src/application/dtos/repository_index_result.py +79 -0
  17. src/application/exceptions.py +41 -0
  18. src/application/services/__init__.py +0 -0
  19. src/application/services/file_scanner_service.py +258 -0
  20. src/application/services/progress_tracker.py +132 -0
  21. src/application/use_cases/__init__.py +0 -0
  22. src/application/use_cases/clear_all_data_use_case.py +180 -0
  23. src/application/use_cases/index_batch_use_case.py +153 -0
  24. src/application/use_cases/index_repository_use_case.py +683 -0
  25. src/application/use_cases/indexing_orchestrator.py +181 -0
  26. src/application/use_cases/list_repositories_use_case.py +84 -0
  27. src/cli.py +512 -0
  28. src/config/__init__.py +5 -0
  29. src/config/container.py +211 -0
  30. src/config/logging_config.py +123 -0
  31. src/config/settings.py +165 -0
  32. src/domain/__init__.py +0 -0
  33. src/domain/entities/__init__.py +20 -0
  34. src/domain/entities/ast_node.py +32 -0
  35. src/domain/entities/code_chunk.py +45 -0
  36. src/domain/entities/code_file.py +44 -0
  37. src/domain/entities/dependency_graph.py +110 -0
  38. src/domain/entities/repository.py +46 -0
  39. src/domain/exceptions.py +36 -0
  40. src/domain/repositories/__init__.py +22 -0
  41. src/domain/repositories/i_code_parser.py +50 -0
  42. src/domain/repositories/i_dependency_extractor.py +35 -0
  43. src/domain/repositories/i_embedding_provider.py +31 -0
  44. src/domain/repositories/i_graph_repository.py +78 -0
  45. src/domain/repositories/i_vector_repository.py +55 -0
  46. src/domain/services/__init__.py +8 -0
  47. src/domain/services/dependency_extractor.py +962 -0
  48. src/domain/services/semantic_chunk_builder.py +719 -0
  49. src/domain/value_objects/__init__.py +12 -0
  50. src/domain/value_objects/chunk_type.py +24 -0
  51. src/domain/value_objects/dependency_type.py +22 -0
  52. src/domain/value_objects/node_type.py +22 -0
  53. src/domain/value_objects/qualified_name.py +78 -0
  54. src/infrastructure/__init__.py +0 -0
  55. src/infrastructure/exceptions.py +41 -0
  56. src/infrastructure/external_apis/__init__.py +0 -0
  57. src/infrastructure/external_apis/ollama_embedding_provider.py +134 -0
  58. src/infrastructure/external_apis/openai_embedding_provider.py +231 -0
  59. src/infrastructure/parsing/__init__.py +20 -0
  60. src/infrastructure/parsing/config_file_parser.py +347 -0
  61. src/infrastructure/parsing/gradle_dependency_parser.py +159 -0
  62. src/infrastructure/parsing/groovy_parser.py +198 -0
  63. src/infrastructure/parsing/maven_dependency_parser.py +147 -0
  64. src/infrastructure/parsing/microfrontend_config_parser.py +242 -0
  65. src/infrastructure/parsing/npm_package_dependency_parser.py +255 -0
  66. src/infrastructure/parsing/python_parser.py +211 -0
  67. src/infrastructure/parsing/sql_schema_parser.py +658 -0
  68. src/infrastructure/parsing/tree_sitter_java_parser.py +434 -0
  69. src/infrastructure/parsing/tree_sitter_typescript_parser.py +600 -0
  70. src/infrastructure/persistence/__init__.py +0 -0
  71. src/infrastructure/persistence/graph_export_repository.py +443 -0
  72. src/infrastructure/persistence/neo4j_dependency_repository.py +657 -0
  73. src/infrastructure/persistence/qdrant_vector_repository.py +357 -0
  74. src/infrastructure/persistence/repository_relationship_repository.py +1312 -0
  75. src/presentation/__init__.py +0 -0
  76. src/presentation/api/__init__.py +0 -0
  77. src/presentation/api/rest/__init__.py +0 -0
  78. src/presentation/api/rest/exception_handlers.py +174 -0
  79. src/presentation/api/rest/main.py +80 -0
  80. src/presentation/api/rest/routers/__init__.py +5 -0
  81. src/presentation/api/rest/routers/admin.py +103 -0
  82. src/presentation/api/rest/routers/analysis.py +980 -0
  83. src/presentation/api/rest/routers/export.py +442 -0
  84. src/presentation/api/rest/routers/health.py +117 -0
  85. src/presentation/api/rest/routers/indexing.py +148 -0
  86. src/presentation/api/rest/routers/relationships.py +1089 -0
@@ -0,0 +1,148 @@
1
+ """
2
+ Indexing Router (Task 9.2)
3
+
4
+ REST API endpoints for repository indexing operations.
5
+ """
6
+ from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
7
+ from pydantic import BaseModel
8
+ import structlog
9
+
10
+ from dependency_injector.wiring import inject, Provide
11
+
12
+ from src.application.dtos.index_batch_request import IndexBatchRequest
13
+ from src.application.dtos.index_batch_response import IndexBatchResponse
14
+ from src.application.use_cases.index_batch_use_case import IndexBatchUseCase
15
+ from src.application.use_cases.list_repositories_use_case import ListRepositoriesUseCase
16
+ from src.config.container import Container
17
+
18
+ logger = structlog.get_logger(__name__)
19
+
20
+ router = APIRouter(prefix="/api/indexing", tags=["indexing"])
21
+
22
+
23
+ class RepositoryListResponse(BaseModel):
24
+ """Response with list of indexed repositories."""
25
+
26
+ repositories: list[str]
27
+ total: int
28
+
29
+
30
+ @router.post(
31
+ "/index/batch",
32
+ response_model=IndexBatchResponse,
33
+ status_code=status.HTTP_202_ACCEPTED,
34
+ responses={
35
+ 202: {"description": "Batch indexing accepted"},
36
+ 400: {"description": "Invalid request (empty list, no valid repos)"},
37
+ 422: {"description": "Validation error"},
38
+ 500: {"description": "Internal server error"}
39
+ }
40
+ )
41
+ @inject
42
+ async def index_batch(
43
+ request: IndexBatchRequest,
44
+ background_tasks: BackgroundTasks,
45
+ use_case: IndexBatchUseCase = Depends(Provide[Container.index_batch_use_case])
46
+ ) -> IndexBatchResponse:
47
+ """
48
+ Index multiple repositories in batch.
49
+
50
+ Processes multiple Java repositories in parallel with configurable
51
+ concurrency limit. Each repository goes through the complete indexing
52
+ pipeline: scanning, AST parsing, dependency extraction, chunking,
53
+ embedding generation, and storage in Qdrant/Neo4j.
54
+
55
+ Args:
56
+ request: Batch indexing request with repository names
57
+ background_tasks: FastAPI background tasks (if background=True)
58
+ use_case: Injected IndexBatchUseCase
59
+
60
+ Returns:
61
+ IndexBatchResponse with aggregated results
62
+
63
+ Raises:
64
+ HTTP 400: Empty repository list or no valid repositories found
65
+ HTTP 422: Request validation failed
66
+ HTTP 500: Internal error during processing
67
+ """
68
+ logger.info(
69
+ "batch_indexing_requested",
70
+ repositories=request.repositories,
71
+ parallel=request.parallel,
72
+ background=request.background
73
+ )
74
+
75
+ # Handle background processing
76
+ if request.background:
77
+ # Schedule background task
78
+ background_tasks.add_task(
79
+ use_case.execute,
80
+ request
81
+ )
82
+
83
+ # Return immediate response
84
+ return IndexBatchResponse(
85
+ total_processed=0,
86
+ success_count=0,
87
+ failed_count=0,
88
+ results=[]
89
+ )
90
+
91
+ # Synchronous processing
92
+ response = await use_case.execute(request)
93
+
94
+ logger.info(
95
+ "batch_indexing_completed",
96
+ total=response.total_processed,
97
+ success=response.success_count,
98
+ failed=response.failed_count
99
+ )
100
+
101
+ return response
102
+
103
+
104
+ @router.get(
105
+ "/repositories",
106
+ response_model=RepositoryListResponse,
107
+ status_code=status.HTTP_200_OK,
108
+ responses={
109
+ 200: {"description": "List of indexed repositories"},
110
+ 500: {"description": "Internal server error"}
111
+ }
112
+ )
113
+ @inject
114
+ async def list_repositories(
115
+ use_case: "ListRepositoriesUseCase" = Depends(Provide[Container.list_repositories_use_case])
116
+ ) -> RepositoryListResponse:
117
+ """
118
+ List all indexed repositories.
119
+
120
+ Returns list of repository names that have been successfully indexed
121
+ and are available in the system.
122
+
123
+ Returns:
124
+ RepositoryListResponse with repository names and count
125
+
126
+ Raises:
127
+ HTTP 500: Internal error querying repositories
128
+ """
129
+ logger.info("list_repositories_requested")
130
+
131
+ try:
132
+ repositories = await use_case.execute()
133
+
134
+ return RepositoryListResponse(
135
+ repositories=repositories,
136
+ total=len(repositories)
137
+ )
138
+
139
+ except Exception as e:
140
+ logger.error(
141
+ "list_repositories_failed",
142
+ error=str(e),
143
+ error_type=type(e).__name__
144
+ )
145
+ raise HTTPException(
146
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
147
+ detail=f"Failed to list repositories: {str(e)}"
148
+ )