Bucket Esgres
iamhuzaifasabahuddin
HOBBYOP

a month ago

Hiya so my bucket is tigris thingy and it costs esgres swhen i try to download files etc how to avoid it or lower the esgress etc as if i am using this """

Models for the Posts app.

class S3FileWrapper:

"""Mock a FileField's 'file' attribute for template compatibility with S3-stored files."""

def __init__(self, key, name):

    self.key = key

    self.name = name

@property

def url(self):

    return default_storage.url(self.key)

def read(self, *args, **kwargs):

    with default_storage.open(self.key) as f:

        return f.read(*args, **kwargs)

def __str__(self):

    return self.key

class Post(models.Model):

"""

Represents a post, optionally linked to a task.

"""

task = models.ForeignKey(

    Task,

    on_delete=models.CASCADE,

    related_name="posts",

    null=True,

    blank=True

)

author = models.ForeignKey(

    User,

    on_delete=models.CASCADE,

    related_name="posts"

)

title = models.CharField(max_length=255)

content = models.TextField()

created_at = models.DateTimeField(auto_now_add=True, db_index=True)

updated_at = models.DateTimeField(auto_now=True)

class Meta:

    ordering = ["-created_at"]

    indexes = [

        models.Index(fields=['task', '-created_at'], name='post_task_created_idx'),

    ]

def __str__(self):

    return self.title

class PostFile(models.Model):

"""

Stores files associated with a post.

"""

post = models.ForeignKey(

    Post,

    on_delete=models.CASCADE,

    related_name='files'

)

file_key = models.CharField(max_length=1024, null=True, blank=True)

file_name = models.CharField(max_length=255, null=True, blank=True)

file_size = models.PositiveBigIntegerField(null=True, blank=True)

uploaded_at = models.DateTimeField(auto_now_add=True)

def __str__(self):

    return f"{self.post.title} - {self.file_name}"

@property

def filename(self):

    return self.file_name

@property

def file(self):

    if not self.file_key:

        return None

    return S3FileWrapper(self.file_key, self.file_name)

class Meta:

    ordering = ['-uploaded_at']

    indexes = [

        models.Index(fields=['post', '-uploaded_at'], name='postfile_post_uploaded_idx'),

    ]

and then in my template

                        <i class="bi bi-file-earmark-arrow-down"></i>

                        <span class="text-truncate" style="max-width: 200px;">{{ file.filename }}</span>

                    </a>

                    {% endfor %}

                </div> what am i doing wrong?
Solved$10 Bounty

Pinned Solution

Based on AI's analysis of your code; you don't necessarily need a custom wrapper class. You can just use the default_storage directly to generate the presigned URL. You can let AI do this suggested implementation for you.

11 Replies

Railway
BOT

a month ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway about 1 month ago


Object storage has free egress. Just make sure you're not passing the files through your website.

https://railway.com/pricing


0x5b62656e5d

Object storage has free egress. Just make sure you're not passing the files through your website. https://railway.com/pricing

iamhuzaifasabahuddin
HOBBYOP

a month ago

Hiy Mate,

Thank you for it I understand that. but what do you mean dont pass the file through your webs

ite? could you please elaborate


iamhuzaifasabahuddin

Hiy Mate, Thank you for it I understand that. but what do you mean dont pass the file through your webs ite? could you please elaborate

If your app downloads the file from your bucket and streams it to the user, you are going to be charged for egress. To utilize the free egress, your app must generate a presigned URL so the user's browser downloads the file directly from the bucket.


iamhuzaifasabahuddin
HOBBYOP

a month ago

Hiya Mate, THank you for your input so something like this? AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')

AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')

AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')

AWS_S3_ENDPOINT_URL = 'https://t3.storageapi.dev'

AWS_S3_REGION_NAME = 'auto'

AWS_S3_SIGNATURE_VERSION = 's3v4'

AWS_DEFAULT_ACL = None

AWS_S3_ADDRESSING_STYLE = "path"

AWS_QUERYSTRING_AUTH = True

AWS_QUERYSTRING_EXPIRE = 3600

AWS_S3_FILE_OVERWRITE = False and then check my code above


iamhuzaifasabahuddin

Hiya Mate, THank you for your input so something like this? AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') AWS_S3_ENDPOINT_URL = 'https://t3.storageapi.dev' AWS_S3_REGION_NAME = 'auto' AWS_S3_SIGNATURE_VERSION = 's3v4' AWS_DEFAULT_ACL = None AWS_S3_ADDRESSING_STYLE = "path" AWS_QUERYSTRING_AUTH = True AWS_QUERYSTRING_EXPIRE = 3600 AWS_S3_FILE_OVERWRITE = False and then check my code above

Yes. You'd use the S3 SDK to generate a presigned URL, then have the user download the file from there.


iamhuzaifasabahuddin
HOBBYOP

a month ago

so i use s3boto etc fo it cana you check my inital model and template and let me now thats the correct approach


iamhuzaifasabahuddin

so i use s3boto etc fo it cana you check my inital model and template and let me now thats the correct approach

Based on AI's analysis of your code; you don't necessarily need a custom wrapper class. You can just use the default_storage directly to generate the presigned URL. You can let AI do this suggested implementation for you.


iamhuzaifasabahuddin
HOBBYOP

a month ago

so my bucket or the default storage shares the link as https://t3.storageapi.dev/stocked-lounge does this count as esgress?


iamhuzaifasabahuddin

so my bucket or the default storage shares the link as https://t3.storageapi.dev/stocked-lounge does this count as esgress?

You need to generate a presigned URL. IIRC you can't directly share a file from the storage URL.


iamhuzaifasabahuddin
HOBBYOP

a month ago

Isn't the above linke presigned?? As if shouldn't it be like that?



Status changed to Solved 0x5b62656e5d 25 days ago


Welcome!

Sign in to your Railway account to join the conversation.

Loading...