This commit is contained in:
Nick Sweeting
2025-12-28 17:51:54 -08:00
parent 54f91c1339
commit f0aa19fa7d
157 changed files with 6774 additions and 5061 deletions

View File

@@ -5,7 +5,7 @@ from signal_webhooks.utils import get_webhook_model
from archivebox.base_models.admin import BaseModelAdmin
from api.models import APIToken
from archivebox.api.models import APIToken
class APITokenAdmin(BaseModelAdmin):

View File

@@ -4,9 +4,9 @@ from django.apps import AppConfig
class APIConfig(AppConfig):
name = 'api'
name = 'archivebox.api'
def register_admin(admin_site):
from api.admin import register_admin
from archivebox.api.admin import register_admin
register_admin(admin_site)

View File

@@ -7,7 +7,7 @@ from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import api.models
import archivebox.api.models
class Migration(migrations.Migration):
@@ -38,7 +38,7 @@ class Migration(migrations.Migration):
('created_by', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('modified_at', models.DateTimeField(auto_now=True)),
('token', models.CharField(default=api.models.generate_secret_token, max_length=32, unique=True)),
('token', models.CharField(default=archivebox.api.models.generate_secret_token, max_length=32, unique=True)),
('expires', models.DateTimeField(blank=True, null=True)),
],
options={

View File

@@ -1,6 +1,6 @@
# Generated by Django 6.0 on 2025-12-27 01:40
import base_models.models
import archivebox.core.models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
@@ -17,11 +17,11 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='apitoken',
name='created_by',
field=models.ForeignKey(default=base_models.models.get_or_create_system_user_pk, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(default=archivebox.core.models.get_or_create_system_user_pk, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='outboundwebhook',
name='created_by',
field=models.ForeignKey(default=base_models.models.get_or_create_system_user_pk, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(default=archivebox.core.models.get_or_create_system_user_pk, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -10,7 +10,7 @@ from django.utils import timezone
from django_stubs_ext.db.models import TypedModelMeta
from signal_webhooks.models import WebhookBase
from base_models.models import get_or_create_system_user_pk
from archivebox.base_models.models import get_or_create_system_user_pk
def generate_secret_token() -> str:
@@ -26,6 +26,7 @@ class APIToken(models.Model):
expires = models.DateTimeField(null=True, blank=True)
class Meta(TypedModelMeta):
app_label = 'api'
verbose_name = "API Key"
verbose_name_plural = "API Keys"
@@ -47,6 +48,7 @@ class OutboundWebhook(WebhookBase):
modified_at = models.DateTimeField(auto_now=True)
class Meta(WebhookBase.Meta):
app_label = 'api'
verbose_name = 'API Outbound Webhook'
def __str__(self) -> str:

View File

@@ -15,7 +15,7 @@ from ninja import NinjaAPI, Swagger
from archivebox.config import VERSION
from archivebox.config.version import get_COMMIT_HASH
from api.auth import API_AUTH_METHODS
from archivebox.api.auth import API_AUTH_METHODS
COMMIT_HASH = get_COMMIT_HASH() or 'unknown'

View File

@@ -6,8 +6,8 @@ from ninja import Router, Schema
from django.utils import timezone
from datetime import timedelta
from api.models import APIToken
from api.auth import auth_using_token, auth_using_password, get_or_create_api_token
from archivebox.api.models import APIToken
from archivebox.api.auth import auth_using_token, auth_using_password, get_or_create_api_token
router = Router(tags=['Authentication'], auth=None)

View File

@@ -118,6 +118,7 @@ def cli_add(request, args: AddCommandSchema):
plugins=args.plugins,
parser=args.parser,
bg=True, # Always run in background for API calls
created_by_id=request.user.pk,
)
return {

View File

@@ -14,8 +14,8 @@ from ninja import Router, Schema, FilterSchema, Field, Query
from ninja.pagination import paginate, PaginationBase
from ninja.errors import HttpError
from core.models import Snapshot, ArchiveResult, Tag
from api.v1_crawls import CrawlSchema
from archivebox.core.models import Snapshot, ArchiveResult, Tag
from archivebox.api.v1_crawls import CrawlSchema
router = Router(tags=['Core Models'])
@@ -80,12 +80,11 @@ class MinimalArchiveResultSchema(Schema):
@staticmethod
def resolve_created_by_id(obj):
return str(obj.created_by_id)
return str(obj.created_by.pk)
@staticmethod
def resolve_created_by_username(obj) -> str:
User = get_user_model()
return User.objects.filter(pk=obj.created_by_id).values_list('username', flat=True)[0]
return obj.created_by.username
class ArchiveResultSchema(MinimalArchiveResultSchema):
@@ -166,12 +165,11 @@ class SnapshotSchema(Schema):
@staticmethod
def resolve_created_by_id(obj):
return str(obj.created_by_id)
return str(obj.created_by.pk)
@staticmethod
def resolve_created_by_username(obj):
User = get_user_model()
return User.objects.get(id=obj.created_by_id).username
return obj.created_by.username
@staticmethod
def resolve_tags(obj):
@@ -190,8 +188,8 @@ class SnapshotSchema(Schema):
class SnapshotFilterSchema(FilterSchema):
id: Optional[str] = Field(None, q=['id__icontains', 'timestamp__startswith'])
created_by_id: str = Field(None, q='created_by_id')
created_by_username: str = Field(None, q='created_by__username__icontains')
created_by_id: str = Field(None, q='crawl__created_by_id')
created_by_username: str = Field(None, q='crawl__created_by__username__icontains')
created_at__gte: datetime = Field(None, q='created_at__gte')
created_at__lt: datetime = Field(None, q='created_at__lt')
created_at: datetime = Field(None, q='created_at')

View File

@@ -9,8 +9,8 @@ from django.contrib.auth import get_user_model
from ninja import Router, Schema
from core.models import Snapshot
from crawls.models import Crawl
from archivebox.core.models import Snapshot
from archivebox.crawls.models import Crawl
from .auth import API_AUTH_METHODS

View File

@@ -7,7 +7,7 @@ from datetime import datetime
from ninja import Router, Schema, FilterSchema, Field, Query
from ninja.pagination import paginate
from api.v1_core import CustomPagination
from archivebox.api.v1_core import CustomPagination
router = Router(tags=['Machine and Dependencies'])
@@ -102,14 +102,14 @@ class BinaryFilterSchema(FilterSchema):
@paginate(CustomPagination)
def get_machines(request, filters: MachineFilterSchema = Query(...)):
"""List all machines."""
from machine.models import Machine
from archivebox.machine.models import Machine
return filters.filter(Machine.objects.all()).distinct()
@router.get("/machine/{machine_id}", response=MachineSchema, url_name="get_machine")
def get_machine(request, machine_id: str):
"""Get a specific machine by ID."""
from machine.models import Machine
from archivebox.machine.models import Machine
from django.db.models import Q
return Machine.objects.get(Q(id__startswith=machine_id) | Q(hostname__iexact=machine_id))
@@ -117,7 +117,7 @@ def get_machine(request, machine_id: str):
@router.get("/machine/current", response=MachineSchema, url_name="get_current_machine")
def get_current_machine(request):
"""Get the current machine."""
from machine.models import Machine
from archivebox.machine.models import Machine
return Machine.current()
@@ -132,19 +132,19 @@ def get_current_machine(request):
@paginate(CustomPagination)
def get_binaries(request, filters: BinaryFilterSchema = Query(...)):
"""List all binaries."""
from machine.models import Binary
from archivebox.machine.models import Binary
return filters.filter(Binary.objects.all().select_related('machine', 'dependency')).distinct()
@router.get("/binary/{binary_id}", response=BinarySchema, url_name="get_binary")
def get_binary(request, binary_id: str):
"""Get a specific binary by ID."""
from machine.models import Binary
from archivebox.machine.models import Binary
return Binary.objects.select_related('machine', 'dependency').get(id__startswith=binary_id)
@router.get("/binary/by-name/{name}", response=List[BinarySchema], url_name="get_binaries_by_name")
def get_binaries_by_name(request, name: str):
"""Get all binaries with the given name."""
from machine.models import Binary
from archivebox.machine.models import Binary
return list(Binary.objects.filter(name__iexact=name).select_related('machine', 'dependency'))