Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4274 from pulumi/thoward/add_python_example_to_pa…
Browse files Browse the repository at this point in the history
…ckage_ecosystems_blog

Add python code samples to packages ecosystem blog post
  • Loading branch information
thoward authored May 15, 2024
2 parents cada965 + d526404 commit c6c3b38
Showing 1 changed file with 117 additions and 20 deletions.
137 changes: 117 additions & 20 deletions themes/default/content/blog/next-level-iac-package-ecosystems/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,30 @@ Let’s have a look at a concrete example where this package ecosystem can get y

## Use Case: Determining S3 MIME types on-the-fly

A popular example of cloud infrastructure automation is creating an S3 bucket and pushing some files to it. This is a common task that many of us have had to do, and most infrastructure-automation tools have a way to accomplish this.
A popular example of cloud infrastructure automation is creating an S3 bucket and pushing some files to it. This is a common task that many of us have had to do, and most infrastructure automation tools have a way to accomplish this.

Here’s our public answer for [how to do that in Pulumi using TypeScript][s3-bucket-example]:
Here’s our public answer for [how to do that in Pulumi][s3-bucket-example]:

{{< chooser language "typescript,python" />}}

{{% choosable language typescript %}}

```typescript
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as fs from 'fs';

// Create an S3 bucket where we will upload the file.
const bucket = new aws.s3.Bucket("my-bucket", {
// You can apply additional bucket settings here.
});

const filePath = "path/to/your/local/file.ext"; // Replace with the path to the file you want to upload

// Read the contents of the file to be uploaded to S3.
const fileContents = fs.readFileSync(filePath, {encoding: 'utf-8'});
const filePath = "path/to/your/local/file.txt"; // Replace with the path to the file you want to upload

// Upload the file to the S3 bucket.
const bucketObject = new aws.s3.BucketObject("my-bucket-object", {
bucket: bucket, // Reference to the bucket created above.
key: "file.txt", // This will be the file's name in the bucket.
content: fileContents, // Contents of the file.
source: pulumi.FileAsset(filePath), // Contents of the file.
contentType: "text/plain", // MIME-type of the file. Adjust if you upload a different type of file.
});

Expand All @@ -60,48 +60,109 @@ export const bucketName = bucket.id;

// Export the URL of the file in the S3 bucket
export const objectUrl = pulumi.interpolate`s3://${bucket.id}/${bucketObject.key}`;
```
```

{{% /choosable %}}

{{% choosable language python %}}

```python
import pulumi
import pulumi_aws as aws

# Create an S3 bucket
bucket = aws.s3.Bucket('my-bucket')

# The path to the file to upload to S3
file_path = "path/to/your/local/file.txt" # Replace with the path to the file you want to upload

# Upload the file to the S3 bucket
bucket_object = aws.s3.BucketObject('my-bucket-object',
bucket=bucket.id, # Reference to the bucket created above.
key='file.txt', # This will be the file's name in the bucket.
source=pulumi.FileAsset(file_path),
content_type='text/plain') # MIME-type of the file. Adjust if you upload a different type of file.

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)

# Export the URL of the file in the S3 bucket
pulumi.export('object_url', pulumi.Output.concat('s3://', bucket.id, '/', bucket_object.key))
```

{{% /choosable %}}


However, something that stands out as a weak link here is the line:

{{< chooser language "typescript,python" />}}

{{% choosable language typescript %}}

```typescript
contentType: "text/plain", // MIME-type of the file. Adjust if you upload a different type of file.
```

{{% /choosable %}}

{{% choosable language python %}}

```python
content_type='text/plain') # MIME-type of the file. Adjust if you upload a different type of file.
```
{{% /choosable %}}

Yeah, hard-coding the MIME type for every file I need to upload is a not going to scale. In fact, I’m probably going to get a random directory full of files I need to iterate over, each with different file types, and it will change every time it runs, and we won’t know what type of file it is ahead of time.

Packages to the rescue!! Turns out that determining the MIME type of a file in TypeScript only involves importing the community-created [`mime-types`][npm-mimetypes] library and a single function call to `mime.lookup(...)`:
Packages to the rescue!! Turns out that determining the MIME type of a file only involves importing a community-created module like [`mime-types`][npm-mimetypes] in TypeScript, or using the [mimetypes][python-mimetypes] module from Python's standard library, and a single function call to guess the MIME type:

{{< chooser language "typescript,python" />}}

{{% choosable language typescript %}}

```typescript
import * as mime from 'mime-types'

const mimeType = mime.lookup(‘path/to/your/local/file.ext’);
// Detect the MIME type of the file
const mimeType = mime.lookup('path/to/your/local/file.txt');

```
{{% /choosable %}}

{{% choosable language python %}}

```python
import mimetypes

# Detect the MIME type of the file
mime_type, _ = mimetypes.guess_type('path/to/your/local/file.txt')
```

So, to work that into our Pulumi program from above, we only need to make two small edits:
{{% /choosable %}}

So, to work that into our Pulumi program from above, we only need to make a few small edits:

```typescript {hl_lines=[4,21]}
{{< chooser language "typescript,python" />}}

{{% choosable language typescript %}}

```typescript {hl_lines=[3,17]}
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as fs from 'fs';
import * as mime from `mime-types’;
import * as mime from 'mime-types';

// Create an S3 bucket where we will upload the file.
const bucket = new aws.s3.Bucket("my-bucket", {
// You can apply additional bucket settings here.
});

const filePath = "path/to/your/local/file.ext"; // Replace with the path to the file you want to upload
// Read the contents of the file to be uploaded to S3.
const fileContents = fs.readFileSync(filePath, {encoding: 'utf-8'});
const filePath = "path/to/your/local/file.txt"; // Replace with the path to the file you want to upload

// Upload the file to the S3 bucket.
const bucketObject = new aws.s3.BucketObject("my-bucket-object", {
bucket: bucket, // Reference to the bucket created above.
key: "file.txt", // This will be the file's name in the bucket.
content: fileContents, // Contents of the file.
source: pulumi.FileAsset(filePath), // Contents of the file.
contentType: mime.lookup(filePath) || "application/octet-stream", // MIME-type of the file
});

Expand All @@ -111,6 +172,41 @@ export const bucketName = bucket.id;
// Export the URL of the file in the S3 bucket
export const objectUrl = pulumi.interpolate`s3://${bucket.id}/${bucketObject.key}`;
```

{{% /choosable %}}

{{% choosable language python %}}

```python {hl_lines=[3,12,19]}
import pulumi
import pulumi_aws as aws
import mimetypes

# Create an S3 bucket
bucket = aws.s3.Bucket('my-bucket')

# The path to the file to upload to S3
file_path = "path/to/your/local/file.txt" # Replace with the path to the file you want to upload

# Detect the MIME type of the file
mime_type, _ = mimetypes.guess_type(file_path)

# Upload the file to the S3 bucket
bucket_object = aws.s3.BucketObject('my-bucket-object',
bucket=bucket.id, # Reference to the bucket created above.
key='file.txt', # This will be the file's name in the bucket.
source=pulumi.FileAsset(file_path),
content_type=mime_type or 'application/octet-stream') # MIME-type of the file

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)

# Export the URL of the file in the S3 bucket
pulumi.export('object_url', pulumi.Output.concat('s3://', bucket.id, '/', bucket_object.key))
```

{{% /choosable %}}

Well that was pretty straightforward, wasn't it? Trying to do this in [another tool][terraform-mime-example] might take all day to figure out the right way to implement it, but in Pulumi it worked exactly like you would expect it to, in no time at all.

It's a real game-changer when you can just quickly grab something complicated like MIME typing from a package. But when you can't, you're going to be stuck figuring out how to write that functionality yourself, from scratch, using things like Bash and primitive data types, and then find yourself copy-pasting that stuff all over the place. All the while fully aware of how much time you're wasting by having to do so. That's a real pain! It's the kind of pain most people managing infrastructure have been through before.
Expand All @@ -130,3 +226,4 @@ Whatever you can do with code in your favorite language, you can do in Pulumi as
[npm-octokit]: https://www.npmjs.com/package/octokit
[nodejs-crypto-module]: https://nodejs.org/api/crypto.html#crypto
[terraform-mime-example]: https://engineering.statefarm.com/blog/terraform-s3-upload-with-mime/
[python-mimetypes]: https://docs.python.org/3/library/mimetypes.html

0 comments on commit c6c3b38

Please sign in to comment.