After waddling my way through some python learning courses, I finally stumbled into an excellent “next step” programming challenge.  It had the ideal combination of a connection to my real life, super straightforward goals, and a handful of moving parts that I was pretty sure I could figure out (but that I would, in fact, have to figure out).  The project was to download an image of the front page of every People’s Daily back to 1993.  This post is going to walk through the process of how to build the python script in a way that I wish someone had done when I was trying to figure this out.  That means instead of code snippets inside of a longer unified program (or just snippets) it will have a series of discrete programs that build upon themselves.  For me, that makes it easier to figure out how each part works.

The “why” I did this is not particularly important, but the “how” is.  The excellent news is that these images are all stored on a server in a standard way.  For example, the image for the cover on April 26, 2016 lives here:

http://58.68.146.102/pic/101p/2000/04/2000040101.jpg

after the /101p/ the pattern is simple: year/month/YearMonthDayPage.jpg

That means I didn’t have to mess with creating a BeautifulSoup object or any real web scraper.  All I needed to do was to create a script that would download the file, move on to the next day, and download that file.  

While that is simple from a programming standpoint, it still requires actual steps that you actually need to code.  The rest of this post walks through each step with a script you can download and break however you want.  All of the code, which is hosted at this github repository is licensed under a CC0 license (more on why I decided to do that at the end).

Step 1: Download & save a picture

The first thing I decided I needed to figure out was how to have python download a picture and save it.   While I started with the template from the excellent Automate the Easy Stuff chapter on web scraping (specifically the exercise that shows you how to download XKCD strips), I quickly realized that it was overkill.  I didn’t need to download and parse a page to find the URL - I already had it.  After a few dead ends using requests, I ended up using the urllib library. The syntax was fairly easy: call it and then pass it the URL you are downloading from and the name you want to save it as.  Here is a fully functioning script using urllib:

import urllib


urllib.urlretrieve(‘http://58.68.146.102/pic/101p/2000/04/2000040101.jpg’, 'test.jpg’)

The first line imports the urllib library.  The second line calls the urlretrieve function from urllib, tells it to download the file at http://58.68.146.102/pic/101p/2000/04/2000040101.jpg and save it to a file called test.jpg.  Note that this will save the file in the same directory as the python script.  You can call the output file whatever you want.

Step 2: Count and Correct Numbers

Next, I needed to remind myself/confirm that I understood how to add 1 to a variable a certain number of times.  That’s a fairly straightforward concept.

I also needed to figure out how to make sure the numbers the represented the date in the program would work when applied to the URL.  The target URL always uses two-digit dates. That means that April is not represented as “4″ but rather as “04″.  In order to be able to find the right file I had to figure out how to turn any integer into a string with two characters no matter what.

Here’s the script that does both of those things:

day = 5

for i in range(0, 15):
     print day
     day_fixed = str(day).zfill(2)
     print day_fixed
     day += 1
     print “I’ve added 1”

The first line sets day to a starting integer.  Note that this is an actual number, not a string.

The rest of the script is a loop that will run a set number of times.  To pick the number of times it will run, change the second argument passed to range (currently that is the 15) to whatever number you want.

All of the “print” commands are just for debugging.  The real action is in the two other lines.

day_fixed is where I hold the version of the day that is turned into a two character string (this becomes important later).  “str(day)” turns the integer day into a string.  .zfill(2) forces that string to be two characters, and will add a 0 to the front if need be.

day += 1 just takes day and adds 1 to it.  That way the days advance every time the loop runs.

Step 3: Iterate

The next step was to combine the ability to advance the dates with the ability to download the file.  I knew  that I would eventually have to make all of the date variables advance (day, month, and year), but I decided to make sure I could do just one before tackling all of them.  Because of that, the script uses strings for the year, month, and page parts of the URL.  That lets it focus on changing just the day:

import urllib

core = “http://58.68.146.102/pic/101p/”

#these all have to be numbers not strings - need to change them

year = “2000”
month = “04”
day = 2
page = “02”

for i in range(0,6):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     urllib.urlretrieve(core+year+“/”+month+”/“+year+month+day_fixed+page+”.jpg", year+“-”+month+“-”+day_fixed+“-”+page+“.jpg”)

Again, the first line imports the urllib that is used to actually download the image file.

The “core” variable is the part of the URL that says constant.  I didn’t have to make it a variable, but since the target URL is a bit complicated turning it into a variable make it a little bit easer to work.

After the note to myself that I’ll need to change the strings to numbers, there is the list of variables that represent the date.  Then there is  a loop that is identical to the last script without the print lines for troubleshooting (it works….).

The last line is the command to download the file.  It is a single line, although it might wrap in your browser.  The first part just calls the urllib.urlretrieve() function.  This function will download whatever URL is in the ().

Inside the () is the URL broken up into pieces.  These need to be broken up because while the relative position of each variable is the same - the path will always end with the month followed by the day followed by the page - the actual value of the variables will change as the script works its way through the process.  That’s kind of the point.  For elements that do not have a variable, I just used strings surrounded by ““.

Each time the loop runs the day is advanced 1, the two character version of the day is created, and then the file at a URL that includes that new day is downloaded and assigned a file name that is also based on the date. 

While the first argument passed to the urllib function has to be what it is, you could change the second function to whatever you want.  I decided to name each file year-month-day-page.jpg.

Step 4: Multiple Variables

Thenext step is to expand the script so it iterates through all of the variables (date, month, and year) not  just date.  Of course, it has to do this in a systematic way so that every combination that corresponds to a date is actually downloaded.  In order to do that, I nested loops within loops.  I wasn’t sure it would work, so I started with just two variables (day and month) to see what would happen:

import urllib

core = “http://58.68.146.102/pic/101p/”

#these all have to be numbers not strings - need to change them

year = “2000”
month = 4
day = 2
page = “01”

for i in range(0,6):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     for i in range(0,4):
         month += 1
         month_fixed = str(month).zfill(2)

         urllib.urlretrieve(core+year+“/”+month_fixed+“/”+year+month_fixed+day_fixed+page+“.jpg”, year+“-”+month_fixed+“-”+day_fixed+“-”+page+“.jpg”)

     month = 4

This is just the previous script with an additional for loop related to the month.  There are two important things that need to be done in order for this to work correctly.  First, the urllib function must be inside the deepest loop.  The most nested loop runs all the way through before jumping up a level, so if urllib is bumped out a few levels you will miss a lot of the files.

Second, you need to reset the variable when its loop is done.  The month loop starts at 4 (because that’s what I set it at in the start of the script) and works its way through 4 times until month is 8 (I limited the number of iterations for testing).  Once it hits 8, the loop exits, the day variable is moved one day forward, and the month loop starts over again.

However, if that is all you do, the month loop will start where it left off last time - at 8 instead of at 4.  This can create a problem if you want it to run, say 31 times for every month.  By the second month you will be trying to download files for the 42nd day of February.

In order to avoid that, I reset the month variable to the original variable outside of the month loop.  Now every time it runs it starts from the same place.

Step 5: Bringing it All Together

Now that I have figured out how all of the pieces worked, I was ready for the final version:

import urllib

core = “http://58.68.146.102/pic/101p/”

#start all of these one below where you want to start because step 1 is +=1

#DON’T FORGET IF YOU CHANGE A VALUE HERE TO ALSO CHANGE IT AT THE END OF THE FOR
year = 2002
month = 0
day = 0
page = “01”

for i in range(0,31):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     for i in range(0,12):
         month += 1
         month_fixed = str(month).zfill(2)

         for i in range(0,6):

             year += 1
             year_fixed = str(year)

             #this needs to go at the bottom of the nest
             urllib.urlretrieve(core+year_fixed+“/”+month_fixed+“/”+year_fixed+month_fixed+day_fixed+page+“.jpg”, year_fixed+“-”+month_fixed+“-”+day_fixed+“-”+page+“.jpg”)

             year = 2002

         #this resets the month to the starting point so it stays in the right range
         month = 0

This uses year, month, and day as variables.  Note that it doesn’t work through the pages.  That variable is necessary for the download URL, but for this first version I didn’t need every page of the paper.  As the all caps comment suggests, you need to set all of the variables one less than the starting variable since the first thing that happens is that 1 is added to them.  You can also manipulate how many years of covers you get by changing the second argument in the year range() function (currently it is set at 6).

Improvements

This script works, which is exciting.  However, there are a few things I might improve going forward:

  • Be smart about dates.  Right now it downloads 31 days of covers for every month.  Obviously that means that some of the files are junk because there is no Feb 31st.  The way to fix this would be to add an if statement to the day loop that changes the number of iterations based on the value of month.  Since I didn’t really mind having a few garbage files I didn’t worry too much about this.
  • Reorder the nesting.  Right now the script will download the January 1 cover for each year, then move on to the January 2 cover for each year, and so on.  This is fine, but if the download is interrupted for some reason it makes it a bit harder to  understand where to restart and it makes it a bit harder to get a sense of how far into the process you are by looking at what has been downloaded.  By reordering the nesting, I could make it download the covers in chronological order.
  • Handle interruptions.  The first two fixes are fairly easy, but this one would require actual additional research. I was testing on this on a few wonky wifi connections, and sometimes I would lose the connection in the middle.  This would cause the script to crash and stop.  It would be great to learn how urllib.urlretrieve handles these sorts of problems, and make the script robust enough to recover.  It can take a few minutes for the script to run, and it was a shame when I cam back only to see that it had crashed three minutes in.

The License

Why a CC0 license?  First, these scripts are so simple that one could probably argue that they are devoid of copyrightable content (except for the comments).  But second, and more importantly, to the extent they are useful to anyone they will be useful for hacking around with trying to learn python.  Even an MIT license would require people to keep a license intact, which seemed too burdensome for this purpose.  CC0 clarifies - to the extent that anyone is worrying about it - that you can do whatever you want with these scripts without worrying about copyright.

That’s the show. Hopefully this is helpful to someone else trying to teach themselves how to do this.

This post originally appeared on the Shapeways blog.

Spring is in the air, and that means that it is time for a few policy updates here at Shapeways.  This blog post serves as a summary of those changes.  As a reminder, if you want to go deeper you can always check out the archived versions of specific policies in order to compare them to the current one.

The biggest update is to the Shop Terms and Conditions.  These terms were last updated in 2012 and, as you can imagine, Shapeways has evolved significantly since then.  In addition to the Shop Terms update, this update includes much smaller fixes to the general Terms and Conditions, the API Terms and Conditions, and the Content Policy.  We are also bringing our content policy precheck program out of beta.  I’ll detail all of the changes below.

Shop Terms and Conditions

These are the terms that govern shop owners on Shapeways.  This update overhauls the format so that it makes a bit more sense, and updates some of the policies.  It also takes steps to simplify the terms.  Since you need to have a regular Shapeways account in order to open a shop, it tries to incorporate terms from the standard Shapeways Terms and Conditions by reference instead of repeating them again in the Shop terms.

For example, instead of having a big section on content rules, the new terms incorporate the existing Content Policy.  That should reduce confusion by just having one content policy that governs the entire site and make the terms a bit more concise and easier to read.

While the payment terms remain largely the same (we pay your markup if it is over $30 on the 15th of each month) there are a few additions designed to clarify policies and address issues that have emerged over the years.

One of the most important changes is to highlight the importance of providing us with correct PayPayl information for an account that can receive transfers from the United States or the Netherlands.  Failure to do this can cause all sorts of problems, so we wanted to make sure that there was ample warning in the terms that you need to do that in order to receive  your markup.

Another change is adding rules about how we handle markups on orders that later get returned or rejected.  Sometimes a model is returned because we did not print it correctly.  In those cases we will continue to reprint the models at our expense and send shop owners their markup.  However, sometimes a model is returned or rejected because of an error on the part of the designer.  We are currently exploring the best way to handle those situations.  It is likely that in at least some of those cases we will not pay the designer a markup if the return or rejection stems from errors that they made.

The changes to the terms give us the ability to begin testing rules governing what happens when a product is returned due to designer error.  The process of exploring options will take some time, and we will strive to do it in an open, inclusive way.  Expect to hear more about the process soon.  Until we roll out a more formal tests, designers will at most receive warnings that their model was returned due to what we believe to be their error.  To put it another way, we will not begin withholding markups for returned or rejected models until we have new rules in place.

Most of the rest of the changes are relatively small.  We added a reminder that some tax authorities require us and/or our payment processors to report data on accounts with gross payments over $20,000 and 200 transactions.  We also did a better job of linking the indemnity and product liability sections of the shop owner terms with the general site terms.  At the end we made it explicit that we may change the terms from time to time.

Finally, we linked the confidentiality terms in the shop owner terms to those in our privacy statement.  Hopefully that will give all users of the site a  more uniform set of expectations in terms of privacy on the site.

Terms and Conditions

As I noted at the start of this post, in addition to an overhaul of the shop terms and conditions we also made some updates to other policies on the site.  In addition to fixing some typos in our general terms, the update has two substantive additions.  These are actually clarifications of existing policies that we wanted to make even more clear in the terms.  Remember that these apply to all users, not just shop owners.

The first is what happens when a model violates the content policy. The terms now make it clear that if a model violates our content policy we will refuse to print it and issue you a refund.  If we catch the violation after we print the model, we will not ship you the model and may not issue you a full refund.

We are pairing this with removing the content policy precheck program from beta.  You can email  content-precheck@shapeways.com if you are worried that a model might run into trouble with our content policy.  Even if your model is incomplete – or even just an idea – we will do our best to give you guidance about how our content policy applies to you.

The second update to the general terms a clarification as to what happens when you remove a model from Shapeways.  The terms now make it clear that we may continue to use the model as part of our internal education and testing process. This is largely because we use user models to develop testing benchmarks that need to be consistent over time.  However, you can still always email customer service when you remove a model and request that it also be removed from internal testing.

API Terms and Conditions

The updates to the API Terms and Conditions are relatively modest.  In addition to some minor typos, the terms now make it clear that developers using the API are responsible for all fraud and chargebacks related to their use.  Since the API developer is in the best position to design their application in a way that avoids these sorts of fraudulent charges, it seemed only fair that they are responsible when someone uses the application fraudulently.

Content Policy

Last on the list of updates is the Content Policy.  The biggest change, which I already  mentioned above, is that we are bringing the content policy precheck out of beta.  Besides cleaning up some typos (by the way, feel free to let me know when you see typos in our policies….), the only other change is to make our preferred way of receiving copyright takedown notices more prominent.  Sending emails to content@shapeways.com is the best way to get a takedown request processed efficiently, and now that email address is more obvious on the page.

Thus concludes the spring recitation of the Shapeways policy updates.  As always, if you have any comments, questions or concerns, feel free to put them in the comments below, email them to me at mweinberg@shapeways.com, or tweet at me @MWeinberg2D.

This post originally appeared on the Shapeways blog.

Last week Shapeways participated in the fifth annual 3D/DC conference.  3D/DC is an event held by the nonprofit advocacy organization Public Knowledge (full disclosure: I used to work there) designed to connect 3D printing with policymakers in Washington, DC.

The world of 3D printing has evolved a lot since the first 3D/DC, and the conference has evolved right along with it. The first 3D/DC (video highlights here) was primarily focused on introducing 3D printing to policymakers and introducing policymakers to 3D printing.  Most attendees of 3D/DC in 2011 had barely ever heard of 3D printing, and may never have even seen pictures of 3D printers.  Similarly, the 3D printing community itself was largely unfamiliar with the policy world and had never even thought about trying to set up a meeting with a Member of Congress.

Fast forward to 2016.  Everyone may not have seen 3D printing first hand, but panelists didn’t have to begin every conversation with an explanation of what 3D printing was.  As a result, after a day of private meetings with Members of Congress and their staff, the public day of 3D/DC could focus on the application of 3D printing to important areas of policy.

Public Knowledge’s Courtney Duffy did a fantastic job of bringing new perspectives and areas of focus to the event this year.  The first panel, on 3D printing and STEAM education included Shapeways’ own Lauren Slowik.  Lauren is our point person on connecting the educational and arts community to Shapeways, so she was able to bring an applied perspective to the conversation.  She was joined by two kids who live 3D printing and STEAM education, John (age 11) and Becky (age 15) Button, along with Sophie Georgiou of Morphi and Joseph Williams of Perris Union High School District.

That first panel set the tone for the rest of the day by talking less about 3D printing for 3D printing’s sake, and instead focusing on how 3D printing integrated into issue areas such as the environment, workforce development, social impact, and the arts.  These panels, which brought together diverse perspectives from both inside and outside of government, were possible because 3D printing has expanded well beyond its original group of enthusiasts.  As we here at Shapeways see every day, many of the most exciting applications of 3D printing comes from people who care less about how 3D printing works and more about what 3D printing can do.

While a policy conference in Washington DC would not be complete without policy panels, 3D/DC is not complete without its culminating reception.  Although many more people have heard about 3D printing in 2016 than in 2011, there are still plenty of people who have never experienced it in person.  The reception and demonstration gives policymakers a chance to see 3D printing and talk to the people behind the printers in a less formal atmosphere.

This reception has evolved over the years as well.  As more and more local community groups, libraries, and maker spaces grow up across the country, 3D/DC can draw on a vibrant local 3D printing scene to demonstrate at the reception.  As a bonus, staffers and policymakers who live in the Washington, DC area can walk into 3D/DC and walk out with information on how to join a local hacker space.  Over the long term, a cadre of wonks who have deep first hand experiences with 3D printing will make sure that 3D printing policy coming out of Washington is created with a nuanced understanding of the technology.

You can check out more about this year’s 3D/DC by searching #3DDC2016 on twitter.  I’ll also try to update this post with a link to videos of the panels as soon as they are up.  In the meantime, you can learn more about what Public Knowledge is doing to help advocate for good 3D printing policy here.

Last week Sparkfun ran a piece on their blog called “FaKey Makey” taking a deep dive into what appears to be an unauthorized derivative of the popular MaKey MaKey hardware accessory.  Briefly - and I commend the entire thing to you - it concludes that a product called the MC2 Circuit Beats manufactured by MGA Entertainment is a derivative of the MaKey MaKey that fails to give MaKey MaKey credit as the source of the idea.  

In addition to the really impressive forensics work in the post, the incident serves as a nice opportunity to reflect on the limits of open source hardware licensing.  It may also help highlight why the Open Source Hardware Association is moving towards a certification model and not an approved license model.

But first…

Some quick background may be helpful.  The MaKey MaKey is a clever bit of hardware that lets you use all sorts of physical objects as input for your computer.  If you are itching to turn those bananas in your kitchen into a piano or use the walls of your living room to control a video game character, the MaKey MaKey is a good place to start.  

It is also open source hardware, which means MaKey MaKey makes things like their schematics available under a CC (in this case attribution, share-alike) license.  

For the purposes of this post I’m going to assume that everything in the Sparkfun article is true and that MGA 1) made something that can trace its lineage back to the MaKey MaKey, and 2) failed to give MaKey MaKey attribution for that history.  Keep in mind that either of those could be incorrect.  I’ll do my best to update this post if I become aware of evidence to the contrary.

Moral/Social Issues

The moral and social issues surrounding open source hardware, derivatives, and attribution can be complex, so I’m going to skip over them here.  Instead, I’m going to focus on the legal and licensing aspects of what happened here. Specifically, did MGA - the company that made the derivative product - violate any licenses?

Does the New Board Violate MaKey MaKey’s License?

Spoiler: I don’t think so.  But I’ll go deeper than that.

MaKey MaKey puts out its schematics under a CC license.  It is important to understand what that really means.  A CC license is a copyright license and can only control the use of works that are protected by copyright.  In this case, the schematics are covered by copyright.  However, this does not mean that the MaKey MaKey itself is covered by copyright. In fact, as a functional object, it is not protected by copyright (there are some clever lawyer arguments that one could use to chip away at this simple statement, but in the interest of clarity I’m just going to work under that assumption).  That means that the license on the schematics are irrelevant to the object itself.

What does that mean?  If you copy MaKey MaKey’s schematics without giving MaKey MaKey attribution, you have infringed on their copyright.  However, if you just decide to copy the MaKey MaKey itself, the license they attached to their schematics requiring attribution doesn’t matter.  You have no legal obligation to give MaKey MaKey anything.

Even if MGA copied MaKey MaKey’s schematics, as long as they kept the attribution on the schematics they probably did not have any obligation to give attribution on the product itself.

Is it Bad that MGA Can Copy MaKey MaKey?

I don’t think that it is.  The fact that hardware can be copied is a feature, not a bug, of IP law.  

Unless MaKey MaKey had a patent on its core functionality, the fact that MaKey MaKey is open source hardware doesn’t really have an impact on MGA’s ability to copy it.  While the schematics  may have made it easier, the Sparkfun post suggests that a determined copier probably could have figured out what was going on without them.

On the flip side, I’d be willing to bet that MaKey MaKey’s openness has helped it grow a community and a market.  I also suspect that this benefit outweighs whatever “cost” making it easier for copiers to access schematics imposed on them.

This incident also serves as a reminder that hardware is open by default.  If you’ve even been frustrated with copyright restrictions, this world of open by default can feel liberating and loaded with possibilities.  If you have ever reverse engineered a piece of hardware without asking permission from the manufacturer first, you understand what that openness means.

Finally, remember that openness goes both ways.  The same legal structures that make it hard for MaKey Makey to protect its core functionality with IP makes it hard for MGA to protect whatever improvements they have come up with.  Even if MGA does not release the schematics, it is likely that MaKey MaKey can reverse engineer them and incorporate them into a future version of MaKey MaKey. (note: maybe do not do this without first talking to a lawyer).  To me, that’s an example of how the openness ecosystem in hardware can extend well beyond a core group of open source hardware devotees.  

Would A Different License Change This Analysis?

I don’t believe so. The core challenge remains that you need a work protected by copyright as a “hook” for any restrictive copyright license.  Even a non-commercial restriction on the schematics probably would not stand in MGA’s way.  (side note: would downloading a copy of the schematics in order to make a commercial product based on those schematics - as opposed to commercially selling the schematics themselves - violate a non-commercial CC restriction?  I don’t know but I’d argue against it).

Would an Open Source Hardware Certification Help in this Situation?

Yes and no.  As I hope this post makes clear, one of the reasons that the Open Source Hardware Association is looking towards certification is because copyright-based hardware licenses can leave a lot out.  Those exclusions can come as a surprise to the people who are using the license.

A certification will not directly prevent someone from making an unattributed derivative of a piece of hardware.  Of course, in many cases, neither would a license. The open by default nature of hardware makes that sort of condition very hard to enforce without patents.

However, to the extent that people see a Open Source Hardware Association certification as valuable, it can help distinguish the MaKey Makeys of the world from the MGAs of the world.  People value openness - and value it more every day.  If a product like MaKey MaKey can stand up and say that they truly are open, it can - I hope - help expand their market reach.

For now, it seems like MaKey MaKey and the MGA board can coexist.  That’s a good outcome too.  My real interest in this incident is that it gives another excuse to do concrete thinking about how open source hardware and licensing can really work.

Let’s start this post with a lawyerly caveat. Everything on this site is my own personal opinion and should not be attributed to my employer or anyone else.   While that’s always true, this post is super thinking-in-progress-y so it seemed wise to repeat that.  Plus I’m not even a pretend product liability lawyer so keep that in mind.

For many people, IP is the first thing that comes to mind when they imagine ways for 3D printing to get into legal trouble.  It certainly was for me, and I think that’s more or less right.  IP issues are coming first in the 3D printing world.

However, if you give people a few more minutes, the second thing that comes to mind is often product liability.  And rightly so - product liability is a big area of law and 3D printed things can hurt people (because, you know, “things” as a product class can hurt people).

However, thinking about 3D printing and product liability isn’t easy.  Modern product liability law developed along with mass manufacturing and the structure of mass manufacturing is build into its underlying assumptions that ground modern product liability law.  A technology that reintroduces variability, customization, and distributed manufacturing into product design and manufacture runs counter to much of product liability’s worldview. Before you even get to the rules, 3D printing just doesn’t fit into how product liability law sees the world.

Furthermore, product liability is not necessarily prepared for a big shift.  Everyone involved in copyright law has experienced (is experiencing?) a fundamental shift in its practice in the last twenty years.  While that shift has not been as extensive in patent and trademark law, those legal worlds are close to copyright.  At a minimum, that gave them a front row seat to the change.  Like it or not, IP lawyers, policymakers, and advocates are emotionally prepared for seismic change.

In contrast, product liability has been on a relatively stable trajectory for decades. This isn’t to suggest that it has been unchanged - there have been plenty of important shifts and big decisions.  But when compared to an area like copyright its basic assumptions and ordering principles have been remarkably static.  That may mean that the people who make up the product liability policy world are less prepared for a big change.

One way to think about the forces driving these changes is to lay out the contrasting world views of traditional product liability and the new model exemplified by companies like Shapeways.

Traditional Model

  • Professional Designers. With modern mass manufacturing, products are designed by individuals or teams with a deep understanding of material properties, tolerances, and  other relevant considerations.  They are trained to anticipate potential use problems and incorporate solutions into the design.
  • B2B Manufacturing Relationship. Once those designers finish the design, they contract directly with a manufacturer.  The manufacturer understands what they are manufacturing and establishes manufacturing and monitoring processes oriented towards the purpose of the object.
  • QA Testing Fit for Purpose.  Because both the designer and manufacturer understand what they are manufacturing and how it will be done, they can collaborate on a testing regime oriented towards the anticipated use of the object.
  • Mature Insurance and Contract Umbrella.  Each party is insured and risk is contractually allocated in line with well established industry norms.

New Model

  • Designers of Mixed Backgrounds.  While some designers in this new model are trained engineers, plenty of them are not.  Their skill set may have blind spots and shortcomings that they are not aware of and that do not immediately and obviously manifest themselves in their work.
  • Arms-Length Manufacturing Relationship.  The designs can be printed by a service bureau, but the service bureau does not necessarily appreciate the actual purpose of the object.  The manufacturer uses generic 3D printing processes that are not tailored to the object.
  • Lack of QA Testing.  Since the manufacturer does not know what they are printing, they do not create tests to make sure that the finished object is fit for purpose.  Repeatability in 3D printing is not up to the standards of traditional mass manufacturing, so the designer may have a limited understanding of the characteristics of a specific model shipped directly to a customer.
  • Immature Insurance and Contract Umbrella.  The process is full of players who may not be insured with an eye towards product liability.  Contracts do not necessarily allocate risk along well established industry norms.

This does not mean that the 3D printing-enabled ability for an individual in their basement to sell physical products to the world is doomed.  Nor does it mean that we should scrap the existing product liability regime because this new model isn’t a perfect fit out of the box.

Instead, as I tried to outline in my response to Adam Thierer’s proposal for maker immunity, it means that we are at a moment where it may make sense to rethink parts of the existing product liability regime.  It is worth trying to understand if the goals of product liability  - to create incentives for people responsible for goods to make their goods safer and to compensate people who are injured by goods - can be advanced in a way that does not require every player in the design-build-distribute chain to be a commercially and legally sophisticated entity.  

Obviously it is way to early to know. Hopefully we are in the beginning of that discussion.

By the way, the Minnesota Journal of Law, Science, and Technology had a really great symposium on 3D printing and law in March.  I’d recommend the entire thing if you are interested, but they did an entire panel on product liability where people who actually know product liability work through some of these issues.