# FileStore
![GitHub](https://img.shields.io/github/license/ichinga-samuel/faststore?style=plastic)
![GitHub issues](https://img.shields.io/github/issues/ichinga-samuel/faststore?style=plastic)
![PyPI](https://img.shields.io/pypi/v/filestore)
![passing](https://img.shields.io/github/actions/workflow/status/ichinga-samuel/faststore/master.yaml)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads)
## Introduction
Simple file storage dependency for FastAPI. Makes use of FastAPI's dependency injection system to provide a simple way
to handle files. Inspired by Multer it allows both single and multiple file uploads through different fields with a
simple interface. Comes with a default implementation for local file storage, in-memory storage and AWS S3
storage but can be easily extended to support other storage systems.
## Installation
```bash
pip install filestore
# to use aws s3 storage
pip install filestore[s3]
```
## Usage
```python
from fastapi import FastAPI, File, UploadFile, Depends
from filestore import LocalStorage, Store
app = FastAPI()
# local storage instance for single file upload
loc = LocalStorage(name='book', required=True)
# local storage instance for multiple file upload with a maximum of 2 files from a single field
loc2 = LocalStorage(name='book', required=True, count=2)
# local storage instance for multiple file uploads from different fields
multiple_local = LocalStorage(fields=[{'name': 'author', 'max_count': 2}, {'name': 'book', 'max_count': 1}])
@app.post('/upload_book')
async def upload_book(book=Depends(loc), model=Depends(loc.model)) -> Store:
return book.store
@app.post('/local_multiple', name='upload', openapi_extra={'form': {'multiple': True}})
async def local_multiple(model=Depends(multiple_local.model), loc=Depends(multiple_local)) -> Store:
return loc.store
```
## API
FastStore Instantiation. All arguments are keyword arguments.
### FastStore
The base class for the FastStore package. It is an abstract class and must be inherited from for custom file
storage services. The upload and multi_upload methods must be implemented in a child class.
**\_\_init\_\_**
```python
def __init__(name: str = '', count: int = 1, required: bool = False, fields: list[FileField] = None,
config: Config = None)
```
Instantiates a FastStore object. All arguments are key word arguments with defaults
**Parameters:**
|Name|Type|Description|Default|
|---|---|---|---|
|`name`|`str`|The name of the file field to expect from the form for a single field upload|`''`|
|`count`|`int`|The maximum number of files to accept for a single field upload|`1`|
|`required`|`bool`|Set as true if the field defined in name is required|`False`|
|`fields`|`list[FileField]`|A list of fields to expect from the form. Usually for multiple file uploads from different fields|`None`|
|`config`|`Config`|The Config dictionary|`None`|
**Note:**
If you provide both name and fields arguments the two are merged together with the name argument taking precedence if there is a name clash.\
**FileField**\
A dictionary representing form fields.
|Key|Type|Description|Note|
|---|---|---|---|
|`name`|`str`|The name of the field|Required|
|`count`|`int`|The maximum number of files to expect|Defaults to 1|
|`required`|`bool`|Set as true if the field is required|Defaults to false|
|`config`|`Config`|A config dict for individual field|Optional|
**Config**\
The config dictionary is to be passed to faststore class during instantiation or added to individual file field dict
|Key|Type|Description|Note|
|---|---|---|---|
|`storage`|`str`|The storage system to use. Defaults to local|`local`, `s3`, `memory`|
|`dest`|`str\|Path`|The path to save the file relative to the current working directory. Defaults to uploads. Specifying destination will override dest |LocalStorage and S3Storage|
|`destination`|`Callable[[Request, Form, str, UploadFile], str \| Path]`|A destination function for saving the file|Local and Cloud Storage|
|`filter`|`Callable[[Request, Form, str, UploadFile], bool]`|Remove unwanted files|
|`max_files`|`int`|The maximum number of files to expect. Defaults to 1000| Not applicable to FileField config dict|
|`max_fields`|`int`|The maximum number of file fields to expect. Defaults to 1000| Not applicable in FileField config dict|
|`filename`|`Callable[[Request, Form, str, UploadFile], UploadFile]`|A function for customizing the filename|Local and Cloud Storage|
|`background`|`bool`|If true run the storage operation as a background task|Local and Cloud Storage|
|`extra_args`|`dict`|Extra arguments for AWS S3 Storage| S3Storage|
|`bucket`|`str`|Name of storage bucket for cloud storage|Cloud Storage|
|`region`|`str`|Name of region for cloud storage|Cloud Storage| Not available in FileField config dict|
**Attributes**
|name|type|description|
|---|---|---|
|fields|`list[FileField]`|A list of FileField objects|
|config|`Config`|The config dictionary|
|form|`FormData`|The form object|
|request|`Request`|The request object|
|store|`Store`|The result of the file storage operation|
|file_count|`int`|The total number of files in the form|
|background|`BackgroundTasks`|The background task object for running storage tasks in the background|
**\_\_call\_\_**
```python
async def __call__(req: Request, bgt: BackgroundTasks) -> FastStore
```
This method allows you to use a FastStore instance as a dependency for your route function. It sets the result
of the file storage operation and returns an instance of the class.
**model**\
The model property dynamically generates a pydantic model for the FastStore instance. This model can be used as a
dependency for your path function. It is generated based on the fields attribute. It is useful for validating the form
fields and for API documentation. Using this property in your path function will enable SwaggerUI generate the
appropriate form fields
**store**
```python
@store.setter
def store(self, value: FileData)
```
The store property gets and sets the result of the file storage operation. The setter method accepts
a FileData object while the getter method returns a Store object. Any implementation of upload should use this to set
the result of the file storage operation.
**upload**
```python
@abstractmethod
async def upload(self, *, file_field: FileField)
```
This method is an abstract method and must be implemented in a child class. It is used for uploading a single file
**multi_upload**
```python
@abstractmethod
async def multi_upload(self, *, file_fields: list[FileField])
```
This method is an abstract method and must be implemented in a child class. It is used for uploading multiple files
### FileData
This pydantic model represents the result of an individual file storage operation.
|Name|Type|Description|Note|
|---|---|---|---|
|`path`|`str`|The path to the file for local storage|Local Storage|
|`url`|`str`|The url to the file for cloud storage|Cloud Storage|
|`status`|`bool`|The status of the file storage operation|Defaults to true|
|`content_type`|`bool`|The content type of the file|
|`filename`|`str`|The name of the file|
|`size`|`int`|The size of the file|
|`file`|`bytes`|The file object for memory storage|Memory Storage|
|`field_name`|`str`|The name of the form field|
|`metadata`|`dict`|Extra metadata of the file|
|`error`|`str`|The error message if the file storage operation failed|
|`message`|`str`|Success message if the file storage operation was successful|
### Store Class
The response model for the FastStore class. A pydantic model.
|Name|Type|Description|
|---|---|---|
|`file`|`FileData \| None`|The result of a single file upload or storage operation|
|`files`|`Dict[str, List[FileData]]`|The result of multiple file uploads or storage operations|
|`failed`|`Dict[str, List[FileData]]`|The results of a failed file upload or storage operation|
|`error`|`str`|The error message if the file storage operation failed|
|`message`|`str`|Success message if the file storage operation was successful|
**\_\_len\_\_**
```python
def __len__(self) -> int
```
Use the len(obj) function to get the total number of successful file uploads or storage operations.
**Sample Store Object**\
A sample Store object for multiple files uploads in two fields (books and authors).
```json
{
"file": null,
"files": {
"books": [
{
"path": "/home/user/test_data/uploads/books/book1.pdf",
"status": true,
"content_type": "application/pdf",
"filename": "book1.pdf",
"size": 1000,
"field_name": "books",
"metadata": {},
"message": "File uploaded successfully"
},
{
"path": "/home/user/test_data/uploads/books/book2.pdf",
"status": true,
"content_type": "application/pdf",
"filename": "book2.pdf",
"size": 1000,
"field_name": "books",
"metadata": {},
"message": "File uploaded successfully"
}
],
"authors": [
{
"path": "/home/user/test_data/uploads/authors/author1.png",
"status": true,
"content_type": "application/png",
"filename": "author1.png",
"size": 1000,
"field_name": "authors",
"metadata": {},
"message": "File uploaded successfully"
},
{
"path": "/home/user/test_data/uploads/authors/author2.png",
"status": true,
"content_type": "application/png",
"filename": "author2.png",
"size": 1000,
"field_name": "authors",
"metadata": {},
"message": "File uploaded successfully"
}
]
},
"failed": {},
"error": "",
"message": "Files uploaded successfully"
}
```
### Configuration Functions.
These are functions that can be passed to either the config parameter of the FastStore class or the config 'key' of
the FileField dictionary. They are used for customizing the file storage operation. They have the same signature but
different return types.
#### Destination function
A destination function can be passed to the LocalStorage and S3Storage config parameter 'destination' to create a
destination for the files in a forms. It can also be passed to the FileField config parameter 'destination' to create a
destination for a single file field.
The function should return a path or string object.
```python
# A destination function
def local_destination(req: Request, form: FormData, field: str, file: UploadFile) -> Path:
path = Path.cwd() / f'test_data/uploads/{field}'
path.mkdir(parents=True, exist_ok=True) if not path.exists() else ...
return path / f'{file.filename}'
```
#### Filename function
This function modifies the filename attribute of the UploadFile object and returns the modified object.
```python
# A filename function
def local_filename(req: Request, form: FormData, field: str, file: UploadFile) -> UploadFile:
file.filename = f'local_{file.filename}'
return file
```
#### Filtering
Set a rule for filtering out unwanted files.
```python
# A filter function that only allows files with .txt extension
def book_filter(req: Request, form: FormData, field: str, file: UploadFile) -> bool:
return file.filename and file.filename.endswith('.txt')
```
#### Example
```python
# initiate a local storage instance with a destination function, a filename function and a filter function.
loc = LocalStorage(
fields = [{'name': 'book', 'max_count': 2, 'required': True, 'config': {'filter': book_filter}}, {'name': 'image', 'max_count': 2}],
config={
'destination': local_destination,
'filename': local_filename,
}
)
@app.post('/upload')
# Adding the model parameter to the path function will generate form fields on the swagger ui and openapi docs.
# That can be used to validate the form fields. It does not affect the file storage operation and can be omitted.
async def upload(model=Depends(loc.modle), form: Form = Depends(loc)) -> Store:
return loc.store
```
### Swagger UI and OpenAPI
Adding the model property of the faststore instance as a parameter to the route function will add a pydantic model
generated from the form fields to the swagger ui and openapi docs. This just for validation and documentation and does
not actually affect the file storage operation. It can be omitted.
### Error Handling.
Any error that occurs is caught and passed to the error attribute of the FileData class and the status attribute
is set to false indicating a failed operation. The resulting FileData object is added to the *failed* attribute of the
*store* property of the FastStore instance. The error message is also added to the *error* attribute of the *store*
### Storage Classes
All storage class inherit from the base FastStore class. This class implements a callable instance that can be used
as a dependency in a fastapi route function.
### LocalStorage
This class handles local file storage to the disk.
### S3Storage
This class handles cloud storage to AWS S3. When using this class ensure that the following environment variables
are set. Any extra parameters is passed to the extra_args dict of the config dict.
- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- `AWS_DEFAULT_REGION`: This is optional as you can specify the region in the config.
- `AWS_BUCKET_NAME`: This is optional as you can specify the bucket name in the config.
```python
from filestore import S3Storage
s3 = S3Storage(fields=[{'name': 'book', 'max_count': 2, 'required': True}, {'name': 'image', 'max_count': 2}],
config={'region': 'us-east-1', 'bucket': 'my-bucket', extra_args={'ACL': 'public-read'}})
```
### MemoryStorage
This class handles memory storage. It stores the file in memory and returns the file object in the store object as
a bytes object. For image files they are encoded with base64 encoding before returning.
### Background Tasks
You can run the file storage operation as a background task by setting the background key in the config parameter
to True in either the object instance config parameter or the FileField config dict.
### Build your own storage class
You can build your own storage class by inheriting from the FastStore class and implementing the **upload** and
**multiple_upload** methods. Just make sure you properly use the store property to set the result of the
file storage operation.
Raw data
{
"_id": null,
"home_page": "",
"name": "filestore",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "fastapi,filestorage,cloudstorage,storageengine,filestore",
"author": "",
"author_email": "Ichinga Samuel <ichingasamuel@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/fb/47/99ef1b03c2478552477a1c00819e1fe6b1e8d0779d41329fb305e486e8bc/filestore-1.0.7.tar.gz",
"platform": null,
"description": "# FileStore\r\n![GitHub](https://img.shields.io/github/license/ichinga-samuel/faststore?style=plastic)\r\n![GitHub issues](https://img.shields.io/github/issues/ichinga-samuel/faststore?style=plastic)\r\n![PyPI](https://img.shields.io/pypi/v/filestore)\r\n![passing](https://img.shields.io/github/actions/workflow/status/ichinga-samuel/faststore/master.yaml)\r\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads)\r\n## Introduction\r\nSimple file storage dependency for FastAPI. Makes use of FastAPI's dependency injection system to provide a simple way\r\nto handle files. Inspired by Multer it allows both single and multiple file uploads through different fields with a \r\nsimple interface. Comes with a default implementation for local file storage, in-memory storage and AWS S3\r\nstorage but can be easily extended to support other storage systems.\r\n\r\n## Installation\r\n\r\n```bash \r\npip install filestore\r\n\r\n# to use aws s3 storage\r\npip install filestore[s3]\r\n```\r\n## Usage\r\n\r\n```python\r\nfrom fastapi import FastAPI, File, UploadFile, Depends\r\nfrom filestore import LocalStorage, Store\r\n\r\napp = FastAPI()\r\n\r\n# local storage instance for single file upload\r\nloc = LocalStorage(name='book', required=True)\r\n\r\n# local storage instance for multiple file upload with a maximum of 2 files from a single field\r\nloc2 = LocalStorage(name='book', required=True, count=2)\r\n\r\n# local storage instance for multiple file uploads from different fields\r\nmultiple_local = LocalStorage(fields=[{'name': 'author', 'max_count': 2}, {'name': 'book', 'max_count': 1}])\r\n\r\n\r\n@app.post('/upload_book')\r\nasync def upload_book(book=Depends(loc), model=Depends(loc.model)) -> Store:\r\n return book.store\r\n\r\n\r\n@app.post('/local_multiple', name='upload', openapi_extra={'form': {'multiple': True}})\r\nasync def local_multiple(model=Depends(multiple_local.model), loc=Depends(multiple_local)) -> Store:\r\n return loc.store\r\n```\r\n\r\n## API\r\nFastStore Instantiation. All arguments are keyword arguments.\r\n\r\n### FastStore\r\nThe base class for the FastStore package. It is an abstract class and must be inherited from for custom file\r\nstorage services. The upload and multi_upload methods must be implemented in a child class.\r\n\r\n**\\_\\_init\\_\\_**\r\n```python\r\ndef __init__(name: str = '', count: int = 1, required: bool = False, fields: list[FileField] = None,\r\n config: Config = None)\r\n```\r\nInstantiates a FastStore object. All arguments are key word arguments with defaults\r\n**Parameters:**\r\n\r\n|Name|Type|Description|Default|\r\n|---|---|---|---|\r\n|`name`|`str`|The name of the file field to expect from the form for a single field upload|`''`|\r\n|`count`|`int`|The maximum number of files to accept for a single field upload|`1`|\r\n|`required`|`bool`|Set as true if the field defined in name is required|`False`|\r\n|`fields`|`list[FileField]`|A list of fields to expect from the form. Usually for multiple file uploads from different fields|`None`|\r\n|`config`|`Config`|The Config dictionary|`None`|\r\n\r\n**Note:**\r\nIf you provide both name and fields arguments the two are merged together with the name argument taking precedence if there is a name clash.\\\r\n\r\n**FileField**\\\r\nA dictionary representing form fields. \r\n\r\n|Key|Type|Description|Note|\r\n|---|---|---|---|\r\n|`name`|`str`|The name of the field|Required|\r\n|`count`|`int`|The maximum number of files to expect|Defaults to 1|\r\n|`required`|`bool`|Set as true if the field is required|Defaults to false|\r\n|`config`|`Config`|A config dict for individual field|Optional|\r\n\r\n**Config**\\\r\nThe config dictionary is to be passed to faststore class during instantiation or added to individual file field dict\r\n\r\n|Key|Type|Description|Note|\r\n|---|---|---|---|\r\n|`storage`|`str`|The storage system to use. Defaults to local|`local`, `s3`, `memory`|\r\n|`dest`|`str\\|Path`|The path to save the file relative to the current working directory. Defaults to uploads. Specifying destination will override dest |LocalStorage and S3Storage|\r\n|`destination`|`Callable[[Request, Form, str, UploadFile], str \\| Path]`|A destination function for saving the file|Local and Cloud Storage|\r\n|`filter`|`Callable[[Request, Form, str, UploadFile], bool]`|Remove unwanted files|\r\n|`max_files`|`int`|The maximum number of files to expect. Defaults to 1000| Not applicable to FileField config dict|\r\n|`max_fields`|`int`|The maximum number of file fields to expect. Defaults to 1000| Not applicable in FileField config dict|\r\n|`filename`|`Callable[[Request, Form, str, UploadFile], UploadFile]`|A function for customizing the filename|Local and Cloud Storage|\r\n|`background`|`bool`|If true run the storage operation as a background task|Local and Cloud Storage|\r\n|`extra_args`|`dict`|Extra arguments for AWS S3 Storage| S3Storage|\r\n|`bucket`|`str`|Name of storage bucket for cloud storage|Cloud Storage|\r\n|`region`|`str`|Name of region for cloud storage|Cloud Storage| Not available in FileField config dict|\r\n\r\n**Attributes**\r\n\r\n|name|type|description|\r\n|---|---|---|\r\n|fields|`list[FileField]`|A list of FileField objects|\r\n|config|`Config`|The config dictionary|\r\n|form|`FormData`|The form object|\r\n|request|`Request`|The request object|\r\n|store|`Store`|The result of the file storage operation|\r\n|file_count|`int`|The total number of files in the form|\r\n|background|`BackgroundTasks`|The background task object for running storage tasks in the background|\r\n\r\n\r\n**\\_\\_call\\_\\_**\r\n```python\r\nasync def __call__(req: Request, bgt: BackgroundTasks) -> FastStore\r\n```\r\nThis method allows you to use a FastStore instance as a dependency for your route function. It sets the result\r\nof the file storage operation and returns an instance of the class.\r\n\r\n**model**\\\r\nThe model property dynamically generates a pydantic model for the FastStore instance. This model can be used as a\r\ndependency for your path function. It is generated based on the fields attribute. It is useful for validating the form\r\nfields and for API documentation. Using this property in your path function will enable SwaggerUI generate the\r\nappropriate form fields\r\n\r\n**store**\r\n```python\r\n@store.setter\r\ndef store(self, value: FileData)\r\n```\r\nThe store property gets and sets the result of the file storage operation. The setter method accepts\r\na FileData object while the getter method returns a Store object. Any implementation of upload should use this to set\r\nthe result of the file storage operation.\r\n\r\n**upload**\r\n```python\r\n@abstractmethod\r\nasync def upload(self, *, file_field: FileField)\r\n```\r\nThis method is an abstract method and must be implemented in a child class. It is used for uploading a single file\r\n\r\n**multi_upload**\r\n```python\r\n@abstractmethod\r\nasync def multi_upload(self, *, file_fields: list[FileField])\r\n```\r\nThis method is an abstract method and must be implemented in a child class. It is used for uploading multiple files\r\n\r\n### FileData\r\nThis pydantic model represents the result of an individual file storage operation.\r\n\r\n|Name|Type|Description|Note|\r\n|---|---|---|---|\r\n|`path`|`str`|The path to the file for local storage|Local Storage|\r\n|`url`|`str`|The url to the file for cloud storage|Cloud Storage|\r\n|`status`|`bool`|The status of the file storage operation|Defaults to true|\r\n|`content_type`|`bool`|The content type of the file|\r\n|`filename`|`str`|The name of the file|\r\n|`size`|`int`|The size of the file|\r\n|`file`|`bytes`|The file object for memory storage|Memory Storage|\r\n|`field_name`|`str`|The name of the form field|\r\n|`metadata`|`dict`|Extra metadata of the file|\r\n|`error`|`str`|The error message if the file storage operation failed|\r\n|`message`|`str`|Success message if the file storage operation was successful|\r\n\r\n### Store Class\r\nThe response model for the FastStore class. A pydantic model.\r\n\r\n|Name|Type|Description|\r\n|---|---|---|\r\n|`file`|`FileData \\| None`|The result of a single file upload or storage operation|\r\n|`files`|`Dict[str, List[FileData]]`|The result of multiple file uploads or storage operations|\r\n|`failed`|`Dict[str, List[FileData]]`|The results of a failed file upload or storage operation|\r\n|`error`|`str`|The error message if the file storage operation failed|\r\n|`message`|`str`|Success message if the file storage operation was successful|\r\n\r\n**\\_\\_len\\_\\_**\r\n```python\r\ndef __len__(self) -> int\r\n```\r\nUse the len(obj) function to get the total number of successful file uploads or storage operations.\r\n\r\n**Sample Store Object**\\\r\nA sample Store object for multiple files uploads in two fields (books and authors).\r\n```json\r\n{\r\n \"file\": null,\r\n \"files\": {\r\n \"books\": [\r\n {\r\n \"path\": \"/home/user/test_data/uploads/books/book1.pdf\",\r\n \"status\": true,\r\n \"content_type\": \"application/pdf\",\r\n \"filename\": \"book1.pdf\",\r\n \"size\": 1000,\r\n \"field_name\": \"books\",\r\n \"metadata\": {},\r\n \"message\": \"File uploaded successfully\"\r\n },\r\n {\r\n \"path\": \"/home/user/test_data/uploads/books/book2.pdf\",\r\n \"status\": true,\r\n \"content_type\": \"application/pdf\",\r\n \"filename\": \"book2.pdf\",\r\n \"size\": 1000,\r\n \"field_name\": \"books\",\r\n \"metadata\": {},\r\n \"message\": \"File uploaded successfully\"\r\n }\r\n ],\r\n \"authors\": [\r\n {\r\n \"path\": \"/home/user/test_data/uploads/authors/author1.png\",\r\n \"status\": true,\r\n \"content_type\": \"application/png\",\r\n \"filename\": \"author1.png\",\r\n \"size\": 1000,\r\n \"field_name\": \"authors\",\r\n \"metadata\": {},\r\n \"message\": \"File uploaded successfully\"\r\n },\r\n {\r\n \"path\": \"/home/user/test_data/uploads/authors/author2.png\",\r\n \"status\": true,\r\n \"content_type\": \"application/png\",\r\n \"filename\": \"author2.png\",\r\n \"size\": 1000,\r\n \"field_name\": \"authors\",\r\n \"metadata\": {},\r\n \"message\": \"File uploaded successfully\"\r\n }\r\n ]\r\n },\r\n \"failed\": {},\r\n \"error\": \"\",\r\n \"message\": \"Files uploaded successfully\"\r\n}\r\n```\r\n\r\n### Configuration Functions.\r\nThese are functions that can be passed to either the config parameter of the FastStore class or the config 'key' of\r\nthe FileField dictionary. They are used for customizing the file storage operation. They have the same signature but\r\ndifferent return types.\r\n\r\n#### Destination function\r\nA destination function can be passed to the LocalStorage and S3Storage config parameter 'destination' to create a \r\ndestination for the files in a forms. It can also be passed to the FileField config parameter 'destination' to create a\r\ndestination for a single file field.\r\nThe function should return a path or string object.\r\n\r\n```python\r\n# A destination function\r\ndef local_destination(req: Request, form: FormData, field: str, file: UploadFile) -> Path:\r\n path = Path.cwd() / f'test_data/uploads/{field}'\r\n path.mkdir(parents=True, exist_ok=True) if not path.exists() else ...\r\n return path / f'{file.filename}'\r\n```\r\n\r\n#### Filename function\r\nThis function modifies the filename attribute of the UploadFile object and returns the modified object.\r\n```python\r\n# A filename function\r\ndef local_filename(req: Request, form: FormData, field: str, file: UploadFile) -> UploadFile:\r\n file.filename = f'local_{file.filename}'\r\n return file\r\n```\r\n\r\n#### Filtering\r\nSet a rule for filtering out unwanted files.\r\n```python\r\n# A filter function that only allows files with .txt extension\r\ndef book_filter(req: Request, form: FormData, field: str, file: UploadFile) -> bool:\r\n return file.filename and file.filename.endswith('.txt')\r\n```\r\n\r\n#### Example\r\n```python\r\n# initiate a local storage instance with a destination function, a filename function and a filter function.\r\nloc = LocalStorage(\r\n fields = [{'name': 'book', 'max_count': 2, 'required': True, 'config': {'filter': book_filter}}, {'name': 'image', 'max_count': 2}],\r\n config={\r\n 'destination': local_destination,\r\n 'filename': local_filename,\r\n }\r\n)\r\n\r\n@app.post('/upload')\r\n# Adding the model parameter to the path function will generate form fields on the swagger ui and openapi docs.\r\n# That can be used to validate the form fields. It does not affect the file storage operation and can be omitted.\r\nasync def upload(model=Depends(loc.modle), form: Form = Depends(loc)) -> Store:\r\n return loc.store\r\n```\r\n### Swagger UI and OpenAPI \r\nAdding the model property of the faststore instance as a parameter to the route function will add a pydantic model\r\ngenerated from the form fields to the swagger ui and openapi docs. This just for validation and documentation and does\r\nnot actually affect the file storage operation. It can be omitted.\r\n\r\n### Error Handling.\r\nAny error that occurs is caught and passed to the error attribute of the FileData class and the status attribute\r\nis set to false indicating a failed operation. The resulting FileData object is added to the *failed* attribute of the\r\n*store* property of the FastStore instance. The error message is also added to the *error* attribute of the *store*\r\n\r\n### Storage Classes\r\nAll storage class inherit from the base FastStore class. This class implements a callable instance that can be used\r\nas a dependency in a fastapi route function.\r\n\r\n### LocalStorage\r\nThis class handles local file storage to the disk.\r\n\r\n### S3Storage\r\nThis class handles cloud storage to AWS S3. When using this class ensure that the following environment variables\r\nare set. Any extra parameters is passed to the extra_args dict of the config dict.\r\n- `AWS_ACCESS_KEY_ID`\r\n- `AWS_SECRET_ACCESS_KEY`\r\n- `AWS_DEFAULT_REGION`: This is optional as you can specify the region in the config.\r\n- `AWS_BUCKET_NAME`: This is optional as you can specify the bucket name in the config.\r\n\r\n```python \r\nfrom filestore import S3Storage\r\ns3 = S3Storage(fields=[{'name': 'book', 'max_count': 2, 'required': True}, {'name': 'image', 'max_count': 2}],\r\n config={'region': 'us-east-1', 'bucket': 'my-bucket', extra_args={'ACL': 'public-read'}})\r\n```\r\n\r\n### MemoryStorage\r\nThis class handles memory storage. It stores the file in memory and returns the file object in the store object as \r\na bytes object. For image files they are encoded with base64 encoding before returning.\r\n\r\n### Background Tasks\r\nYou can run the file storage operation as a background task by setting the background key in the config parameter\r\nto True in either the object instance config parameter or the FileField config dict.\r\n\r\n### Build your own storage class\r\nYou can build your own storage class by inheriting from the FastStore class and implementing the **upload** and \r\n**multiple_upload** methods. Just make sure you properly use the store property to set the result of the\r\nfile storage operation.\r\n",
"bugtrack_url": null,
"license": "",
"summary": "Storage Engine Package for FastAPI",
"version": "1.0.7",
"project_urls": {
"Bug Tracker": "https://github.com/Ichinga-Samuel/faststore/issues",
"Homepage": "https://github.com/Ichinga-Samuel/faststore"
},
"split_keywords": [
"fastapi",
"filestorage",
"cloudstorage",
"storageengine",
"filestore"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d53d323f1cb4bb47f79efe0aa0a116c2a729f35aa98b38cf3449901ae10f8bff",
"md5": "c115832bb4f2505234dd461f53e93e46",
"sha256": "56e9c586f44f4f51fe48dd6419e91df93ab3300ef6f4cddbc67e60d4fb123526"
},
"downloads": -1,
"filename": "filestore-1.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c115832bb4f2505234dd461f53e93e46",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 20409,
"upload_time": "2024-01-01T00:56:10",
"upload_time_iso_8601": "2024-01-01T00:56:10.719770Z",
"url": "https://files.pythonhosted.org/packages/d5/3d/323f1cb4bb47f79efe0aa0a116c2a729f35aa98b38cf3449901ae10f8bff/filestore-1.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fb4799ef1b03c2478552477a1c00819e1fe6b1e8d0779d41329fb305e486e8bc",
"md5": "3bcc9870880a51e8faba104463cb6d5e",
"sha256": "78768626f8e83f267dbc180ac0a133c211f2cd2aff4ee914e31e33421702ca14"
},
"downloads": -1,
"filename": "filestore-1.0.7.tar.gz",
"has_sig": false,
"md5_digest": "3bcc9870880a51e8faba104463cb6d5e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 19830,
"upload_time": "2024-01-01T00:56:12",
"upload_time_iso_8601": "2024-01-01T00:56:12.927951Z",
"url": "https://files.pythonhosted.org/packages/fb/47/99ef1b03c2478552477a1c00819e1fe6b1e8d0779d41329fb305e486e8bc/filestore-1.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-01 00:56:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Ichinga-Samuel",
"github_project": "faststore",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "filestore"
}