code-analyser 0.1.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.
@@ -0,0 +1,172 @@
1
+ """
2
+ Database models for analysis reports and results
3
+ """
4
+
5
+ from datetime import datetime
6
+ from typing import TYPE_CHECKING
7
+
8
+ from sqlalchemy import JSON, Boolean, DateTime, Float, ForeignKey, Integer, String, Text
9
+ from sqlalchemy.orm import Mapped, mapped_column, relationship
10
+ from sqlalchemy.sql import func
11
+
12
+ from codelens.db.database import Base
13
+
14
+ if TYPE_CHECKING:
15
+ from .assignments import Assignment
16
+
17
+
18
+ class AnalysisReport(Base):
19
+ """Analysis report for a code submission (metadata only, not the code itself)"""
20
+
21
+ __tablename__ = "analysis_reports"
22
+
23
+ id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
24
+
25
+ # Assignment and student information
26
+ assignment_id: Mapped[int] = mapped_column(
27
+ Integer, ForeignKey("assignments.id"), nullable=False, index=True
28
+ )
29
+ student_id: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True)
30
+ student_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
31
+ submission_id: Mapped[str] = mapped_column(String(100), nullable=False, index=True) # Unique submission ID
32
+
33
+ # File information (metadata only)
34
+ file_name: Mapped[str] = mapped_column(String(255), nullable=False)
35
+ file_size: Mapped[int] = mapped_column(Integer, nullable=False) # in bytes
36
+ file_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True) # SHA-256 hash
37
+ language: Mapped[str] = mapped_column(String(50), nullable=False)
38
+
39
+ # Analysis results
40
+ analysis_version: Mapped[str] = mapped_column(String(20), nullable=False) # Version of analysis tools
41
+
42
+ # Syntax and validation results
43
+ syntax_valid: Mapped[bool] = mapped_column(Boolean, nullable=False)
44
+ syntax_errors: Mapped[dict | None] = mapped_column(JSON, nullable=True)
45
+
46
+ # Code quality metrics
47
+ quality_metrics: Mapped[dict] = mapped_column(JSON, nullable=False)
48
+ # Expected structure: {
49
+ # "complexity": {"cyclomatic": 5, "cognitive": 8},
50
+ # "lines_of_code": 120,
51
+ # "style_issues": [...],
52
+ # "type_issues": [...],
53
+ # "documentation_score": 0.75
54
+ # }
55
+
56
+ # Test execution results
57
+ test_results: Mapped[dict | None] = mapped_column(JSON, nullable=True)
58
+ # Expected structure: {
59
+ # "total_tests": 10,
60
+ # "passed_tests": 8,
61
+ # "failed_tests": [...],
62
+ # "execution_time": 1.23,
63
+ # "memory_usage": "45MB"
64
+ # }
65
+
66
+ # Grading results
67
+ grade_breakdown: Mapped[dict] = mapped_column(JSON, nullable=False)
68
+ # Expected structure: {
69
+ # "functionality": 85,
70
+ # "style": 90,
71
+ # "documentation": 70,
72
+ # "testing": 95,
73
+ # "total": 85
74
+ # }
75
+ total_score: Mapped[float] = mapped_column(Float, nullable=False)
76
+ max_score: Mapped[float] = mapped_column(Float, nullable=False, default=100.0)
77
+
78
+ # Similarity analysis
79
+ similarity_results: Mapped[dict | None] = mapped_column(JSON, nullable=True)
80
+ # Expected structure: {
81
+ # "highest_similarity": 0.15,
82
+ # "flagged_submissions": [...],
83
+ # "ai_baseline_similarity": 0.45,
84
+ # "methods_used": ["ast_similarity", "token_similarity"]
85
+ # }
86
+
87
+ # Feedback and recommendations
88
+ feedback: Mapped[dict] = mapped_column(JSON, nullable=False)
89
+ # Expected structure: {
90
+ # "strengths": [...],
91
+ # "improvements": [...],
92
+ # "resources": [...],
93
+ # "detailed_comments": {...}
94
+ # }
95
+
96
+ # Processing metadata
97
+ processing_time: Mapped[float] = mapped_column(Float, nullable=False) # seconds
98
+ tools_used: Mapped[dict] = mapped_column(JSON, nullable=False) # Which analysis tools were used
99
+
100
+ # Status and timestamps
101
+ status: Mapped[str] = mapped_column(String(20), nullable=False, default="completed") # pending, processing, completed, failed
102
+ error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
103
+
104
+ analyzed_at: Mapped[datetime] = mapped_column(
105
+ DateTime(timezone=True),
106
+ server_default=func.now(),
107
+ nullable=False
108
+ )
109
+
110
+ # Relationships
111
+ assignment: Mapped["Assignment"] = relationship("Assignment", back_populates="reports")
112
+ similarity_matches: Mapped[list["SimilarityMatch"]] = relationship(
113
+ "SimilarityMatch",
114
+ foreign_keys="SimilarityMatch.report_id",
115
+ back_populates="report",
116
+ cascade="all, delete-orphan"
117
+ )
118
+
119
+
120
+ class SimilarityMatch(Base):
121
+ """Records of similarity matches between submissions"""
122
+
123
+ __tablename__ = "similarity_matches"
124
+
125
+ id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
126
+
127
+ # Source and target reports
128
+ report_id: Mapped[int] = mapped_column(
129
+ Integer, ForeignKey("analysis_reports.id"), nullable=False, index=True
130
+ )
131
+ matched_report_id: Mapped[int] = mapped_column(
132
+ Integer, ForeignKey("analysis_reports.id"), nullable=False, index=True
133
+ )
134
+
135
+ # Similarity metrics
136
+ similarity_score: Mapped[float] = mapped_column(Float, nullable=False)
137
+ similarity_method: Mapped[str] = mapped_column(String(50), nullable=False) # ast, token, etc
138
+
139
+ # Match details
140
+ matched_sections: Mapped[dict] = mapped_column(JSON, nullable=False)
141
+ # Expected structure: {
142
+ # "functions": [...],
143
+ # "code_blocks": [...],
144
+ # "variable_patterns": [...]
145
+ # }
146
+
147
+ confidence: Mapped[float] = mapped_column(Float, nullable=False) # 0.0 - 1.0
148
+ flagged: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
149
+
150
+ # Review status
151
+ reviewed: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
152
+ review_decision: Mapped[str | None] = mapped_column(String(20), nullable=True) # flagged, cleared, escalated
153
+ reviewer_notes: Mapped[str | None] = mapped_column(Text, nullable=True)
154
+
155
+ # Timestamps
156
+ detected_at: Mapped[datetime] = mapped_column(
157
+ DateTime(timezone=True),
158
+ server_default=func.now(),
159
+ nullable=False
160
+ )
161
+ reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
162
+
163
+ # Relationships
164
+ report: Mapped["AnalysisReport"] = relationship(
165
+ "AnalysisReport",
166
+ foreign_keys=[report_id],
167
+ back_populates="similarity_matches"
168
+ )
169
+ matched_report: Mapped["AnalysisReport"] = relationship(
170
+ "AnalysisReport",
171
+ foreign_keys=[matched_report_id]
172
+ )
@@ -0,0 +1,76 @@
1
+ """
2
+ Database models for rubrics and grading criteria
3
+ """
4
+
5
+ from datetime import datetime
6
+ from typing import TYPE_CHECKING
7
+
8
+ from sqlalchemy import JSON, DateTime, Float, Integer, String, Text
9
+ from sqlalchemy.orm import Mapped, mapped_column, relationship
10
+ from sqlalchemy.sql import func
11
+
12
+ from codelens.db.database import Base
13
+
14
+ if TYPE_CHECKING:
15
+ from .assignments import Assignment
16
+
17
+
18
+ class Rubric(Base):
19
+ """Rubric for grading assignments"""
20
+
21
+ __tablename__ = "rubrics"
22
+
23
+ id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
24
+ name: Mapped[str] = mapped_column(String(200), nullable=False, index=True)
25
+ description: Mapped[str | None] = mapped_column(Text, nullable=True)
26
+ language: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
27
+
28
+ # Rubric configuration
29
+ criteria: Mapped[dict] = mapped_column(JSON, nullable=False) # Grading criteria
30
+ weights: Mapped[dict] = mapped_column(JSON, nullable=False) # Category weights
31
+ total_points: Mapped[int] = mapped_column(Integer, nullable=False, default=100)
32
+
33
+ # Analysis configuration
34
+ analysis_config: Mapped[dict] = mapped_column(JSON, nullable=True) # Tool configs
35
+
36
+ # Metadata
37
+ created_at: Mapped[datetime] = mapped_column(
38
+ DateTime(timezone=True),
39
+ server_default=func.now(),
40
+ nullable=False
41
+ )
42
+ updated_at: Mapped[datetime] = mapped_column(
43
+ DateTime(timezone=True),
44
+ server_default=func.now(),
45
+ onupdate=func.now(),
46
+ nullable=False
47
+ )
48
+
49
+ # Relationships
50
+ assignments: Mapped[list["Assignment"]] = relationship(
51
+ "Assignment", back_populates="rubric", cascade="all, delete-orphan"
52
+ )
53
+
54
+
55
+ class RubricCriterion(Base):
56
+ """Individual criterion within a rubric"""
57
+
58
+ __tablename__ = "rubric_criteria"
59
+
60
+ id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
61
+ rubric_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
62
+
63
+ # Criterion details
64
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
65
+ description: Mapped[str] = mapped_column(Text, nullable=False)
66
+ category: Mapped[str] = mapped_column(String(50), nullable=False) # functionality, style, etc
67
+ max_points: Mapped[int] = mapped_column(Integer, nullable=False)
68
+ weight: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
69
+
70
+ # Auto-grading configuration
71
+ auto_gradable: Mapped[bool] = mapped_column(nullable=False, default=True)
72
+ evaluation_method: Mapped[str | None] = mapped_column(String(50), nullable=True) # test_count, complexity, etc
73
+ evaluation_config: Mapped[dict | None] = mapped_column(JSON, nullable=True)
74
+
75
+ # Performance levels (excellent, good, satisfactory, needs_improvement)
76
+ performance_levels: Mapped[dict] = mapped_column(JSON, nullable=False)
@@ -0,0 +1,37 @@
1
+ """Business logic services"""
2
+
3
+ from .batch_processor import (
4
+ BatchFile,
5
+ BatchProcessingConfig,
6
+ BatchProcessingResult,
7
+ BatchProcessor,
8
+ batch_processor,
9
+ )
10
+ from .code_executor import (
11
+ CodeExecutionRequest,
12
+ CodeExecutionResponse,
13
+ CodeExecutorService,
14
+ ValidationResult,
15
+ code_executor,
16
+ )
17
+ from .sandbox import DockerSandbox, ExecutionResult, TestResult, sandbox
18
+ from .similarity_service import SimilarityService, similarity_service
19
+
20
+ __all__ = [
21
+ "DockerSandbox",
22
+ "ExecutionResult",
23
+ "TestResult",
24
+ "sandbox",
25
+ "CodeExecutorService",
26
+ "CodeExecutionRequest",
27
+ "CodeExecutionResponse",
28
+ "ValidationResult",
29
+ "code_executor",
30
+ "BatchProcessor",
31
+ "BatchProcessingConfig",
32
+ "BatchFile",
33
+ "BatchProcessingResult",
34
+ "batch_processor",
35
+ "SimilarityService",
36
+ "similarity_service",
37
+ ]