Skip to content

Commit 065c91d

Browse files
committed
Fix up pre-commit
1 parent 17ddeb4 commit 065c91d

File tree

4 files changed

+75
-76
lines changed

4 files changed

+75
-76
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
exclude: '^pypi_view/static/bootstrap'
12
repos:
23
- repo: https://github.com/pre-commit/pre-commit-hooks
34
rev: v4.3.0

pypi_view/app.py

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,26 @@
44
import os.path
55
import re
66

7-
import pygments.lexers
8-
import pygments.lexers.special
97
import fluffy_code.code
108
import fluffy_code.prebuilt_styles
9+
import pygments.lexers.special
1110
from identify import identify
12-
from starlette.middleware.base import BaseHTTPMiddleware
13-
from starlette.middleware import Middleware
1411
from starlette.applications import Starlette
15-
from starlette.staticfiles import StaticFiles
12+
from starlette.middleware import Middleware
13+
from starlette.middleware.base import BaseHTTPMiddleware
1614
from starlette.requests import Request
17-
from starlette.responses import Response
1815
from starlette.responses import PlainTextResponse
1916
from starlette.responses import RedirectResponse
17+
from starlette.responses import Response
2018
from starlette.responses import StreamingResponse
21-
from starlette.routing import Route
19+
from starlette.staticfiles import StaticFiles
2220
from starlette.templating import Jinja2Templates
2321

2422
from pypi_view import packaging
2523
from pypi_view import pypi
2624

2725
PACKAGE_TYPE_NOT_SUPPORTED_ERROR = (
28-
"Sorry, this package type is not yet supported (only .zip and .whl supported currently)."
26+
'Sorry, this package type is not yet supported (only .zip and .whl supported currently).'
2927
)
3028
TEXT_RENDER_FILESIZE_LIMIT = 20 * 1024 # 20 KiB
3129

@@ -66,63 +64,63 @@ class CacheControlHeaderMiddleware(BaseHTTPMiddleware):
6664
async def dispatch(self, request, call_next):
6765
response = await call_next(request)
6866
# TODO: There should be a better way to do this...
69-
response.headers["Cache-Control"] = "no-cache"
67+
response.headers['Cache-Control'] = 'no-cache'
7068
return response
7169

7270

7371
app = Starlette(
74-
debug=os.environ.get("PYPI_VIEW_DEBUG") == "1",
72+
debug=os.environ.get('PYPI_VIEW_DEBUG') == '1',
7573
middleware=[
7674
Middleware(CacheControlHeaderMiddleware),
7775
],
7876
)
7977
app.mount('/static', StaticFiles(directory=os.path.join(install_root, 'static')), name='static')
8078

8179
templates = Jinja2Templates(
82-
directory=os.path.join(install_root, "templates"),
80+
directory=os.path.join(install_root, 'templates'),
8381
)
8482

8583

8684
@app.route('/')
8785
async def home(request: Request) -> Response:
88-
return templates.TemplateResponse("home.html", {"request": request})
86+
return templates.TemplateResponse('home.html', {'request': request})
8987

9088

9189
@app.route('/package/{package}')
9290
async def package(request: Request) -> Response:
93-
package_name = request.path_params["package"]
91+
package_name = request.path_params['package']
9492
try:
9593
version_to_files = await pypi.files_for_package(package_name)
9694
except pypi.PackageDoesNotExist:
9795
return PlainTextResponse(
98-
f"Package {package_name!r} does not exist on PyPI.",
96+
f'Package {package_name!r} does not exist on PyPI.',
9997
status_code=404,
10098
)
10199
else:
102100
return templates.TemplateResponse(
103-
"package.html",
101+
'package.html',
104102
{
105-
"request": request,
106-
"package": package_name,
107-
"version_to_files": version_to_files,
103+
'request': request,
104+
'package': package_name,
105+
'version_to_files': version_to_files,
108106
},
109107
)
110108

111109

112110
@app.route('/package/{package}/{filename}')
113111
async def package_file(request: Request) -> Response:
114-
package_name = request.path_params["package"]
115-
file_name = request.path_params["filename"]
112+
package_name = request.path_params['package']
113+
file_name = request.path_params['filename']
116114
try:
117115
archive = await pypi.downloaded_file_path(package_name, file_name)
118116
except pypi.PackageDoesNotExist:
119117
return PlainTextResponse(
120-
f"Package {package_name!r} does not exist on PyPI.",
118+
f'Package {package_name!r} does not exist on PyPI.',
121119
status_code=404,
122120
)
123121
except pypi.CannotFindFileError:
124122
return PlainTextResponse(
125-
f"File {file_name!r} does not exist for package {package_name!r}.",
123+
f'File {file_name!r} does not exist for package {package_name!r}.',
126124
status_code=404,
127125
)
128126

@@ -138,14 +136,15 @@ async def package_file(request: Request) -> Response:
138136
metadata_entries = [
139137
entry
140138
for entry in entries
141-
if re.match(r'(?:[^/]+\.dist-info/METADATA|^[^/]+/PKG-INFO)$', entry.path) and entry.size <= TEXT_RENDER_FILESIZE_LIMIT
139+
if re.match(r'(?:[^/]+\.dist-info/METADATA|^[^/]+/PKG-INFO)$', entry.path)
140+
and entry.size <= TEXT_RENDER_FILESIZE_LIMIT
142141
]
143142
if len(metadata_entries) > 0:
144143
metadata_path = metadata_entries[0].path
145144
metadata = {}
146145

147146
async with package.open_from_archive(metadata_path) as f:
148-
metadata_file = io.StringIO((await f.read()).decode("utf8", errors="ignore"))
147+
metadata_file = io.StringIO((await f.read()).decode('utf8', errors='ignore'))
149148

150149
message = email.message_from_file(metadata_file)
151150
metadata = {
@@ -156,35 +155,34 @@ async def package_file(request: Request) -> Response:
156155
metadata_path = None
157156
metadata = {}
158157

159-
160158
return templates.TemplateResponse(
161-
"package_file.html",
159+
'package_file.html',
162160
{
163-
"request": request,
164-
"package": package_name,
165-
"filename": file_name,
166-
"entries": entries,
167-
"metadata_path": metadata_path,
168-
"metadata": metadata,
161+
'request': request,
162+
'package': package_name,
163+
'filename': file_name,
164+
'entries': entries,
165+
'metadata_path': metadata_path,
166+
'metadata': metadata,
169167
},
170168
)
171169

172170

173171
@app.route('/package/{package}/{filename}/{archive_path:path}')
174172
async def package_file_archive_path(request: Request) -> Response:
175-
package_name = request.path_params["package"]
176-
file_name = request.path_params["filename"]
177-
archive_path = request.path_params["archive_path"]
173+
package_name = request.path_params['package']
174+
file_name = request.path_params['filename']
175+
archive_path = request.path_params['archive_path']
178176
try:
179177
archive = await pypi.downloaded_file_path(package_name, file_name)
180178
except pypi.PackageDoesNotExist:
181179
return PlainTextResponse(
182-
f"Package {package_name!r} does not exist on PyPI.",
180+
f'Package {package_name!r} does not exist on PyPI.',
183181
status_code=404,
184182
)
185183
except pypi.CannotFindFileError:
186184
return PlainTextResponse(
187-
f"File {file_name!r} does not exist for package {package_name!r}.",
185+
f'File {file_name!r} does not exist for package {package_name!r}.',
188186
status_code=404,
189187
)
190188
try:
@@ -199,7 +197,7 @@ async def package_file_archive_path(request: Request) -> Response:
199197
matching_entries = [entry for entry in entries if entry.path == archive_path]
200198
if len(matching_entries) == 0:
201199
return PlainTextResponse(
202-
f"Path {archive_path!r} does not exist in archive.",
200+
f'Path {archive_path!r} does not exist in archive.',
203201
status_code=404,
204202
)
205203
entry = matching_entries[0]
@@ -216,11 +214,11 @@ async def transfer_file():
216214

217215
return StreamingResponse(
218216
transfer_file(),
219-
media_type=mimetype if (mimetype or "").startswith(MIME_WHITELIST) else None,
220-
headers={"Content-Length": str(entry.size)},
217+
media_type=mimetype if (mimetype or '').startswith(MIME_WHITELIST) else None,
218+
headers={'Content-Length': str(entry.size)},
221219
)
222220

223-
if "raw" in request.query_params:
221+
if 'raw' in request.query_params:
224222
return _transfer_raw()
225223

226224
# There are a few cases to handle here:
@@ -258,46 +256,46 @@ async def transfer_file():
258256
lexer = pygments.lexers.special.TextLexer()
259257

260258
return templates.TemplateResponse(
261-
"package_file_archive_path.html",
259+
'package_file_archive_path.html',
262260
{
263-
"request": request,
264-
"package": package_name,
265-
"filename": file_name,
266-
"archive_path": archive_path,
267-
"rendered_text": fluffy_code.code.render(
261+
'request': request,
262+
'package': package_name,
263+
'filename': file_name,
264+
'archive_path': archive_path,
265+
'rendered_text': fluffy_code.code.render(
268266
first_chunk,
269267
style_config=style_config,
270268
highlight_config=fluffy_code.code.HighlightConfig(
271269
lexer=lexer,
272270
highlight_diff=False,
273271
),
274272
),
275-
"extra_css": fluffy_code.code.get_global_css() + "\n" + style_config.css,
276-
"extra_js": fluffy_code.code.get_global_javascript(),
273+
'extra_css': fluffy_code.code.get_global_css() + '\n' + style_config.css,
274+
'extra_js': fluffy_code.code.get_global_javascript(),
277275
},
278276
)
279277
else:
280278
# Case 2: too long to syntax highlight.
281279
return templates.TemplateResponse(
282-
"package_file_archive_path_cannot_render.html",
280+
'package_file_archive_path_cannot_render.html',
283281
{
284-
"request": request,
285-
"package": package_name,
286-
"filename": file_name,
287-
"archive_path": archive_path,
288-
"error": "This file is too long to syntax highlight.",
282+
'request': request,
283+
'package': package_name,
284+
'filename': file_name,
285+
'archive_path': archive_path,
286+
'error': 'This file is too long to syntax highlight.',
289287
},
290288
)
291289

292290
# Case 4: link to binary
293291
return templates.TemplateResponse(
294-
"package_file_archive_path_cannot_render.html",
292+
'package_file_archive_path_cannot_render.html',
295293
{
296-
"request": request,
297-
"package": package_name,
298-
"filename": file_name,
299-
"archive_path": archive_path,
300-
"error": "This file appears to be a binary.",
294+
'request': request,
295+
'package': package_name,
296+
'filename': file_name,
297+
'archive_path': archive_path,
298+
'error': 'This file appears to be a binary.',
301299
},
302300
)
303301

pypi_view/packaging.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AsyncArchiveFile:
5151
def __init__(self, file_: ArchiveFile) -> None:
5252
self.file_ = file_
5353

54-
async def __aenter__(self) -> "AsyncArchiveFile":
54+
async def __aenter__(self) -> 'AsyncArchiveFile':
5555
return self
5656

5757
async def __aexit__(self, exc_t, exc_v, exc_tb) -> None:
@@ -68,13 +68,13 @@ class Package:
6868
path: str
6969

7070
@classmethod
71-
def from_path(cls, path: str) -> "Package":
72-
name = base64.b64decode(os.path.basename(path).encode("ascii")).decode("utf8")
71+
def from_path(cls, path: str) -> 'Package':
72+
name = base64.b64decode(os.path.basename(path).encode('ascii')).decode('utf8')
7373

74-
if name.endswith(".whl"):
74+
if name.endswith('.whl'):
7575
package_type = PackageType.WHEEL
7676
package_format = PackageFormat.ZIPFILE
77-
elif name.endswith(".zip"):
77+
elif name.endswith('.zip'):
7878
package_type = PackageType.SDIST
7979
package_format = PackageFormat.ZIPFILE
8080
else:

pypi_view/pypi.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import base64
22
import contextlib
3-
import os.path
43
import itertools
4+
import os.path
55
import typing
66

7-
import aiofiles
87
import aiofiles.os
98
import httpx
109

@@ -31,8 +30,8 @@ async def files_for_package(package: str) -> typing.Dict[str, typing.Set[str]]:
3130
metadata = await package_metadata(client, package)
3231

3332
return {
34-
version: {file_["filename"] for file_ in files}
35-
for version, files in metadata["releases"].items()
33+
version: {file_['filename'] for file_ in files}
34+
for version, files in metadata['releases'].items()
3635
}
3736

3837

@@ -45,16 +44,17 @@ def _storage_path(package: str, filename: str) -> str:
4544
STORAGE_DIR,
4645
# Base64-encoding the names to calculate the storage path just to be
4746
# extra sure to avoid any path traversal vulnerabilities.
48-
base64.urlsafe_b64encode(package.encode("utf8")).decode("ascii"),
49-
base64.urlsafe_b64encode(filename.encode("utf8")).decode("ascii"),
47+
base64.urlsafe_b64encode(package.encode('utf8')).decode('ascii'),
48+
base64.urlsafe_b64encode(filename.encode('utf8')).decode('ascii'),
5049
)
5150

51+
5252
@contextlib.asynccontextmanager
5353
async def _atomic_file(path: str, mode: str = 'w') -> typing.Any:
5454
async with aiofiles.tempfile.NamedTemporaryFile(mode, dir=os.path.dirname(path), delete=False) as f:
5555
try:
5656
yield f
57-
except:
57+
except BaseException:
5858
await aiofiles.os.remove(f.name)
5959
raise
6060
else:
@@ -78,9 +78,9 @@ async def downloaded_file_path(package: str, filename: str) -> str:
7878
# Parsing versions from non-wheel Python packages isn't perfectly
7979
# reliable, so just search through all releases until we find a
8080
# matching file.
81-
for file_ in itertools.chain.from_iterable(metadata["releases"].values()):
82-
if file_["filename"] == filename:
83-
url = file_["url"]
81+
for file_ in itertools.chain.from_iterable(metadata['releases'].values()):
82+
if file_['filename'] == filename:
83+
url = file_['url']
8484
break
8585
else:
8686
raise CannotFindFileError(package, filename)

0 commit comments

Comments
 (0)