API: Upload new version of an extension #138
No reviewers
Labels
No Label
Priority
Critical
Priority
High
Priority
Low
Priority
Normal
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
Type
Breaking
Type
Documentation
Type
Enhancement
Type
Feature
Type
Report
Type
Security
Type
Suggestion
Type
Testing
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: infrastructure/extensions-website#138
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "tokens-version-api"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
URL: /api/v1/version-upload/
Method: POST
Parameters:
This patch includes: !134
3faa541385
to167b7fc30b
I suspect I may have to sanitize the release message, but not sure if it is needed.
WIP: This is failling the tests at the moment because it requires a token even to get the extensions listing.
API: Upload new version of an extensionto WIP: API: Upload new version of an extensionWIP: API: Upload new version of an extensionto API: Upload new version of an extensionoverall the api endpoint looks good, some comments inline
token handling is discussed in #134
@ -152,0 +196,4 @@
status=status.HTTP_403_FORBIDDEN,
)
try:
could we avoid this big try-except? what is the default drf error behavior?
we need to make sure that we are not leaking any error details in production - we will have the exception logged via sentry, and api users can't do anything useful with those details
@ -152,0 +210,4 @@
# Create the file instance
file_instance = form.save(commit=False)
file_instance.user = user
file_instance.save()
this save and the update_or_create below should ideally be together in the same transaction, we should wrap all db writes in one
with transaction.atomic():
@ -152,0 +226,4 @@
'extension_id': extension_id,
'version_file': version_file.name,
'release_notes': version.release_notes,
'version_id': version.id,
in UI we don't expose our internal ids, do we need to return this one here?
6b79f74233
tof4b3b0d4e7
Addressed the review comments.
Without the try/catch if I force an error I get one of the usual error screens:
But this probably only happens because I'm in a debug environment, right?
yes, that's normal in dev, in prod we will have a standard 500 error page
@ -0,0 +14,4 @@
TEST_FILES_DIR = Path(__file__).resolve().parent / 'files'
class VersionUploadAPITest(APITestCase):
should include a test for a non-authenticated request
returning 403 is ok: maybe not 100% correct from a purist perspective, but it serves the purpose
@ -0,0 +44,4 @@
'release_notes': 'These are the release notes',
},
format='multipart',
HTTP_AUTHORIZATION=f'Bearer {self.token.token}',
how does this part work now? we are not keeping a
token
field on the object anymore as far as i can tell@ -0,0 +85,4 @@
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertIn('version_id', response.data)
this assert must be failing now after the changes to the response
f4b3b0d4e7
tob8fe0d6929
I could not get the test to produce a 401 in this case. I'm checking for a 403, is that ok?
overall looks good, but let's change the url/parameter structure, as mentioned inline
@ -17,2 +17,4 @@
# API
path('api/v1/extensions/', api.ExtensionsAPIView.as_view(), name='api'),
path(
'api/v1/version-upload/',
sorry, haven't thought of this before, let's restructure the parameters: make them more in line with REST conventions, and get a nice bonus for logs transparency
the url becomes
api/v1/extensions/<extension_id>/versions/new/
, and theextension_id
in the body is not neededPending changes:
API: Upload new version of an extensionto WIP: API: Upload new version of an extension15e4287643
tof72b6c217c
All suggestions tackled
WIP: API: Upload new version of an extensionto API: Upload new version of an extension@ -154,0 +212,4 @@
file_instance.save()
# Create the version from the file
version = Version.objects.update_or_create(
btw, what's the use case for update here? why we are not just creating the object?
I guess I was just copying the same code we used on UploadFileView.form_valid. Which probably should be changed as well.
Anyways, changing the PR to use create(), and will merge after testing.
Apparently create_or_update is required because of the many-to-many relations.
Without it I get the following errors during test:
The error is:
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use licenses.set() instead.