tuspyserver 2.2.0__tar.gz → 2.2.2__tar.gz

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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: tuspyserver
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: TUS py protocol implementation in FastAPI
5
5
  Home-page: https://github.com/edihasaj/tuspy-fast-api
6
6
  Author: Edi Hasaj
@@ -15,19 +15,6 @@ Classifier: Programming Language :: Python
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: fastapi>=0.110.0
19
- Requires-Dist: pydantic>=2.6.2
20
- Dynamic: author
21
- Dynamic: author-email
22
- Dynamic: classifier
23
- Dynamic: description
24
- Dynamic: description-content-type
25
- Dynamic: home-page
26
- Dynamic: license
27
- Dynamic: license-file
28
- Dynamic: platform
29
- Dynamic: requires-dist
30
- Dynamic: summary
31
18
 
32
19
  # FastAPI Tus
33
20
 
@@ -50,8 +37,8 @@ pip install tuspyserver
50
37
  Or install directly from source:
51
38
 
52
39
  ```bash
53
- git clone https://github.com/your-org/tuspyserver.git
54
- cd tuspyserver
40
+ git clone https://github.com/edihasaj/tuspy-fast-api
41
+ cd tuspy-fast-api
55
42
  pip install .
56
43
  ```
57
44
 
@@ -74,6 +61,15 @@ app.add_middleware(
74
61
  allow_origins=["*"],
75
62
  allow_methods=["*"],
76
63
  allow_headers=["*"],
64
+ expose_headers=[
65
+ "Location",
66
+ "Upload-Offset",
67
+ "Tus-Resumable",
68
+ "Tus-Version",
69
+ "Tus-Extension",
70
+ "Tus-Max-Size",
71
+ "Upload-Expires",
72
+ ],
77
73
  )
78
74
  app.mount("/static", StaticFiles(directory="static"), name="static")
79
75
 
@@ -91,6 +87,27 @@ app.include_router(
91
87
  prefix="files", # OPTIONAL: URL prefix (default: 'files')
92
88
  ),
93
89
  )
90
+
91
+ ```
92
+
93
+ ### !Warning If you include your own router then it is necessary that your app allows these Headers:
94
+
95
+ ```python
96
+ app.add_middleware(
97
+ CORSMiddleware, (# OPTIONAL: add CORS middleware if needed)
98
+ allow_origins=["*"], # OPTIONAL: allow all origins
99
+ allow_methods=["*"], # OPTIONAL: allow all methods
100
+ allow_headers=["*"], # OPTIONAL: allow all headers
101
+ expose_headers=[ # REQUIRED: expose these headers to the client
102
+ "Location",
103
+ "Upload-Offset",
104
+ "Tus-Resumable",
105
+ "Tus-Version",
106
+ "Tus-Extension",
107
+ "Tus-Max-Size",
108
+ "Upload-Expires",
109
+ ],
110
+ )
94
111
  ```
95
112
 
96
113
  ### Dependency‑Injected Hook (Advanced)
@@ -161,6 +178,6 @@ scheduler.start()
161
178
 
162
179
  ## Contributing
163
180
 
164
- Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/your-org/tuspyserver).
181
+ Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/edihasaj/tuspy-fast-api).
165
182
 
166
183
  *© 2025 Edi Hasaj [X](https://x.com/hasajedi)*
@@ -19,8 +19,8 @@ pip install tuspyserver
19
19
  Or install directly from source:
20
20
 
21
21
  ```bash
22
- git clone https://github.com/your-org/tuspyserver.git
23
- cd tuspyserver
22
+ git clone https://github.com/edihasaj/tuspy-fast-api
23
+ cd tuspy-fast-api
24
24
  pip install .
25
25
  ```
26
26
 
@@ -43,6 +43,15 @@ app.add_middleware(
43
43
  allow_origins=["*"],
44
44
  allow_methods=["*"],
45
45
  allow_headers=["*"],
46
+ expose_headers=[
47
+ "Location",
48
+ "Upload-Offset",
49
+ "Tus-Resumable",
50
+ "Tus-Version",
51
+ "Tus-Extension",
52
+ "Tus-Max-Size",
53
+ "Upload-Expires",
54
+ ],
46
55
  )
47
56
  app.mount("/static", StaticFiles(directory="static"), name="static")
48
57
 
@@ -60,6 +69,27 @@ app.include_router(
60
69
  prefix="files", # OPTIONAL: URL prefix (default: 'files')
61
70
  ),
62
71
  )
72
+
73
+ ```
74
+
75
+ ### !Warning If you include your own router then it is necessary that your app allows these Headers:
76
+
77
+ ```python
78
+ app.add_middleware(
79
+ CORSMiddleware, (# OPTIONAL: add CORS middleware if needed)
80
+ allow_origins=["*"], # OPTIONAL: allow all origins
81
+ allow_methods=["*"], # OPTIONAL: allow all methods
82
+ allow_headers=["*"], # OPTIONAL: allow all headers
83
+ expose_headers=[ # REQUIRED: expose these headers to the client
84
+ "Location",
85
+ "Upload-Offset",
86
+ "Tus-Resumable",
87
+ "Tus-Version",
88
+ "Tus-Extension",
89
+ "Tus-Max-Size",
90
+ "Upload-Expires",
91
+ ],
92
+ )
63
93
  ```
64
94
 
65
95
  ### Dependency‑Injected Hook (Advanced)
@@ -130,6 +160,6 @@ scheduler.start()
130
160
 
131
161
  ## Contributing
132
162
 
133
- Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/your-org/tuspyserver).
163
+ Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/edihasaj/tuspy-fast-api).
134
164
 
135
165
  *© 2025 Edi Hasaj [X](https://x.com/hasajedi)*
@@ -12,7 +12,7 @@ with open("README.md", "r") as f:
12
12
 
13
13
  setup(
14
14
  name="tuspyserver",
15
- version="2.2.0",
15
+ version="2.2.2",
16
16
  description="TUS py protocol implementation in FastAPI",
17
17
  long_description=long_description,
18
18
  long_description_content_type="text/markdown",
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: tuspyserver
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: TUS py protocol implementation in FastAPI
5
5
  Home-page: https://github.com/edihasaj/tuspy-fast-api
6
6
  Author: Edi Hasaj
@@ -15,19 +15,6 @@ Classifier: Programming Language :: Python
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: fastapi>=0.110.0
19
- Requires-Dist: pydantic>=2.6.2
20
- Dynamic: author
21
- Dynamic: author-email
22
- Dynamic: classifier
23
- Dynamic: description
24
- Dynamic: description-content-type
25
- Dynamic: home-page
26
- Dynamic: license
27
- Dynamic: license-file
28
- Dynamic: platform
29
- Dynamic: requires-dist
30
- Dynamic: summary
31
18
 
32
19
  # FastAPI Tus
33
20
 
@@ -50,8 +37,8 @@ pip install tuspyserver
50
37
  Or install directly from source:
51
38
 
52
39
  ```bash
53
- git clone https://github.com/your-org/tuspyserver.git
54
- cd tuspyserver
40
+ git clone https://github.com/edihasaj/tuspy-fast-api
41
+ cd tuspy-fast-api
55
42
  pip install .
56
43
  ```
57
44
 
@@ -74,6 +61,15 @@ app.add_middleware(
74
61
  allow_origins=["*"],
75
62
  allow_methods=["*"],
76
63
  allow_headers=["*"],
64
+ expose_headers=[
65
+ "Location",
66
+ "Upload-Offset",
67
+ "Tus-Resumable",
68
+ "Tus-Version",
69
+ "Tus-Extension",
70
+ "Tus-Max-Size",
71
+ "Upload-Expires",
72
+ ],
77
73
  )
78
74
  app.mount("/static", StaticFiles(directory="static"), name="static")
79
75
 
@@ -91,6 +87,27 @@ app.include_router(
91
87
  prefix="files", # OPTIONAL: URL prefix (default: 'files')
92
88
  ),
93
89
  )
90
+
91
+ ```
92
+
93
+ ### !Warning If you include your own router then it is necessary that your app allows these Headers:
94
+
95
+ ```python
96
+ app.add_middleware(
97
+ CORSMiddleware, (# OPTIONAL: add CORS middleware if needed)
98
+ allow_origins=["*"], # OPTIONAL: allow all origins
99
+ allow_methods=["*"], # OPTIONAL: allow all methods
100
+ allow_headers=["*"], # OPTIONAL: allow all headers
101
+ expose_headers=[ # REQUIRED: expose these headers to the client
102
+ "Location",
103
+ "Upload-Offset",
104
+ "Tus-Resumable",
105
+ "Tus-Version",
106
+ "Tus-Extension",
107
+ "Tus-Max-Size",
108
+ "Upload-Expires",
109
+ ],
110
+ )
94
111
  ```
95
112
 
96
113
  ### Dependency‑Injected Hook (Advanced)
@@ -161,6 +178,6 @@ scheduler.start()
161
178
 
162
179
  ## Contributing
163
180
 
164
- Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/your-org/tuspyserver).
181
+ Contributions welcome! Please open issues or PRs on [GitHub](https://github.com/edihasaj/tuspy-fast-api).
165
182
 
166
183
  *© 2025 Edi Hasaj [X](https://x.com/hasajedi)*
@@ -1,4 +1,5 @@
1
1
  import base64
2
+ import inspect
2
3
  import json
3
4
  import os
4
5
  from datetime import datetime, timedelta
@@ -20,7 +21,7 @@ from starlette.responses import FileResponse
20
21
  from tusserver.metadata import FileMetadata
21
22
 
22
23
 
23
- def default_auth():
24
+ async def default_auth():
24
25
  pass
25
26
 
26
27
 
@@ -35,7 +36,7 @@ def create_api_router(
35
36
  ):
36
37
  if prefix and prefix[0] == "/":
37
38
  prefix = prefix[1:]
38
- router = APIRouter(prefix=f"/{prefix}")
39
+ router = APIRouter(prefix=f"/{prefix}", redirect_slashes=True)
39
40
 
40
41
  tus_version = "1.0.0"
41
42
  tus_extension = (
@@ -107,7 +108,7 @@ def create_api_router(
107
108
  return response
108
109
 
109
110
  @router.patch("/{uuid}", status_code=status.HTTP_204_NO_CONTENT)
110
- def upload_chunk(
111
+ async def upload_chunk(
111
112
  response: Response,
112
113
  uuid: str,
113
114
  content_length: int = Header(None),
@@ -126,7 +127,10 @@ def create_api_router(
126
127
  meta = _read_metadata(uuid)
127
128
  if meta and meta.size == meta.offset:
128
129
  file_path = os.path.join(files_dir, uuid)
129
- on_complete(file_path, meta.metadata)
130
+ result = on_complete(file_path, meta.metadata)
131
+ # if the callback returned a coroutine, await it
132
+ if inspect.isawaitable(result):
133
+ await result
130
134
 
131
135
  return headers
132
136
 
@@ -140,6 +144,7 @@ def create_api_router(
140
144
  response.status_code = status.HTTP_204_NO_CONTENT
141
145
  return response
142
146
 
147
+ @router.post("", status_code=status.HTTP_201_CREATED)
143
148
  @router.post("/", status_code=status.HTTP_201_CREATED)
144
149
  async def create_upload(
145
150
  request: Request,
@@ -186,7 +191,10 @@ def create_api_router(
186
191
  meta = _read_metadata(uuid)
187
192
  if meta and meta.size == 0:
188
193
  file_path = os.path.join(files_dir, uuid)
189
- on_complete(file_path, meta.metadata)
194
+ result = on_complete(file_path, meta.metadata)
195
+ # if the callback returned a coroutine, await it
196
+ if inspect.isawaitable(result):
197
+ await result
190
198
 
191
199
  return response
192
200
 
File without changes
File without changes