init
This commit is contained in:
497
API.md
Normal file
497
API.md
Normal file
@@ -0,0 +1,497 @@
|
||||
# API Documentation
|
||||
|
||||
Complete API reference for the Test Artifact Data Lake.
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
http://localhost:8000
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Currently, the API does not require authentication. Add authentication middleware as needed for your deployment.
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
### Root
|
||||
|
||||
#### GET /
|
||||
|
||||
Get API information.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Test Artifact Data Lake API",
|
||||
"version": "1.0.0",
|
||||
"docs": "/docs",
|
||||
"storage_backend": "minio"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Health Check
|
||||
|
||||
#### GET /health
|
||||
|
||||
Health check endpoint for monitoring.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"status": "healthy"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Upload Artifact
|
||||
|
||||
#### POST /api/v1/artifacts/upload
|
||||
|
||||
Upload a new artifact file with metadata.
|
||||
|
||||
**Content-Type:** `multipart/form-data`
|
||||
|
||||
**Form Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| file | File | Yes | The file to upload |
|
||||
| test_name | String | No | Name of the test |
|
||||
| test_suite | String | No | Test suite identifier |
|
||||
| test_config | JSON String | No | Test configuration (must be valid JSON) |
|
||||
| test_result | String | No | Test result: pass, fail, skip, error |
|
||||
| metadata | JSON String | No | Additional metadata (must be valid JSON) |
|
||||
| description | String | No | Text description |
|
||||
| tags | JSON Array String | No | Array of tags (must be valid JSON array) |
|
||||
| version | String | No | Version identifier |
|
||||
| parent_id | Integer | No | ID of parent artifact (for versioning) |
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/artifacts/upload" \
|
||||
-F "file=@results.csv" \
|
||||
-F "test_name=login_test" \
|
||||
-F "test_suite=authentication" \
|
||||
-F "test_result=pass" \
|
||||
-F 'test_config={"browser":"chrome","timeout":30}' \
|
||||
-F 'tags=["regression","smoke"]' \
|
||||
-F "description=Login functionality test"
|
||||
```
|
||||
|
||||
**Response (201 Created):**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"filename": "results.csv",
|
||||
"file_type": "csv",
|
||||
"file_size": 1024,
|
||||
"storage_path": "minio://test-artifacts/abc-123.csv",
|
||||
"content_type": "text/csv",
|
||||
"test_name": "login_test",
|
||||
"test_suite": "authentication",
|
||||
"test_config": {"browser": "chrome", "timeout": 30},
|
||||
"test_result": "pass",
|
||||
"metadata": null,
|
||||
"description": "Login functionality test",
|
||||
"tags": ["regression", "smoke"],
|
||||
"created_at": "2024-10-14T12:00:00",
|
||||
"updated_at": "2024-10-14T12:00:00",
|
||||
"version": null,
|
||||
"parent_id": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Get Artifact Metadata
|
||||
|
||||
#### GET /api/v1/artifacts/{artifact_id}
|
||||
|
||||
Retrieve artifact metadata by ID.
|
||||
|
||||
**Path Parameters:**
|
||||
- `artifact_id` (integer): The artifact ID
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/artifacts/1"
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"filename": "results.csv",
|
||||
"file_type": "csv",
|
||||
"file_size": 1024,
|
||||
"storage_path": "minio://test-artifacts/abc-123.csv",
|
||||
"content_type": "text/csv",
|
||||
"test_name": "login_test",
|
||||
"test_suite": "authentication",
|
||||
"test_config": {"browser": "chrome"},
|
||||
"test_result": "pass",
|
||||
"metadata": null,
|
||||
"description": "Login test",
|
||||
"tags": ["regression"],
|
||||
"created_at": "2024-10-14T12:00:00",
|
||||
"updated_at": "2024-10-14T12:00:00",
|
||||
"version": null,
|
||||
"parent_id": null
|
||||
}
|
||||
```
|
||||
|
||||
**Error Response (404 Not Found):**
|
||||
```json
|
||||
{
|
||||
"detail": "Artifact not found"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Download Artifact
|
||||
|
||||
#### GET /api/v1/artifacts/{artifact_id}/download
|
||||
|
||||
Download the artifact file.
|
||||
|
||||
**Path Parameters:**
|
||||
- `artifact_id` (integer): The artifact ID
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/artifacts/1/download" \
|
||||
-o downloaded_file.csv
|
||||
```
|
||||
|
||||
**Response:**
|
||||
- Returns the file with appropriate `Content-Type` and `Content-Disposition` headers
|
||||
- Status: 200 OK
|
||||
|
||||
**Error Response (404 Not Found):**
|
||||
```json
|
||||
{
|
||||
"detail": "Artifact not found"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Get Presigned URL
|
||||
|
||||
#### GET /api/v1/artifacts/{artifact_id}/url
|
||||
|
||||
Get a presigned URL for downloading the artifact.
|
||||
|
||||
**Path Parameters:**
|
||||
- `artifact_id` (integer): The artifact ID
|
||||
|
||||
**Query Parameters:**
|
||||
- `expiration` (integer, optional): URL expiration in seconds (60-86400). Default: 3600
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/artifacts/1/url?expiration=3600"
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"url": "https://minio.example.com/test-artifacts/abc-123.csv?X-Amz-Algorithm=...",
|
||||
"expires_in": 3600
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Query Artifacts
|
||||
|
||||
#### POST /api/v1/artifacts/query
|
||||
|
||||
Query artifacts with filters.
|
||||
|
||||
**Content-Type:** `application/json`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| filename | String | No | Filter by filename (partial match) |
|
||||
| file_type | String | No | Filter by file type (csv, json, binary, pcap) |
|
||||
| test_name | String | No | Filter by test name (partial match) |
|
||||
| test_suite | String | No | Filter by test suite (exact match) |
|
||||
| test_result | String | No | Filter by test result (pass, fail, skip, error) |
|
||||
| tags | Array[String] | No | Filter by tags (must contain all specified tags) |
|
||||
| start_date | DateTime | No | Filter by creation date (from) |
|
||||
| end_date | DateTime | No | Filter by creation date (to) |
|
||||
| limit | Integer | No | Maximum results (1-1000). Default: 100 |
|
||||
| offset | Integer | No | Number of results to skip. Default: 0 |
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/artifacts/query" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"test_suite": "authentication",
|
||||
"test_result": "fail",
|
||||
"start_date": "2024-01-01T00:00:00",
|
||||
"end_date": "2024-12-31T23:59:59",
|
||||
"tags": ["regression"],
|
||||
"limit": 50,
|
||||
"offset": 0
|
||||
}'
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 5,
|
||||
"filename": "auth_fail.csv",
|
||||
"file_type": "csv",
|
||||
"file_size": 2048,
|
||||
"storage_path": "minio://test-artifacts/def-456.csv",
|
||||
"content_type": "text/csv",
|
||||
"test_name": "login_test",
|
||||
"test_suite": "authentication",
|
||||
"test_config": {"browser": "firefox"},
|
||||
"test_result": "fail",
|
||||
"metadata": {"error": "timeout"},
|
||||
"description": "Failed login test",
|
||||
"tags": ["regression"],
|
||||
"created_at": "2024-10-14T11:00:00",
|
||||
"updated_at": "2024-10-14T11:00:00",
|
||||
"version": null,
|
||||
"parent_id": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### List Artifacts
|
||||
|
||||
#### GET /api/v1/artifacts/
|
||||
|
||||
List all artifacts with pagination.
|
||||
|
||||
**Query Parameters:**
|
||||
- `limit` (integer, optional): Maximum results (1-1000). Default: 100
|
||||
- `offset` (integer, optional): Number of results to skip. Default: 0
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/artifacts/?limit=50&offset=0"
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"filename": "test1.csv",
|
||||
...
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"filename": "test2.json",
|
||||
...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Delete Artifact
|
||||
|
||||
#### DELETE /api/v1/artifacts/{artifact_id}
|
||||
|
||||
Delete an artifact and its file from storage.
|
||||
|
||||
**Path Parameters:**
|
||||
- `artifact_id` (integer): The artifact ID
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:8000/api/v1/artifacts/1"
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"message": "Artifact deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Error Response (404 Not Found):**
|
||||
```json
|
||||
{
|
||||
"detail": "Artifact not found"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Types
|
||||
|
||||
The API automatically detects file types based on extension:
|
||||
|
||||
| Extension | File Type |
|
||||
|-----------|-----------|
|
||||
| .csv | csv |
|
||||
| .json | json |
|
||||
| .pcap, .pcapng | pcap |
|
||||
| .bin, .dat | binary |
|
||||
| Others | binary |
|
||||
|
||||
---
|
||||
|
||||
## Error Responses
|
||||
|
||||
### 400 Bad Request
|
||||
Invalid request parameters or malformed JSON.
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Invalid JSON in metadata fields: ..."
|
||||
}
|
||||
```
|
||||
|
||||
### 404 Not Found
|
||||
Resource not found.
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Artifact not found"
|
||||
}
|
||||
```
|
||||
|
||||
### 500 Internal Server Error
|
||||
Server error during processing.
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Upload failed: ..."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interactive Documentation
|
||||
|
||||
The API provides interactive documentation at:
|
||||
|
||||
- **Swagger UI:** http://localhost:8000/docs
|
||||
- **ReDoc:** http://localhost:8000/redoc
|
||||
|
||||
These interfaces allow you to:
|
||||
- Explore all endpoints
|
||||
- View request/response schemas
|
||||
- Test API calls directly in the browser
|
||||
- Download OpenAPI specification
|
||||
|
||||
---
|
||||
|
||||
## Client Libraries
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# Upload file
|
||||
with open('test.csv', 'rb') as f:
|
||||
files = {'file': f}
|
||||
data = {
|
||||
'test_name': 'my_test',
|
||||
'test_suite': 'integration',
|
||||
'test_result': 'pass',
|
||||
'tags': '["smoke"]'
|
||||
}
|
||||
response = requests.post(
|
||||
'http://localhost:8000/api/v1/artifacts/upload',
|
||||
files=files,
|
||||
data=data
|
||||
)
|
||||
artifact = response.json()
|
||||
print(f"Uploaded artifact ID: {artifact['id']}")
|
||||
|
||||
# Query artifacts
|
||||
query = {
|
||||
'test_suite': 'integration',
|
||||
'test_result': 'fail',
|
||||
'limit': 10
|
||||
}
|
||||
response = requests.post(
|
||||
'http://localhost:8000/api/v1/artifacts/query',
|
||||
json=query
|
||||
)
|
||||
artifacts = response.json()
|
||||
|
||||
# Download file
|
||||
artifact_id = 1
|
||||
response = requests.get(
|
||||
f'http://localhost:8000/api/v1/artifacts/{artifact_id}/download'
|
||||
)
|
||||
with open('downloaded.csv', 'wb') as f:
|
||||
f.write(response.content)
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
// Upload file
|
||||
const formData = new FormData();
|
||||
formData.append('file', fileInput.files[0]);
|
||||
formData.append('test_name', 'my_test');
|
||||
formData.append('test_suite', 'integration');
|
||||
formData.append('tags', JSON.stringify(['smoke']));
|
||||
|
||||
const response = await fetch('http://localhost:8000/api/v1/artifacts/upload', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
const artifact = await response.json();
|
||||
|
||||
// Query artifacts
|
||||
const query = {
|
||||
test_suite: 'integration',
|
||||
test_result: 'fail',
|
||||
limit: 10
|
||||
};
|
||||
|
||||
const queryResponse = await fetch('http://localhost:8000/api/v1/artifacts/query', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(query)
|
||||
});
|
||||
const artifacts = await queryResponse.json();
|
||||
```
|
||||
|
||||
### cURL
|
||||
|
||||
See examples throughout this documentation.
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Currently not implemented. Add rate limiting middleware as needed.
|
||||
|
||||
---
|
||||
|
||||
## Versioning
|
||||
|
||||
The API is versioned via the URL path (`/api/v1/`). Future versions will use `/api/v2/`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For API questions or issues, please refer to the main [README.md](README.md) or open an issue.
|
||||
Reference in New Issue
Block a user